Skip to content

Commit

Permalink
Use MacroPackageConfig.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmorgan committed Aug 9, 2024
1 parent f759461 commit 52b7e98
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 42 deletions.
16 changes: 4 additions & 12 deletions pkgs/_analyzer_macros/lib/macro_implementation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,21 @@ import 'package:macros/src/executor.dart' as injected;
/// Injected macro implementation for the analyzer.
class MacroImplementation implements injected.MacroImplementation {
final Uri packageConfig;
final Map<String, String> macroImplByName;
final MacroHost _host;

MacroImplementation._(this.packageConfig, this.macroImplByName, this._host);
MacroImplementation._(this.packageConfig, this._host);

/// Starts the macro host.
///
/// [packageConfig] is the package config of the workspace of the code being
/// edited.
///
/// [macroImplByName] identifies macros, it's a placeholder until we identify
/// macros using package config. Keys are macro annotation qualified names
/// (`uri#name`) and values are macro implementation qualified names.
static Future<MacroImplementation> start({
required Uri packageConfig,
required Map<String, String> macroImplByName,
}) async =>
MacroImplementation._(
packageConfig,
macroImplByName,
await MacroHost.serve(
macroImplByName: macroImplByName,
packageConfig: packageConfig,
queryService: AnalyzerQueryService()));

@override
Expand All @@ -60,7 +53,7 @@ class AnalyzerMacroPackageConfigs implements injected.MacroPackageConfigs {

@override
bool isMacro(Uri uri, String name) =>
_impl._host.isMacro(_impl.packageConfig, QualifiedName('$uri#$name'));
_impl._host.isMacro(QualifiedName('$uri#$name'));
}

class AnalyzerMacroRunner implements injected.MacroRunner {
Expand All @@ -72,8 +65,7 @@ class AnalyzerMacroRunner implements injected.MacroRunner {
injected.RunningMacro run(Uri uri, String name) => AnalyzerRunningMacro.run(
_impl,
QualifiedName('$uri#$name'),
// Look up from the macro name to its implementation.
QualifiedName(_impl.macroImplByName['$uri#$name']!));
_impl._host.lookupMacroImplementation(QualifiedName('$uri#$name'))!);
}

class AnalyzerRunningMacro implements injected.RunningMacro {
Expand Down
7 changes: 1 addition & 6 deletions pkgs/_analyzer_macros/test/analyzer_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,7 @@ void main() {
AnalysisContextCollection(includedPaths: [directory.path]);
analysisContext = contextCollection.contexts.first;
injected.macroImplementation = await MacroImplementation.start(
packageConfig: Isolate.packageConfigSync!,
macroImplByName: {
'package:_test_macros/declare_x_macro.dart#DeclareX':
'package:_test_macros/declare_x_macro.dart'
'#DeclareXImplementation'
});
packageConfig: Isolate.packageConfigSync!);
});

