-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a3a5ec0
commit 4812370
Showing
4 changed files
with
211 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
import 'dart:io'; | ||
|
||
import 'package:_analyzer_macros/macro_implementation.dart'; | ||
import 'package:analyzer/dart/analysis/analysis_context_collection.dart'; | ||
import 'package:analyzer/dart/analysis/results.dart'; | ||
import 'package:analyzer/src/summary2/macro_injected_impl.dart' | ||
as injected_analyzer; | ||
import 'package:macro_service/macro_service.dart'; | ||
|
||
import 'macro_tool.dart'; | ||
|
||
class AnalyzerMacroTool extends MacroTool { | ||
AnalyzerMacroTool( | ||
{required super.workspacePath, | ||
required super.packageConfigPath, | ||
required super.scriptPath, | ||
required super.skipCleanup}) | ||
: super.internal(); | ||
|
||
/// Runs macros in [scriptFile] on the analyzer. | ||
/// | ||
/// Writes any augmentation to [_augmentationFilePath]. | ||
/// | ||
/// Returns whether an augmentation file was written. | ||
@override | ||
Future<bool> augment() async { | ||
final contextCollection = | ||
AnalysisContextCollection(includedPaths: [workspacePath]); | ||
final analysisContext = contextCollection.contexts.first; | ||
injected_analyzer.macroImplementation = | ||
await AnalyzerMacroImplementation.start( | ||
protocol: Protocol( | ||
encoding: ProtocolEncoding.binary, | ||
version: ProtocolVersion.macros1), | ||
packageConfig: Uri.file(packageConfigPath)); | ||
|
||
final resolvedLibrary = (await analysisContext.currentSession | ||
.getResolvedLibrary(scriptPath)) as ResolvedLibraryResult; | ||
|
||
final errors = (await analysisContext.currentSession.getErrors(scriptPath)) | ||
as ErrorsResult; | ||
if (errors.errors.isNotEmpty) { | ||
print('Errors: ${errors.errors}'); | ||
} | ||
|
||
final augmentationUnits = | ||
resolvedLibrary.units.where((u) => u.isMacroPart).toList(); | ||
if (augmentationUnits.isEmpty) { | ||
return false; | ||
} | ||
|
||
print('Macro output (patched to use augment library): ' | ||
'$augmentationFilePath'); | ||
File(augmentationFilePath).writeAsStringSync(augmentationUnits | ||
.single.content | ||
// The analyzer produces augmentations in parts, but the CFE still | ||
// wants them in augmentation libraries. Adjust the output accordingly. | ||
.replaceAll('part of', 'augment library')); | ||
|
||
return true; | ||
} | ||
|
||
@override | ||
String toString() => 'analyzer'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
import 'dart:io'; | ||
import 'dart:isolate'; | ||
|
||
import 'package:_cfe_macros/macro_implementation.dart'; | ||
import 'package:front_end/src/macros/macro_injected_impl.dart' as injected_cfe; | ||
import 'package:frontend_server/compute_kernel.dart'; | ||
import 'package:macro_service/macro_service.dart'; | ||
|
||
import 'macro_tool.dart'; | ||
|
||
class CfeMacroTool extends MacroTool { | ||
CfeMacroTool( | ||
{required super.workspacePath, | ||
required super.packageConfigPath, | ||
required super.scriptPath, | ||
required super.skipCleanup}) | ||
: super.internal(); | ||
|
||
/// Runs macros in [scriptFile] using the CFE. | ||
/// | ||
/// Writes any augmentation to [augmentationFilePath]. | ||
/// | ||
/// Returns whether an augmentation file was written. | ||
@override | ||
Future<bool> augment() async { | ||
// TODO(davidmorgan): this dill comes from the Dart SDK running the test, | ||
// but `package:frontend_server` and `package:front_end` are used as a | ||
// library, so we will see version skew breakage. Find a better way. | ||
final productPlatformDill = File('${Platform.resolvedExecutable}/../../' | ||
'lib/_internal/vm_platform_strong_product.dill'); | ||
if (!File.fromUri(productPlatformDill.uri).existsSync()) { | ||
throw StateError('Failed to find platform dill: $productPlatformDill'); | ||
} | ||
injected_cfe.macroImplementation = await CfeMacroImplementation.start( | ||
protocol: Protocol( | ||
encoding: ProtocolEncoding.json, version: ProtocolVersion.macros1), | ||
packageConfig: Isolate.packageConfigSync!); | ||
|
||
final packagesUri = Isolate.packageConfigSync; | ||
|
||
// Don't directly use the compiler output: for consistency with the analyzer | ||
// codepath, run from the resulting source. | ||
// TODO(davidmorgan): maybe offer both as options? Not clear yet. | ||
final outputFile = File('/dev/null'); | ||
|
||
final computeKernelResult = await computeKernel([ | ||
'--enable-experiment=macros', | ||
'--no-summary', | ||
'--no-summary-only', | ||
'--target=vm', | ||
'--dart-sdk-summary=${productPlatformDill.uri}', | ||
'--output=${outputFile.path}', | ||
'--source=$scriptPath', | ||
'--packages-file=$packagesUri', | ||
// TODO(davidmorgan): this is so we can pull the generated | ||
// augmentation source out of incremental compiler state; find a less | ||
// hacky way. | ||
'--use-incremental-compiler', | ||
// For augmentations. | ||
'--enable-experiment=macros', | ||
]); | ||
|
||
final sources = computeKernelResult | ||
.previousState!.incrementalCompiler!.context.uriToSource; | ||
final applicationMacroOutput = sources.entries | ||
.where((e) => e.key.scheme == 'dart-macro+file') | ||
.singleOrNull; | ||
if (applicationMacroOutput == null) return false; | ||
|
||
print('Macro output: ' | ||
'$augmentationFilePath'); | ||
File(augmentationFilePath) | ||
.writeAsStringSync(applicationMacroOutput.value.text); | ||
|
||
return true; | ||
} | ||
|
||
@override | ||
String toString() => 'CFE'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters