Version 2.17.0-42.0.dev
Merge commit '5dffffbf08811d19e748ed7d4216b37b56a4b80f' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
index 514fcd9..4d2f6a1 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
@@ -2,21 +2,32 @@
// 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.
-/// Generates a Dart program for a given macro, which can be compiled and then
-/// passed as a precompiled kernel file to `MacroExecutor.loadMacro`.
+/// Generates a Dart program for a given set of macros, which can be compiled
+/// and then passed as a precompiled kernel file to `MacroExecutor.loadMacro`.
+///
+/// The [macroDeclarations] is a map from library URIs to macro classes for the
+/// macros supported. The macro classes are provided as a map from macro class
+/// names to the names of the macro class constructors.
String bootstrapMacroIsolate(
- String macroImport, String macroName, List<String> constructorNames) {
- StringBuffer constructorEntries = new StringBuffer(
- "MacroClassIdentifierImpl(Uri.parse('$macroImport'), '$macroName'): {");
- for (String constructor in constructorNames) {
- constructorEntries.writeln("'$constructor': "
- "$macroName.${constructor.isEmpty ? 'new' : constructor},");
- }
- constructorEntries.writeln('},');
- return template
- .replaceFirst(_importMarker, 'import \'$macroImport\';')
- .replaceFirst(
- _macroConstructorEntriesMarker, constructorEntries.toString());
+ Map<String, Map<String, List<String>>> macroDeclarations) {
+ StringBuffer imports = new StringBuffer();
+ StringBuffer constructorEntries = new StringBuffer();
+ macroDeclarations
+ .forEach((String macroImport, Map<String, List<String>> macroClasses) {
+ imports.writeln('import \'$macroImport\';');
+ macroClasses.forEach((String macroName, List<String> constructorNames) {
+ constructorEntries
+ .writeln("MacroClassIdentifierImpl(Uri.parse('$macroImport'), "
+ "'$macroName'): {");
+ for (String constructor in constructorNames) {
+ constructorEntries.writeln("'$constructor': "
+ "$macroName.${constructor.isEmpty ? 'new' : constructor},");
+ }
+ constructorEntries.writeln('},');
+ });
+ });
+ return template.replaceFirst(_importMarker, imports.toString()).replaceFirst(
+ _macroConstructorEntriesMarker, constructorEntries.toString());
}
const String _importMarker = '{{IMPORT}}';
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
index 849c662..57f0ec8 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
@@ -182,7 +182,7 @@
IsExactlyTypeRequest request =
new IsExactlyTypeRequest.deserialize(deserializer, zoneId);
StaticType leftType = request.leftType.instance as StaticType;
- StaticType rightType = request.leftType.instance as StaticType;
+ StaticType rightType = request.rightType.instance as StaticType;
SerializableResponse response = new SerializableResponse(
response:
new BooleanValue(await leftType.isExactly(rightType)),
@@ -197,7 +197,7 @@
IsSubtypeOfRequest request =
new IsSubtypeOfRequest.deserialize(deserializer, zoneId);
StaticType leftType = request.leftType.instance as StaticType;
- StaticType rightType = request.leftType.instance as StaticType;
+ StaticType rightType = request.rightType.instance as StaticType;
SerializableResponse response = new SerializableResponse(
response:
new BooleanValue(await leftType.isSubtypeOf(rightType)),
diff --git a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
index a7f5491..7c242a4 100644
--- a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
@@ -44,8 +44,11 @@
var macroUri = simpleMacroFile.absolute.uri;
var macroName = 'SimpleMacro';
- var bootstrapContent =
- bootstrapMacroIsolate(macroUri.toString(), macroName, ['', 'named']);
+ var bootstrapContent = bootstrapMacroIsolate({
+ macroUri.toString(): {
+ macroName: ['', 'named']
+ }
+ });
var bootstrapFile = File(tmpDir.uri.resolve('main.dart').toFilePath())
..writeAsStringSync(bootstrapContent);
var kernelOutputFile =
diff --git a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart
index 035d96f..84ddb7a 100644
--- a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart
@@ -36,13 +36,13 @@
}
var classType =
await builder.resolve(method.definingClass) as NamedStaticType;
- if (!(await staticReturnType.isExactly(classType))) {
+ if (await staticReturnType.isExactly(classType)) {
throw StateError(
'The return type should not be exactly equal to the class type');
}
- if (!(await staticReturnType.isSubtypeOf(classType))) {
+ if (await staticReturnType.isSubtypeOf(classType)) {
throw StateError(
- 'The return type should be a subtype of the class type!');
+ 'The return type should not be a subtype of the class type!');
}
// Test the type declaration resolver
diff --git a/pkg/front_end/lib/src/fasta/builder_graph.dart b/pkg/front_end/lib/src/fasta/builder_graph.dart
index 9e2b434..fdae514 100644
--- a/pkg/front_end/lib/src/fasta/builder_graph.dart
+++ b/pkg/front_end/lib/src/fasta/builder_graph.dart
@@ -23,13 +23,15 @@
class BuilderGraph implements Graph<Uri> {
final Map<Uri, LibraryBuilder> builders;
+ final Map<Uri, List<Uri>> _neighborsCache = {};
+
BuilderGraph(this.builders);
@override
Iterable<Uri> get vertices => builders.keys;
- @override
- Iterable<Uri> neighborsOf(Uri vertex) sync* {
+ List<Uri> _computeNeighborsOf(Uri vertex) {
+ List<Uri> neighbors = [];
LibraryBuilder? library = builders[vertex];
if (library == null) {
throw "Library not found: $vertex";
@@ -40,20 +42,20 @@
if (import.imported != null) {
Uri uri = import.imported!.importUri;
if (builders.containsKey(uri)) {
- yield uri;
+ neighbors.add(uri);
}
}
}
for (Export export in library.exports) {
Uri uri = export.exported.importUri;
if (builders.containsKey(uri)) {
- yield uri;
+ neighbors.add(uri);
}
}
for (LibraryBuilder part in library.parts) {
Uri uri = part.importUri;
if (builders.containsKey(uri)) {
- yield uri;
+ neighbors.add(uri);
}
}
} else if (library is DillLibraryBuilder) {
@@ -61,7 +63,7 @@
for (LibraryDependency dependency in library.library.dependencies) {
Uri uri = dependency.targetLibrary.importUri;
if (builders.containsKey(uri)) {
- yield uri;
+ neighbors.add(uri);
}
}
@@ -69,9 +71,14 @@
for (LibraryPart part in library.library.parts) {
Uri uri = getPartUri(library.importUri, part);
if (builders.containsKey(uri)) {
- yield uri;
+ neighbors.add(uri);
}
}
}
+ return neighbors;
}
+
+ @override
+ Iterable<Uri> neighborsOf(Uri vertex) =>
+ _neighborsCache[vertex] ??= _computeNeighborsOf(vertex);
}
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 76ab9eb8..2a1e8b7 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -361,7 +361,7 @@
verify: c.options.verify);
componentWithDill = buildResult.component;
}
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
hierarchy ??= currentKernelTarget.loader.hierarchy;
if (currentKernelTarget.classHierarchyChanges != null) {
hierarchy.applyTreeChanges(
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 814b523..86144de 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -284,6 +284,7 @@
}
Version? _currentSdkVersion;
+
Version get currentSdkVersion {
if (_currentSdkVersion == null) {
_parseCurrentSdkVersion();
@@ -464,7 +465,8 @@
loader.finishNoSuchMethodForwarders();
List<SourceClassBuilder> sourceClasses = loader.collectSourceClasses();
if (macroApplications != null) {
- await macroApplications.applyDefinitionMacros();
+ await macroApplications.applyDefinitionMacros(
+ loader.coreTypes, loader.hierarchy);
}
loader.finishNativeMethods();
loader.finishPatchMethods();
diff --git a/pkg/front_end/lib/src/fasta/kernel/macro.dart b/pkg/front_end/lib/src/fasta/kernel/macro.dart
index 6d95bbf..3c8f11a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/macro.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/macro.dart
@@ -5,9 +5,15 @@
import 'package:_fe_analyzer_shared/src/macros/api.dart' hide TypeBuilder;
import 'package:_fe_analyzer_shared/src/macros/executor.dart';
import 'package:_fe_analyzer_shared/src/macros/executor_shared/introspection_impls.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor_shared/remote_instance.dart';
+import 'package:kernel/ast.dart' show DartType, DynamicType;
+import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/type_environment.dart';
import '../builder/class_builder.dart';
import '../builder/formal_parameter_builder.dart';
+import '../builder/library_builder.dart';
import '../builder/member_builder.dart';
import '../builder/named_type_builder.dart';
import '../builder/type_builder.dart';
@@ -46,12 +52,39 @@
}
}
+class MacroApplication {
+ final ClassBuilder classBuilder;
+ final String constructorName;
+
+ // TODO(johnniwinther): Add support for arguments.
+
+ MacroApplication(this.classBuilder, this.constructorName);
+
+ late MacroInstanceIdentifier instanceIdentifier;
+}
+
+class MacroApplicationDataForTesting {
+ Map<SourceLibraryBuilder, LibraryMacroApplicationData> libraryData = {};
+ Map<MemberBuilder, List<MacroExecutionResult>> memberDefinitionsResults = {};
+}
+
+class LibraryMacroApplicationData {
+ Map<SourceClassBuilder, ClassMacroApplicationData> classData = {};
+ Map<MemberBuilder, List<MacroApplication>> memberApplications = {};
+}
+
+class ClassMacroApplicationData {
+ List<MacroApplication>? classApplications;
+ Map<MemberBuilder, List<MacroApplication>> memberApplications = {};
+}
+
class MacroApplications {
- final MacroExecutor macroExecutor;
+ final MacroExecutor _macroExecutor;
final Map<SourceLibraryBuilder, LibraryMacroApplicationData> libraryData;
final MacroApplicationDataForTesting? dataForTesting;
- MacroApplications(this.macroExecutor, this.libraryData, this.dataForTesting) {
+ MacroApplications(
+ this._macroExecutor, this.libraryData, this.dataForTesting) {
dataForTesting?.libraryData.addAll(libraryData);
}
@@ -124,7 +157,7 @@
Future<void> _applyTypeMacros(
Declaration declaration, List<MacroApplication> macroApplications) async {
for (MacroApplication macroApplication in macroApplications) {
- await macroExecutor.executeTypesPhase(
+ await _macroExecutor.executeTypesPhase(
macroApplication.instanceIdentifier, declaration);
}
}
@@ -151,7 +184,7 @@
TypeResolver typeResolver,
ClassIntrospector classIntrospector) async {
for (MacroApplication macroApplication in macroApplications) {
- await macroExecutor.executeDeclarationsPhase(
+ await _macroExecutor.executeDeclarationsPhase(
macroApplication.instanceIdentifier,
declaration,
typeResolver,
@@ -160,7 +193,7 @@
}
Future<void> applyDeclarationMacros() async {
- TypeResolver typeResolver = new _TypeResolver();
+ TypeResolver typeResolver = new _TypeResolver(this);
ClassIntrospector classIntrospector = new _ClassIntrospector();
for (MapEntry<SourceLibraryBuilder,
LibraryMacroApplicationData> libraryEntry in libraryData.entries) {
@@ -186,19 +219,24 @@
TypeDeclarationResolver typeDeclarationResolver) async {
List<MacroExecutionResult> results = [];
for (MacroApplication macroApplication in macroApplications) {
- MacroExecutionResult result = await macroExecutor.executeDefinitionsPhase(
- macroApplication.instanceIdentifier,
- declaration,
- typeResolver,
- classIntrospector,
- typeDeclarationResolver);
+ MacroExecutionResult result =
+ await _macroExecutor.executeDefinitionsPhase(
+ macroApplication.instanceIdentifier,
+ declaration,
+ typeResolver,
+ classIntrospector,
+ typeDeclarationResolver);
results.add(result);
}
return results;
}
- Future<void> applyDefinitionMacros() async {
- TypeResolver typeResolver = new _TypeResolver();
+ late TypeEnvironment typeEnvironment;
+
+ Future<void> applyDefinitionMacros(
+ CoreTypes coreTypes, ClassHierarchy classHierarchy) async {
+ typeEnvironment = new TypeEnvironment(coreTypes, classHierarchy);
+ TypeResolver typeResolver = new _TypeResolver(this);
ClassIntrospector classIntrospector = new _ClassIntrospector();
TypeDeclarationResolver typeDeclarationResolver =
new _TypeDeclarationResolver();
@@ -222,126 +260,179 @@
}
}
}
-}
-class MacroApplication {
- final ClassBuilder classBuilder;
- final String constructorName;
- // TODO(johnniwinther): Add support for arguments.
-
- MacroApplication(this.classBuilder, this.constructorName);
-
- late MacroInstanceIdentifier instanceIdentifier;
-}
-
-class MacroApplicationDataForTesting {
- Map<SourceLibraryBuilder, LibraryMacroApplicationData> libraryData = {};
- Map<MemberBuilder, List<MacroExecutionResult>> memberDefinitionsResults = {};
-}
-
-class LibraryMacroApplicationData {
- Map<SourceClassBuilder, ClassMacroApplicationData> classData = {};
- Map<MemberBuilder, List<MacroApplication>> memberApplications = {};
-}
-
-class ClassMacroApplicationData {
- List<MacroApplication>? classApplications;
- Map<MemberBuilder, List<MacroApplication>> memberApplications = {};
-}
-
-FunctionDeclaration createTopLevelFunctionDeclaration(
- SourceProcedureBuilder builder) {
- List<ParameterDeclarationImpl>? positionalParameters;
- List<ParameterDeclarationImpl>? namedParameters;
-
- List<FormalParameterBuilder>? formals = builder.formals;
- if (formals == null) {
- positionalParameters = namedParameters = const [];
- } else {
- positionalParameters = [];
- namedParameters = [];
- for (FormalParameterBuilder formal in formals) {
- TypeAnnotationImpl type = computeTypeAnnotation(formal.type);
- // TODO(johnniwinther): Support default values.
- if (formal.isNamed) {
- namedParameters.add(new ParameterDeclarationImpl(
- id: _removeInstanceId++,
- name: formal.name,
- isRequired: formal.isNamedRequired,
- isNamed: true,
- type: type,
- defaultValue: null));
- } else {
- positionalParameters.add(new ParameterDeclarationImpl(
- id: _removeInstanceId++,
- name: formal.name,
- isRequired: formal.isRequired,
- isNamed: false,
- type: type,
- defaultValue: null));
- }
- }
+ void close() {
+ _macroExecutor.close();
+ _staticTypeCache.clear();
+ _typeAnnotationCache.clear();
}
- return new FunctionDeclarationImpl(
- id: _removeInstanceId++,
- name: builder.name,
- isAbstract: builder.isAbstract,
- isExternal: builder.isExternal,
- isGetter: builder.isGetter,
- isSetter: builder.isSetter,
- positionalParameters: positionalParameters,
- namedParameters: namedParameters,
- returnType: computeTypeAnnotation(builder.returnType),
- // TODO(johnniwinther): Support typeParameters
- typeParameters: const []);
+ FunctionDeclaration createTopLevelFunctionDeclaration(
+ SourceProcedureBuilder builder) {
+ List<ParameterDeclarationImpl>? positionalParameters;
+ List<ParameterDeclarationImpl>? namedParameters;
+
+ List<FormalParameterBuilder>? formals = builder.formals;
+ if (formals == null) {
+ positionalParameters = namedParameters = const [];
+ } else {
+ positionalParameters = [];
+ namedParameters = [];
+ for (FormalParameterBuilder formal in formals) {
+ TypeAnnotationImpl type =
+ computeTypeAnnotation(builder.library, formal.type);
+ // TODO(johnniwinther): Support default values.
+ if (formal.isNamed) {
+ namedParameters.add(new ParameterDeclarationImpl(
+ id: RemoteInstance.uniqueId,
+ name: formal.name,
+ isRequired: formal.isNamedRequired,
+ isNamed: true,
+ type: type,
+ defaultValue: null));
+ } else {
+ positionalParameters.add(new ParameterDeclarationImpl(
+ id: RemoteInstance.uniqueId,
+ name: formal.name,
+ isRequired: formal.isRequired,
+ isNamed: false,
+ type: type,
+ defaultValue: null));
+ }
+ }
+ }
+
+ return new FunctionDeclarationImpl(
+ id: RemoteInstance.uniqueId,
+ name: builder.name,
+ isAbstract: builder.isAbstract,
+ isExternal: builder.isExternal,
+ isGetter: builder.isGetter,
+ isSetter: builder.isSetter,
+ positionalParameters: positionalParameters,
+ namedParameters: namedParameters,
+ returnType: computeTypeAnnotation(builder.library, builder.returnType),
+ // TODO(johnniwinther): Support typeParameters
+ typeParameters: const []);
+ }
+
+ Map<TypeBuilder?, _NamedTypeAnnotationImpl> _typeAnnotationCache = {};
+
+ List<TypeAnnotationImpl> computeTypeAnnotations(
+ LibraryBuilder library, List<TypeBuilder>? typeBuilders) {
+ if (typeBuilders == null) return const [];
+ return new List.generate(typeBuilders.length,
+ (int index) => computeTypeAnnotation(library, typeBuilders[index]));
+ }
+
+ _NamedTypeAnnotationImpl _computeTypeAnnotation(
+ LibraryBuilder libraryBuilder, TypeBuilder? typeBuilder) {
+ if (typeBuilder != null) {
+ if (typeBuilder is NamedTypeBuilder) {
+ Object name = typeBuilder.name;
+ List<TypeAnnotationImpl> typeArguments =
+ computeTypeAnnotations(libraryBuilder, typeBuilder.arguments);
+ bool isNullable = typeBuilder.nullabilityBuilder.isNullable;
+ if (name is String) {
+ return new _NamedTypeAnnotationImpl(
+ typeBuilder: typeBuilder,
+ libraryBuilder: libraryBuilder,
+ id: RemoteInstance.uniqueId,
+ name: name,
+ typeArguments: typeArguments,
+ isNullable: isNullable);
+ } else if (name is QualifiedName) {
+ assert(name.qualifier is String);
+ return new _NamedTypeAnnotationImpl(
+ typeBuilder: typeBuilder,
+ libraryBuilder: libraryBuilder,
+ id: RemoteInstance.uniqueId,
+ name: '${name.qualifier}.${name.name}',
+ typeArguments: typeArguments,
+ isNullable: isNullable);
+ }
+ }
+ }
+ return new _NamedTypeAnnotationImpl(
+ typeBuilder: typeBuilder,
+ libraryBuilder: libraryBuilder,
+ id: RemoteInstance.uniqueId,
+ name: 'dynamic',
+ isNullable: false,
+ typeArguments: const []);
+ }
+
+ TypeAnnotationImpl computeTypeAnnotation(
+ LibraryBuilder libraryBuilder, TypeBuilder? typeBuilder) {
+ return _typeAnnotationCache[typeBuilder] ??=
+ _computeTypeAnnotation(libraryBuilder, typeBuilder);
+ }
+
+ StaticType resolveTypeAnnotation(_NamedTypeAnnotationImpl typeAnnotation) {
+ TypeBuilder? typeBuilder = typeAnnotation.typeBuilder;
+ LibraryBuilder libraryBuilder = typeAnnotation.libraryBuilder;
+ DartType dartType;
+ if (typeBuilder != null) {
+ dartType = typeBuilder.build(libraryBuilder);
+ } else {
+ dartType = const DynamicType();
+ }
+ return createStaticType(dartType);
+ }
+
+ Map<DartType, _StaticTypeImpl> _staticTypeCache = {};
+
+ StaticType createStaticType(DartType dartType) {
+ return _staticTypeCache[dartType] ??= new _StaticTypeImpl(this, dartType);
+ }
}
-// TODO(johnniwinther): Cache remote instances when needed.
-int _removeInstanceId = 0;
+class _NamedTypeAnnotationImpl extends NamedTypeAnnotationImpl {
+ final TypeBuilder? typeBuilder;
+ final LibraryBuilder libraryBuilder;
-List<TypeAnnotationImpl> computeTypeAnnotations(
- List<TypeBuilder>? typeBuilders) {
- if (typeBuilders == null) return const [];
- return new List.generate(typeBuilders.length,
- (int index) => computeTypeAnnotation(typeBuilders[index]));
-}
-
-TypeAnnotationImpl computeTypeAnnotation(TypeBuilder? typeBuilder) {
- if (typeBuilder != null) {
- if (typeBuilder is NamedTypeBuilder) {
- Object name = typeBuilder.name;
- List<TypeAnnotationImpl> typeArguments =
- computeTypeAnnotations(typeBuilder.arguments);
- bool isNullable = typeBuilder.nullabilityBuilder.isNullable;
- if (name is String) {
- return new NamedTypeAnnotationImpl(
- id: _removeInstanceId++,
+ _NamedTypeAnnotationImpl({
+ required this.typeBuilder,
+ required this.libraryBuilder,
+ required int id,
+ required bool isNullable,
+ required String name,
+ required List<TypeAnnotationImpl> typeArguments,
+ }) : super(
+ id: id,
+ isNullable: isNullable,
name: name,
- typeArguments: typeArguments,
- isNullable: isNullable);
- } else if (name is QualifiedName) {
- assert(name.qualifier is String);
- return new NamedTypeAnnotationImpl(
- id: _removeInstanceId++,
- name: '${name.qualifier}.${name.name}',
- typeArguments: typeArguments,
- isNullable: isNullable);
- }
- }
+ typeArguments: typeArguments);
+}
+
+class _StaticTypeImpl extends StaticType {
+ final MacroApplications macroApplications;
+ final DartType type;
+
+ _StaticTypeImpl(this.macroApplications, this.type);
+
+ @override
+ Future<bool> isExactly(covariant _StaticTypeImpl other) {
+ return new Future.value(type == other.type);
}
- return new NamedTypeAnnotationImpl(
- id: _removeInstanceId++,
- name: 'dynamic',
- isNullable: false,
- typeArguments: const []);
+
+ @override
+ Future<bool> isSubtypeOf(covariant _StaticTypeImpl other) {
+ return new Future.value(macroApplications.typeEnvironment
+ .isSubtypeOf(type, other.type, SubtypeCheckMode.withNullabilities));
+ }
}
class _TypeResolver implements TypeResolver {
+ final MacroApplications macroApplications;
+
+ _TypeResolver(this.macroApplications);
+
@override
- Future<StaticType> resolve(TypeAnnotation typeAnnotation) {
- // TODO: implement resolve
- throw new UnimplementedError('_TypeResolver.resolve');
+ Future<StaticType> resolve(
+ covariant _NamedTypeAnnotationImpl typeAnnotation) {
+ return new Future.value(
+ macroApplications.resolveTypeAnnotation(typeAnnotation));
}
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
index c880b78..dcaf732 100644
--- a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
@@ -357,45 +357,42 @@
if (formal.isSuperInitializingFormal) {
superInitializingFormalIndex++;
bool hasImmediatelyDeclaredInitializer = formal.hasDeclaredInitializer;
- if (formal.type == null) {
- DartType? type;
- if (formal.isPositional) {
- if (superInitializingFormalIndex < superFormals.length) {
- FormalParameterBuilder correspondingSuperFormal =
- superFormals[superInitializingFormalIndex];
- formal.hasDeclaredInitializer =
- hasImmediatelyDeclaredInitializer ||
- correspondingSuperFormal.hasDeclaredInitializer;
- if (!hasImmediatelyDeclaredInitializer) {
- (positionalSuperParameters ??= <int>[]).add(formalIndex);
- }
- type = correspondingSuperFormal.variable!.type;
- } else {
- // TODO(cstefantsova): Report an error.
+ FormalParameterBuilder? correspondingSuperFormal;
+
+ if (formal.isPositional) {
+ if (superInitializingFormalIndex < superFormals.length) {
+ correspondingSuperFormal =
+ superFormals[superInitializingFormalIndex];
+ formal.hasDeclaredInitializer = hasImmediatelyDeclaredInitializer ||
+ correspondingSuperFormal.hasDeclaredInitializer;
+ if (!hasImmediatelyDeclaredInitializer) {
+ (positionalSuperParameters ??= <int>[]).add(formalIndex);
}
} else {
- FormalParameterBuilder? correspondingSuperFormal;
- for (FormalParameterBuilder superFormal in superFormals) {
- if (superFormal.isNamed && superFormal.name == formal.name) {
- correspondingSuperFormal = superFormal;
- break;
- }
- }
-
- if (correspondingSuperFormal != null) {
- formal.hasDeclaredInitializer =
- hasImmediatelyDeclaredInitializer ||
- correspondingSuperFormal.hasDeclaredInitializer;
- if (!hasImmediatelyDeclaredInitializer) {
- (namedSuperParameters ??= <String>[]).add(formal.name);
- }
- type = correspondingSuperFormal.variable!.type;
- } else {
- // TODO(cstefantsova): Report an error.
+ // TODO(cstefantsova): Report an error.
+ }
+ } else {
+ for (FormalParameterBuilder superFormal in superFormals) {
+ if (superFormal.isNamed && superFormal.name == formal.name) {
+ correspondingSuperFormal = superFormal;
+ break;
}
}
+ if (correspondingSuperFormal != null) {
+ formal.hasDeclaredInitializer = hasImmediatelyDeclaredInitializer ||
+ correspondingSuperFormal.hasDeclaredInitializer;
+ if (!hasImmediatelyDeclaredInitializer) {
+ (namedSuperParameters ??= <String>[]).add(formal.name);
+ }
+ } else {
+ // TODO(cstefantsova): Report an error.
+ }
+ }
+
+ if (formal.type == null) {
+ DartType? type = correspondingSuperFormal?.variable?.type;
if (substitution.isNotEmpty && type != null) {
type = substitute(type, substitution);
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index e8b0af8..f481250 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -1364,26 +1364,42 @@
dataForTesting!.macroDeclarationData.macrosAreAvailable = true;
}
- Set<ClassBuilder> macroClasses = {macroClassBuilder};
- Set<Uri> macroLibraries = {macroLibraryBuilder.importUri};
+ Set<ClassBuilder> macroClasses = {};
- for (SourceLibraryBuilder sourceLibraryBuilder in sourceLibraryBuilders) {
- Iterator<Builder> iterator = sourceLibraryBuilder.iterator;
+ /// Libraries containing macros that need compilation.
+ Set<Uri> macroLibraries = {};
+
+ /// Libraries containing precompiled macro classes.
+ Set<Uri> precompiledMacroLibraries = {};
+
+ Map<MacroClass, Uri> precompiledMacroUris =
+ target.context.options.precompiledMacroUris;
+
+ for (LibraryBuilder libraryBuilder in libraryBuilders) {
+ Iterator<Builder> iterator = libraryBuilder.iterator;
while (iterator.moveNext()) {
Builder builder = iterator.current;
- if (builder is SourceClassBuilder && builder.isMacro) {
- macroClasses.add(builder);
- macroLibraries.add(builder.library.importUri);
- if (retainDataForTesting) {
- (dataForTesting!.macroDeclarationData
- .macroDeclarations[builder.library.importUri] ??= [])
- .add(builder.name);
+ if (builder is ClassBuilder && builder.isMacro) {
+ Uri libraryUri = builder.library.importUri;
+ MacroClass macroClass = new MacroClass(libraryUri, builder.name);
+ if (!precompiledMacroUris.containsKey(macroClass)) {
+ macroClasses.add(builder);
+ macroLibraries.add(libraryUri);
+ if (retainDataForTesting) {
+ (dataForTesting!.macroDeclarationData
+ .macroDeclarations[libraryUri] ??= [])
+ .add(builder.name);
+ }
+ } else {
+ precompiledMacroLibraries.add(libraryUri);
}
}
}
}
- bool isDillLibrary(Uri uri) => _builders[uri]?.loader != this;
+ if (macroClasses.isEmpty) {
+ return;
+ }
List<List<Uri>> computeCompilationSequence(Graph<Uri> libraryGraph,
{required bool Function(Uri) filter}) {
@@ -1418,9 +1434,39 @@
return layeredComponents;
}
- List<List<Uri>> compilationSteps = computeCompilationSequence(
- new BuilderGraph(_builders),
- filter: isDillLibrary);
+ Graph<Uri> graph = new BuilderGraph(_builders);
+
+ /// Libraries that are considered precompiled. These are libraries that are
+ /// either given as precompiled macro libraries, or libraries that these
+ /// depend upon.
+ // TODO(johnniwinther): Can we assume that the precompiled dills are
+ // self-contained?
+ Set<Uri> precompiledLibraries = {};
+
+ void addPrecompiledLibrary(Uri uri) {
+ if (precompiledLibraries.add(uri)) {
+ for (Uri neighbor in graph.neighborsOf(uri)) {
+ addPrecompiledLibrary(neighbor);
+ }
+ }
+ }
+
+ for (LibraryBuilder builder in _builders.values) {
+ if (builder.loader != this) {
+ addPrecompiledLibrary(builder.importUri);
+ } else if (precompiledMacroLibraries.contains(builder.importUri)) {
+ assert(
+ !macroLibraries.contains(builder.importUri),
+ "Macro library ${builder.importUri} is only partially "
+ "precompiled.");
+ addPrecompiledLibrary(builder.importUri);
+ }
+ }
+
+ bool isPrecompiledLibrary(Uri uri) => precompiledLibraries.contains(uri);
+
+ List<List<Uri>> compilationSteps =
+ computeCompilationSequence(graph, filter: isPrecompiledLibrary);
if (retainDataForTesting) {
dataForTesting!.macroDeclarationData.compilationSequence =
compilationSteps;
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index 0deb368..2470a1a 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -172,7 +172,7 @@
}
// TODO(johnniwinther): Should we reuse the macro executor on subsequent
// compilations where possible?
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
return new InternalCompilerResult(
summary: summary,
diff --git a/pkg/front_end/test/explicit_creation_git_test.dart b/pkg/front_end/test/explicit_creation_git_test.dart
index 0f00042..3200635 100644
--- a/pkg/front_end/test/explicit_creation_git_test.dart
+++ b/pkg/front_end/test/explicit_creation_git_test.dart
@@ -104,7 +104,7 @@
BuildResult buildResult = await kernelTarget.buildOutlines();
buildResult = await kernelTarget.buildComponent(
macroApplications: buildResult.macroApplications);
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
});
print("Done in ${stopwatch.elapsedMilliseconds} ms. "
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index d4e1b8c..02231dd 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -1856,7 +1856,7 @@
: context.verify);
p = buildResult.component!;
}
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
// To avoid possible crash in mixin transformation in the transformation
// of the user of this linked dependency we have to transform this too.
@@ -1928,7 +1928,7 @@
if (updateComments) {
await instrumentation.fixSource(description.uri, false);
} else {
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
return new Result<ComponentResult>(
new ComponentResult(description, p, userLibraries,
compilationSetup, sourceTarget),
@@ -1939,7 +1939,7 @@
}
}
}
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
return pass(new ComponentResult(
description, p, userLibraries, compilationSetup, sourceTarget));
});
diff --git a/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart b/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart
index a5469f1..b686cc0 100644
--- a/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart
+++ b/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart
@@ -15,3 +15,21 @@
}'''));
}
}
+
+macro class FunctionDefinitionMacro2 implements FunctionDefinitionMacro {
+ const FunctionDefinitionMacro2();
+
+ FutureOr<void> buildDefinitionForFunction(
+ FunctionDeclaration function, FunctionDefinitionBuilder builder) async {
+ if (function.positionalParameters.isEmpty) {
+ return;
+ }
+ StaticType returnType = await builder.resolve(function.returnType);
+ StaticType parameterType =
+ await builder.resolve(function.positionalParameters.first.type);
+ builder.augment(new FunctionBodyCode.fromString('''{
+ print('isExactly=${await returnType.isExactly(parameterType)}');
+ print('isSubtype=${await returnType.isSubtypeOf(parameterType)}');
+}'''));
+ }
+}
diff --git a/pkg/front_end/test/macro_application/data/tests/parameters.dart b/pkg/front_end/test/macro_application/data/tests/parameters.dart
index 41fcf36..bb606bb 100644
--- a/pkg/front_end/test/macro_application/data/tests/parameters.dart
+++ b/pkg/front_end/test/macro_application/data/tests/parameters.dart
@@ -4,30 +4,30 @@
import 'package:macro/macro.dart';
-@FunctionDefinitionMacro1()
/*member: topLevelFunction1:
augment void topLevelFunction1(int a, ) {
return 42;
}*/
+@FunctionDefinitionMacro1()
external void topLevelFunction1(int a);
-@FunctionDefinitionMacro1()
/*member: topLevelFunction2:
augment void topLevelFunction2(int a, int b, ) {
return 42;
}*/
+@FunctionDefinitionMacro1()
external void topLevelFunction2(int a, int b);
-@FunctionDefinitionMacro1()
/*member: topLevelFunction3:
augment void topLevelFunction3(int a, [int? b, ]) {
return 42;
}*/
+@FunctionDefinitionMacro1()
external void topLevelFunction3(int a, [int? b]);
-@FunctionDefinitionMacro1()
/*member: topLevelFunction4:
augment void topLevelFunction4(int a, {int? b, int? c, }) {
return 42;
}*/
+@FunctionDefinitionMacro1()
external void topLevelFunction4(int a, {int? b, int? c});
diff --git a/pkg/front_end/test/macro_application/data/tests/subtypes.dart b/pkg/front_end/test/macro_application/data/tests/subtypes.dart
new file mode 100644
index 0000000..245908a
--- /dev/null
+++ b/pkg/front_end/test/macro_application/data/tests/subtypes.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2022, 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 'package:macro/macro.dart';
+
+class A {}
+
+class B1 {}
+
+class B2 extends B1 {}
+
+class C1 extends C2 {}
+
+class C2 {}
+
+class D1 {}
+
+class D2 {}
+
+/*member: topLevelFunction1:
+augment A topLevelFunction1(A a, ) {
+ print('isExactly=true');
+ print('isSubtype=true');
+}*/
+@FunctionDefinitionMacro2()
+external A topLevelFunction1(A a);
+
+/*member: topLevelFunction2:
+augment B2 topLevelFunction2(B1 a, ) {
+ print('isExactly=false');
+ print('isSubtype=true');
+}*/
+@FunctionDefinitionMacro2()
+external B2 topLevelFunction2(B1 a);
+
+/*member: topLevelFunction3:
+augment C2 topLevelFunction3(C1 a, ) {
+ print('isExactly=false');
+ print('isSubtype=false');
+}*/
+@FunctionDefinitionMacro2()
+external C2 topLevelFunction3(C1 a);
+
+/*member: topLevelFunction4:
+augment D2 topLevelFunction4(D1 a, ) {
+ print('isExactly=false');
+ print('isSubtype=false');
+}*/
+@FunctionDefinitionMacro2()
+external D2 topLevelFunction4(D1 a);
diff --git a/pkg/front_end/test/macro_application/macro_application_test.dart b/pkg/front_end/test/macro_application/macro_application_test.dart
index db171e8..d24b4ae 100644
--- a/pkg/front_end/test/macro_application/macro_application_test.dart
+++ b/pkg/front_end/test/macro_application/macro_application_test.dart
@@ -25,6 +25,13 @@
import 'package:kernel/target/targets.dart';
import 'package:vm/target/vm.dart';
+const Map<String, Map<String, List<String>>> macroDeclarations = {
+ 'package:macro/macro.dart': {
+ 'FunctionDefinitionMacro1': [''],
+ 'FunctionDefinitionMacro2': [''],
+ }
+};
+
Future<Uri> compileMacros(Directory directory) async {
CompilerOptions options = new CompilerOptions();
options.target = new VmTarget(new TargetFlags());
@@ -32,10 +39,9 @@
options.environmentDefines = {};
options.packagesFileUri = Platform.script.resolve('data/package_config.json');
- CompilerResult? compilerResult = await compileScript({
- 'main.dart': bootstrapMacroIsolate(
- 'package:macro/macro.dart', 'FunctionDefinitionMacro1', [''])
- }, options: options, requireMain: false);
+ CompilerResult? compilerResult = await compileScript(
+ {'main.dart': bootstrapMacroIsolate(macroDeclarations)},
+ options: options, requireMain: false);
Uri uri = directory.absolute.uri.resolve('macros.dill');
await writeComponentToFile(compilerResult!.component!, uri);
return uri;
@@ -48,11 +54,14 @@
await Directory.systemTemp.createTemp('macro_application');
Uri macrosUri = await compileMacros(tempDirectory);
- Map<MacroClass, Uri> precompiledMacroUris = {
- new MacroClass(
- Uri.parse('package:macro/macro.dart'), 'FunctionDefinitionMacro1'):
- macrosUri
- };
+ Map<MacroClass, Uri> precompiledMacroUris = {};
+ macroDeclarations
+ .forEach((String macroUri, Map<String, List<String>> macroClasses) {
+ macroClasses.forEach((String macroClass, List<String> constructorNames) {
+ precompiledMacroUris[new MacroClass(Uri.parse(macroUri), macroClass)] =
+ macrosUri;
+ });
+ });
Directory dataDir =
new Directory.fromUri(Platform.script.resolve('data/tests'));
diff --git a/pkg/front_end/test/macros/data/package_config.json b/pkg/front_end/test/macros/data/package_config.json
index 9de8189..f176d49 100644
--- a/pkg/front_end/test/macros/data/package_config.json
+++ b/pkg/front_end/test/macros/data/package_config.json
@@ -6,6 +6,10 @@
"rootUri": "pkgs/macro/lib/"
},
{
+ "name": "precompiled_macro",
+ "rootUri": "pkgs/precompiled_macro/lib/"
+ },
+ {
"name": "_fe_analyzer_shared",
"rootUri": "../../../../_fe_analyzer_shared/lib/"
}
diff --git a/pkg/front_end/test/macros/data/pkgs/precompiled_macro/lib/precompiled_macro.dart b/pkg/front_end/test/macros/data/pkgs/precompiled_macro/lib/precompiled_macro.dart
new file mode 100644
index 0000000..8d112ca
--- /dev/null
+++ b/pkg/front_end/test/macros/data/pkgs/precompiled_macro/lib/precompiled_macro.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2022, 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 'package:_fe_analyzer_shared/src/macros/api.dart';
+
+import 'src/macro_base.dart';
+
+macro class PrecompiledMacro extends MacroBase implements Macro {
+ const PrecompiledMacro();
+}
diff --git a/pkg/front_end/test/macros/data/pkgs/precompiled_macro/lib/src/macro_base.dart b/pkg/front_end/test/macros/data/pkgs/precompiled_macro/lib/src/macro_base.dart
new file mode 100644
index 0000000..e503d1b
--- /dev/null
+++ b/pkg/front_end/test/macros/data/pkgs/precompiled_macro/lib/src/macro_base.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2022, 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.
+
+class MacroBase {
+ const MacroBase();
+}
diff --git a/pkg/front_end/test/macros/data/tests/all_precompiled.dart b/pkg/front_end/test/macros/data/tests/all_precompiled.dart
new file mode 100644
index 0000000..9310930
--- /dev/null
+++ b/pkg/front_end/test/macros/data/tests/all_precompiled.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, 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.
+
+/*library:
+ macroClassIds=[package:precompiled_macro/precompiled_macro.dart/PrecompiledMacro],
+ macroInstanceIds=[package:precompiled_macro/precompiled_macro.dart/PrecompiledMacro/()],
+ macrosAreApplied,
+ macrosAreAvailable
+*/
+
+import 'package:precompiled_macro/precompiled_macro.dart';
+
+/*member: main:appliedMacros=[PrecompiledMacro.new]*/
+@PrecompiledMacro()
+void main() {}
diff --git a/pkg/front_end/test/macros/data/tests/applications.dart b/pkg/front_end/test/macros/data/tests/applications.dart
index 4201d8c..06bf716 100644
--- a/pkg/front_end/test/macros/data/tests/applications.dart
+++ b/pkg/front_end/test/macros/data/tests/applications.dart
@@ -4,8 +4,7 @@
/*library:
compilationSequence=[
- package:_fe_analyzer_shared/src/macros/api.dart,
- package:macro/macro.dart,
+ package:_fe_analyzer_shared/src/macros/api.dart|package:macro/macro.dart,
main.dart],
macroClassIds=[
package:macro/macro.dart/Macro1,
diff --git a/pkg/front_end/test/macros/data/tests/declare_macro.dart b/pkg/front_end/test/macros/data/tests/declare_macro.dart
index 056edbd..65611e1 100644
--- a/pkg/front_end/test/macros/data/tests/declare_macro.dart
+++ b/pkg/front_end/test/macros/data/tests/declare_macro.dart
@@ -3,9 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
/*library:
- compilationSequence=[
- package:_fe_analyzer_shared/src/macros/api.dart,
- main.dart],
+ compilationSequence=[main.dart|package:_fe_analyzer_shared/src/macros/api.dart],
declaredMacros=[MyMacro],
macrosAreAvailable
*/
diff --git a/pkg/front_end/test/macros/data/tests/declare_vs_apply/main.dart b/pkg/front_end/test/macros/data/tests/declare_vs_apply/main.dart
index 1a6c048..69ea910 100644
--- a/pkg/front_end/test/macros/data/tests/declare_vs_apply/main.dart
+++ b/pkg/front_end/test/macros/data/tests/declare_vs_apply/main.dart
@@ -4,8 +4,7 @@
/*library:
compilationSequence=[
- apply_lib_dep.dart|macro_lib_dep.dart|main_lib_dep.dart|package:_fe_analyzer_shared/src/macros/api.dart,
- macro_lib.dart,
+ apply_lib_dep.dart|macro_lib.dart|macro_lib_dep.dart|main_lib_dep.dart|package:_fe_analyzer_shared/src/macros/api.dart,
apply_lib.dart|main.dart],
macroClassIds=[macro_lib.dart/Macro1],
macroInstanceIds=[macro_lib.dart/Macro1/()],
diff --git a/pkg/front_end/test/macros/data/tests/direct_import.dart b/pkg/front_end/test/macros/data/tests/direct_import.dart
index a07f128..793a5f4 100644
--- a/pkg/front_end/test/macros/data/tests/direct_import.dart
+++ b/pkg/front_end/test/macros/data/tests/direct_import.dart
@@ -2,12 +2,7 @@
// 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.
-/*library:
- compilationSequence=[
- package:_fe_analyzer_shared/src/macros/api.dart,
- main.dart],
- macrosAreAvailable
-*/
+/*library: macrosAreAvailable*/
// ignore: unused_import
import 'package:_fe_analyzer_shared/src/macros/api.dart';
diff --git a/pkg/front_end/test/macros/data/tests/import_macro_builder.dart b/pkg/front_end/test/macros/data/tests/import_macro_builder.dart
index a07f128..793a5f4 100644
--- a/pkg/front_end/test/macros/data/tests/import_macro_builder.dart
+++ b/pkg/front_end/test/macros/data/tests/import_macro_builder.dart
@@ -2,12 +2,7 @@
// 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.
-/*library:
- compilationSequence=[
- package:_fe_analyzer_shared/src/macros/api.dart,
- main.dart],
- macrosAreAvailable
-*/
+/*library: macrosAreAvailable*/
// ignore: unused_import
import 'package:_fe_analyzer_shared/src/macros/api.dart';
diff --git a/pkg/front_end/test/macros/data/tests/import_macro_package.dart b/pkg/front_end/test/macros/data/tests/import_macro_package.dart
index 0c25eea..9619bb1 100644
--- a/pkg/front_end/test/macros/data/tests/import_macro_package.dart
+++ b/pkg/front_end/test/macros/data/tests/import_macro_package.dart
@@ -4,8 +4,7 @@
/*library:
compilationSequence=[
- package:_fe_analyzer_shared/src/macros/api.dart,
- package:macro/macro.dart,
+ package:_fe_analyzer_shared/src/macros/api.dart|package:macro/macro.dart,
main.dart],
macrosAreAvailable
*/
diff --git a/pkg/front_end/test/macros/data/tests/import_macro_source/main.dart b/pkg/front_end/test/macros/data/tests/import_macro_source/main.dart
index dce865b..15c660c 100644
--- a/pkg/front_end/test/macros/data/tests/import_macro_source/main.dart
+++ b/pkg/front_end/test/macros/data/tests/import_macro_source/main.dart
@@ -4,8 +4,7 @@
/*library:
compilationSequence=[
- package:_fe_analyzer_shared/src/macros/api.dart,
- macro_lib.dart,
+ macro_lib.dart|package:_fe_analyzer_shared/src/macros/api.dart,
main.dart],
macrosAreAvailable
*/
diff --git a/pkg/front_end/test/macros/data/tests/macro_declarations.dart b/pkg/front_end/test/macros/data/tests/macro_declarations.dart
index b6cb47f..c780d61 100644
--- a/pkg/front_end/test/macros/data/tests/macro_declarations.dart
+++ b/pkg/front_end/test/macros/data/tests/macro_declarations.dart
@@ -3,9 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
/*library:
- compilationSequence=[
- package:_fe_analyzer_shared/src/macros/api.dart,
- main.dart],
+ compilationSequence=[main.dart|package:_fe_analyzer_shared/src/macros/api.dart],
declaredMacros=[
Extends,
ExtendsAlias,
diff --git a/pkg/front_end/test/macros/data/tests/multiple_macros/main.dart b/pkg/front_end/test/macros/data/tests/multiple_macros/main.dart
index 4aeb2a7..873d202 100644
--- a/pkg/front_end/test/macros/data/tests/multiple_macros/main.dart
+++ b/pkg/front_end/test/macros/data/tests/multiple_macros/main.dart
@@ -4,8 +4,7 @@
/*library:
compilationSequence=[
- package:_fe_analyzer_shared/src/macros/api.dart,
- macro_lib1.dart|macro_lib2a.dart,
+ macro_lib1.dart|macro_lib2a.dart|package:_fe_analyzer_shared/src/macros/api.dart,
macro_lib2b.dart,
main.dart],
macroClassIds=[
diff --git a/pkg/front_end/test/macros/data/tests/precompiled.dart b/pkg/front_end/test/macros/data/tests/precompiled.dart
new file mode 100644
index 0000000..5b29de2
--- /dev/null
+++ b/pkg/front_end/test/macros/data/tests/precompiled.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2022, 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.
+
+/*library:
+ compilationSequence=[
+ package:macro/macro.dart,
+ main.dart],
+ macroClassIds=[
+ package:macro/macro.dart/Macro1,
+ package:precompiled_macro/precompiled_macro.dart/PrecompiledMacro],
+ macroInstanceIds=[
+ package:macro/macro.dart/Macro1/(),
+ package:precompiled_macro/precompiled_macro.dart/PrecompiledMacro/()],
+ macrosAreApplied,
+ macrosAreAvailable
+*/
+
+import 'package:precompiled_macro/precompiled_macro.dart';
+import 'package:macro/macro.dart';
+
+/*member: main:appliedMacros=[
+ Macro1.new,
+ PrecompiledMacro.new]*/
+@PrecompiledMacro()
+@Macro1()
+void main() {}
diff --git a/pkg/front_end/test/macros/data/tests/use_macro_package.dart b/pkg/front_end/test/macros/data/tests/use_macro_package.dart
index 691f58a..c3b123e 100644
--- a/pkg/front_end/test/macros/data/tests/use_macro_package.dart
+++ b/pkg/front_end/test/macros/data/tests/use_macro_package.dart
@@ -4,8 +4,7 @@
/*library:
compilationSequence=[
- package:_fe_analyzer_shared/src/macros/api.dart,
- package:macro/macro.dart,
+ package:_fe_analyzer_shared/src/macros/api.dart|package:macro/macro.dart,
main.dart],
macroClassIds=[
package:macro/macro.dart/Macro1,
diff --git a/pkg/front_end/test/macros/data/tests/use_macro_source/main.dart b/pkg/front_end/test/macros/data/tests/use_macro_source/main.dart
index 5bc5073..eff50a1 100644
--- a/pkg/front_end/test/macros/data/tests/use_macro_source/main.dart
+++ b/pkg/front_end/test/macros/data/tests/use_macro_source/main.dart
@@ -4,8 +4,7 @@
/*library:
compilationSequence=[
- package:_fe_analyzer_shared/src/macros/api.dart,
- macro_lib.dart,
+ macro_lib.dart|package:_fe_analyzer_shared/src/macros/api.dart,
main.dart],
macroClassIds=[
macro_lib.dart/Macro1,
diff --git a/pkg/front_end/test/macros/macro_test.dart b/pkg/front_end/test/macros/macro_test.dart
index 756e587..25ee5db 100644
--- a/pkg/front_end/test/macros/macro_test.dart
+++ b/pkg/front_end/test/macros/macro_test.dart
@@ -43,6 +43,11 @@
CompilerOptions options, TestData testData) {
TestMacroExecutor macroExecutor = new TestMacroExecutor();
options.macroExecutorProvider = () async => macroExecutor;
+ Uri precompiledPackage =
+ Uri.parse('package:precompiled_macro/precompiled_macro.dart');
+ options.precompiledMacroUris = {
+ new MacroClass(precompiledPackage, 'PrecompiledMacro'): dummyUri,
+ };
return macroExecutor;
}
}
@@ -295,10 +300,6 @@
@override
Future<MacroClassIdentifier> loadMacro(Uri library, String name,
{Uri? precompiledKernelUri}) async {
- if (precompiledKernelUri != null) {
- throw new UnsupportedError(
- 'Precompiled kernel not supported for this implementation.');
- }
_MacroClassIdentifier id = new _MacroClassIdentifier(library, name);
macroClasses.add(id);
return id;
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart
new file mode 100644
index 0000000..f5b1bd9
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, 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.
+
+class S {
+ int s1;
+ int s2;
+ S([this.s1 = 1, this.s2 = 2]);
+}
+
+class C extends S {
+ int c1;
+ C(this.c1, [int super.s1, int x = 0, int super.s2]);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.strong.expect b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.strong.expect
new file mode 100644
index 0000000..3bd8f09
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.strong.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class S extends core::Object {
+ field core::int s1;
+ field core::int s2;
+ constructor •([core::int s1 = #C1, core::int s2 = #C2]) → self::S
+ : self::S::s1 = s1, self::S::s2 = s2, super core::Object::•()
+ ;
+}
+class C extends self::S {
+ field core::int c1;
+ constructor •(core::int c1, [dynamic s1 = #C1, core::int x = #C3, dynamic s2 = #C2]) → self::C
+ : self::C::c1 = c1, super self::S::•(s1, s2)
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 1
+ #C2 = 2
+ #C3 = 0
+}
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.strong.transformed.expect b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.strong.transformed.expect
new file mode 100644
index 0000000..3bd8f09
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class S extends core::Object {
+ field core::int s1;
+ field core::int s2;
+ constructor •([core::int s1 = #C1, core::int s2 = #C2]) → self::S
+ : self::S::s1 = s1, self::S::s2 = s2, super core::Object::•()
+ ;
+}
+class C extends self::S {
+ field core::int c1;
+ constructor •(core::int c1, [dynamic s1 = #C1, core::int x = #C3, dynamic s2 = #C2]) → self::C
+ : self::C::c1 = c1, super self::S::•(s1, s2)
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 1
+ #C2 = 2
+ #C3 = 0
+}
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.textual_outline.expect b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..7acd1b7
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class S {
+ int s1;
+ int s2;
+ S([this.s1 = 1, this.s2 = 2]);
+}
+class C extends S {
+ int c1;
+ C(this.c1, [int super.s1, int x = 0, int super.s2]);
+}
+main() {}
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.expect b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.expect
new file mode 100644
index 0000000..3bd8f09
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class S extends core::Object {
+ field core::int s1;
+ field core::int s2;
+ constructor •([core::int s1 = #C1, core::int s2 = #C2]) → self::S
+ : self::S::s1 = s1, self::S::s2 = s2, super core::Object::•()
+ ;
+}
+class C extends self::S {
+ field core::int c1;
+ constructor •(core::int c1, [dynamic s1 = #C1, core::int x = #C3, dynamic s2 = #C2]) → self::C
+ : self::C::c1 = c1, super self::S::•(s1, s2)
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 1
+ #C2 = 2
+ #C3 = 0
+}
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.modular.expect b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.modular.expect
new file mode 100644
index 0000000..3bd8f09
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.modular.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class S extends core::Object {
+ field core::int s1;
+ field core::int s2;
+ constructor •([core::int s1 = #C1, core::int s2 = #C2]) → self::S
+ : self::S::s1 = s1, self::S::s2 = s2, super core::Object::•()
+ ;
+}
+class C extends self::S {
+ field core::int c1;
+ constructor •(core::int c1, [dynamic s1 = #C1, core::int x = #C3, dynamic s2 = #C2]) → self::C
+ : self::C::c1 = c1, super self::S::•(s1, s2)
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 1
+ #C2 = 2
+ #C3 = 0
+}
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.outline.expect b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.outline.expect
new file mode 100644
index 0000000..aae570e
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.outline.expect
@@ -0,0 +1,18 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class S extends core::Object {
+ field core::int s1;
+ field core::int s2;
+ constructor •([core::int s1 = 1, core::int s2 = 2]) → self::S
+ ;
+}
+class C extends self::S {
+ field core::int c1;
+ constructor •(core::int c1, [dynamic s1 = 1, core::int x = 0, dynamic s2 = 2]) → self::C
+ : self::C::c1 = c1
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.transformed.expect b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.transformed.expect
new file mode 100644
index 0000000..3bd8f09
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.transformed.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class S extends core::Object {
+ field core::int s1;
+ field core::int s2;
+ constructor •([core::int s1 = #C1, core::int s2 = #C2]) → self::S
+ : self::S::s1 = s1, self::S::s2 = s2, super core::Object::•()
+ ;
+}
+class C extends self::S {
+ field core::int c1;
+ constructor •(core::int c1, [dynamic s1 = #C1, core::int x = #C3, dynamic s2 = #C2]) → self::C
+ : self::C::c1 = c1, super self::S::•(s1, s2)
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 1
+ #C2 = 2
+ #C3 = 0
+}
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 86a420c..751ebe1 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -100,10 +100,10 @@
general/issue43363: FormatterCrash
general/issue45490: FormatterCrash
general/issue45700.crash: FormatterCrash
-general/issue_46886: FormatterCrash
general/issue47495: FormatterCrash
general/issue47728_2: FormatterCrash
general/issue47728_3: FormatterCrash
+general/issue_46886: FormatterCrash
general/macro_class: FormatterCrash
general/many_errors: FormatterCrash
general/missing_prefix_name: FormatterCrash
@@ -219,6 +219,7 @@
super_parameters/simple_inference: FormatterCrash
super_parameters/simple_named_super_parameters: FormatterCrash
super_parameters/simple_positional_super_parameters: FormatterCrash
+super_parameters/super_parameters_with_types_and_default_values: FormatterCrash
super_parameters/synthesized_super_constructor_with_parameters: FormatterCrash
super_parameters/type_alias_in_supertype: FormatterCrash
super_parameters/typed_super_parameter: FormatterCrash
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index f99d05f..24fad8f 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -309,7 +309,7 @@
output: output,
omitPlatform: omitPlatform,
supportAdditionalDills: supportAdditionalDills);
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
return kernelTarget;
}
@@ -384,7 +384,7 @@
buildResult = await kernelTarget.buildComponent(
macroApplications: buildResult.macroApplications,
verify: c.options.verify);
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
Component component = buildResult.component!;
if (c.options.debugDump) {
printComponentText(component,
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 8764498..d3ec0f0 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -81,7 +81,7 @@
/// ```
/// For a character outside the Basic Multilingual Plane (plane 0) that is
/// composed of a surrogate pair, [runes] combines the pair and returns a
-/// single integer. For example, the Unicode character for a
+/// single integer. For example, the Unicode character for a
/// musical G-clef ('𝄞') with rune value 0x1D11E consists of a UTF-16 surrogate
/// pair: `0xD834` and `0xDD1E`. Using [codeUnits] returns the surrogate pair,
/// and using `runes` returns their combined value:
@@ -198,7 +198,7 @@
/// The length of the string.
///
/// Returns the number of UTF-16 code units in this string. The number
- /// of [runes] might be fewer, if the string contains characters outside
+ /// of [runes] might be fewer if the string contains characters outside
/// the Basic Multilingual Plane (plane 0):
/// ```dart
/// 'Dart'.length; // 4
@@ -346,7 +346,7 @@
/// result = string.substring(1, 4); // 'art'
/// ```
///
- /// Both [start] and [end] must be non-negative and no greater than [length], and
+ /// Both [start] and [end] must be non-negative and no greater than [length];
/// [end], if provided, must be greater than or equal to [start].
String substring(int start, [int? end]);
@@ -494,7 +494,7 @@
/// Example:
/// ```dart
/// '0.0001'.replaceFirst(RegExp(r'0'), ''); // '.0001'
- /// '0.0001'.replaceFirst(RegExp(r'0'), '7', 1); // '0.7001'
+ /// '0.0001'.replaceFirst(RegExp(r'0'), '7', 1); // '0.7001'
/// ```
String replaceFirst(Pattern from, String to, [int startIndex = 0]);
@@ -724,6 +724,44 @@
}
/// The runes (integer Unicode code points) of a [String].
+///
+/// The characters of a string are encoded in UTF-16. Decoding UTF-16, which
+/// combines surrogate pairs, yields Unicode code points. Following a similar
+/// terminology to Go, Dart uses the name 'rune' for an integer representing a
+/// Unicode code point. Use the `runes` property to get the runes of a string.
+///
+/// Example:
+/// ```dart
+/// const string = 'Dart';
+/// final runes = string.runes.toList();
+/// print(runes); // [68, 97, 114, 116]
+/// ```
+///
+/// For a character outside the Basic Multilingual Plane (plane 0) that is
+/// composed of a surrogate pair, runes combines the pair and returns a
+/// single integer.
+///
+/// For example, the Unicode character for "Man" emoji ('👨', `U+1F468`) is
+/// combined from the surrogates `U+d83d` and `U+dc68`.
+///
+/// Example:
+/// ```dart
+/// const emojiMan = '👨';
+/// print(emojiMan.runes); // (128104)
+///
+/// // Surrogate pairs:
+/// for (final item in emojiMan.codeUnits) {
+/// print(item.toRadixString(16));
+/// // d83d
+/// // dc68
+/// }
+/// ```
+///
+/// **See also:**
+/// * [Runes and grapheme clusters](
+/// https://dart.dev/guides/language/language-tour#runes-and-grapheme-clusters)
+/// in
+/// [A tour of the Dart language](https://dart.dev/guides/language/language-tour).
class Runes extends Iterable<int> {
/// The string that this is the runes of.
final String string;
diff --git a/tools/VERSION b/tools/VERSION
index 3f0e9b0..58a37e5 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 41
+PRERELEASE 42
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/dart_sdk.py b/tools/bots/dart_sdk.py
index d14f3ce..934906f 100755
--- a/tools/bots/dart_sdk.py
+++ b/tools/bots/dart_sdk.py
@@ -79,7 +79,7 @@
def CreateUploadAPIDocs():
dartdoc_dir = BuildRootPath('gen-dartdocs')
dartdoc_zip = BuildRootPath('dartdocs-api.zip')
- if CHANNEL == bot_utils.Channel.TRY:
+ if CHANNEL == bot_utils.Channel.TRY or DART_EXPERIMENTAL_BUILD == '1':
BuildDartdocAPIDocs(dartdoc_dir)
else:
UploadApiLatestFile()
@@ -222,12 +222,13 @@
BUILD_OS = utils.GuessOS()
BUILDER_NAME = os.environ.get('BUILDBOT_BUILDERNAME')
+ DART_EXPERIMENTAL_BUILD = os.environ.get('DART_EXPERIMENTAL_BUILD')
CHANNEL = bot_utils.GetChannelFromName(BUILDER_NAME)
if command == 'api_docs':
if BUILD_OS == 'linux':
CreateUploadAPIDocs()
- elif CHANNEL != bot_utils.Channel.TRY:
+ elif CHANNEL != bot_utils.Channel.TRY and DART_EXPERIMENTAL_BUILD != '1':
for arch in archs:
print('Create and upload sdk zip for ' + arch)
sdk_path = BuildRootPath('dart-sdk', arch=arch)