test('discovers macros, runs them, applies augmentations', () async {
Expand Down
29 changes: 16 additions & 13 deletions pkgs/_macro_host/lib/macro_host.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,42 @@ import 'package:_macro_server/macro_server.dart';
import 'package:dart_model/dart_model.dart';
import 'package:macro_service/macro_service.dart';

import 'src/package_config.dart';

/// Hosts macros: builds them, runs them, serves the macro service.
///
/// Tools that want to support macros, such as the Analyzer and the CFE, can
/// do so by running a `MacroHost` and providing their own `HostService`.
class MacroHost {
final Map<String, String> macroImplByName;
final MacroPackageConfig macroPackageConfig;
final _HostService _hostService;
final MacroServer macroServer;
final MacroBuilder macroBuilder = MacroBuilder();
final MacroRunner macroRunner = MacroRunner();

MacroHost._(this.macroImplByName, this.macroServer, this._hostService);
MacroHost._(this.macroPackageConfig, this.macroServer, this._hostService);

/// Starts a macro host with introspection queries handled by [queryService].
///
/// [macroImplByName] is a map from macro annotation qualified name to macro
/// implementation qualified name, it's needed until this information is
/// available in package configs.
static Future<MacroHost> serve({
required Map<String, String> macroImplByName,
required Uri packageConfig,
required QueryService queryService,
}) async {
final macroPackageConfig = MacroPackageConfig.readFromUri(packageConfig);
final hostService = _HostService(queryService);
final server = await MacroServer.serve(service: hostService);
return MacroHost._(macroImplByName, server, hostService);
return MacroHost._(macroPackageConfig, server, hostService);
}

/// Whether [name] is a macro according to that package's `pubspec.yaml`.
bool isMacro(Uri packageConfig, QualifiedName name) {
// TODO(language/3728): this is a placeholder, use package config when
// available.
return macroImplByName.keys.contains(name.string);
}
bool isMacro(QualifiedName name) => lookupMacroImplementation(name) != null;

/// Checks whether [name] is a macro annotation.
///
/// If so, returns the qualified name of the macro implementation.
///
/// If not, returns `null`.
QualifiedName? lookupMacroImplementation(QualifiedName name) =>
macroPackageConfig.lookupMacroImplementation(name);

/// Determines which phases the macro implemented at [name] runs in.
Future<Set<int>> queryMacroPhases(
Expand Down
9 changes: 3 additions & 6 deletions pkgs/_macro_host/lib/src/package_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class MacroPackageConfig {

MacroPackageConfig({required this.packageConfig});

factory MacroPackageConfig.readUri(Uri uri) => MacroPackageConfig(
factory MacroPackageConfig.readFromUri(Uri uri) => MacroPackageConfig(
packageConfig:
PackageConfig.parseBytes(File.fromUri(uri).readAsBytesSync(), uri));

Expand All @@ -38,6 +38,7 @@ class MacroPackageConfig {
/// ```
QualifiedName? lookupMacroImplementation(QualifiedName name) {
var packageName = name.uri;
if (packageName.startsWith('dart:')) return null;
if (packageName.startsWith('package:') && packageName.contains('/')) {
packageName = packageName.substring('package:'.length);
packageName = packageName.substring(0, packageName.indexOf('/'));
Expand All @@ -48,11 +49,7 @@ class MacroPackageConfig {
final libraryPath =
'lib/${name.string.substring(name.uri.indexOf('/') + 1)}';

final matchingPackage = packageConfig.packages
.where((p) => p.name == packageName)
.toList()
.singleOrNull;

final matchingPackage = packageConfig[packageName];
if (matchingPackage == null) {
throw StateError('Package "$packageName" not found in package config.');
}
Expand Down
8 changes: 4 additions & 4 deletions pkgs/_macro_host/test/macro_host_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ void main() {

final queryService = TestQueryService();
final host = await MacroHost.serve(
macroImplByName: {macroName.string: macroImplementation.string},
packageConfig: Isolate.packageConfigSync!,
queryService: queryService);

final packageConfig = Isolate.packageConfigSync!;

expect(host.isMacro(packageConfig, macroName), true);
expect(host.isMacro(macroName), true);
expect(
await host.queryMacroPhases(packageConfig, macroImplementation), {2});

Expand All @@ -42,12 +42,12 @@ void main() {

final queryService = TestQueryService();
final host = await MacroHost.serve(
macroImplByName: {macroName.string: macroImplementation.string},
packageConfig: Isolate.packageConfigSync!,
queryService: queryService);

final packageConfig = Isolate.packageConfigSync!;

expect(host.isMacro(packageConfig, macroName), true);
expect(host.isMacro(macroName), true);
expect(
await host.queryMacroPhases(packageConfig, macroImplementation), {3});

Expand Down
2 changes: 1 addition & 1 deletion pkgs/_macro_host/test/package_config_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ void main() {
group(MacroPackageConfig, () {
test('can look up macro implementations', () async {
final packageConfig =
MacroPackageConfig.readUri(Isolate.packageConfigSync!);
MacroPackageConfig.readFromUri(Isolate.packageConfigSync!);

expect(
packageConfig
Expand Down

0 comments on commit 52b7e98

Please sign in to comment.