[cfe] Use buildAugmentationLibrary on phase 1 results

This CL add support for identifier resolution to use the
MacroExecutor.buildAugmentationLibrary for generating the code.

The CL updates the ResolvedIdentifier to have a nullable [uri] in
order to support built in identifiers, such as `void`.

Change-Id: I9436ea77c06cf5618f1977f4c9ac0490ff059587
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/232623
Reviewed-by: Jake Macdonald <jakemac@google.com>
Auto-Submit: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther 2022-02-14 11:31:25 +00:00 committed by Commit Bot
parent 0408bc6c18
commit 74a355c544
11 changed files with 209 additions and 55 deletions

View file

@ -232,9 +232,12 @@ class Arguments implements Serializable {
class ResolvedIdentifier extends Identifier {
/// The import URI for the library that defines the member that is referenced
/// by this identifier.
final Uri uri;
///
/// If this identifier is an instance member or a built-in type, like
/// `void`, [uri] is `null`.
final Uri? uri;
/// Type type of identifier this is (instance, static, top level).
/// Type of identifier this is (instance, static, top level).
final IdentifierKind kind;
/// The unqualified name of this identifier.

View file

@ -31,17 +31,20 @@ mixin AugmentationLibraryBuilder on MacroExecutor {
buildCode(part);
} else if (part is Identifier) {
ResolvedIdentifier resolved = resolveIdentifier(part);
String prefix = importPrefixes.putIfAbsent(resolved.uri, () {
String prefix = 'i${nextPrefix++}';
importsBuffer.writeln("import '${resolved.uri}' as $prefix;");
return prefix;
});
String? prefix;
if (resolved.uri != null) {
prefix = importPrefixes.putIfAbsent(resolved.uri!, () {
String prefix = 'i${nextPrefix++}';
importsBuffer.writeln("import '${resolved.uri}' as $prefix;");
return prefix;
});
}
if (resolved.kind == IdentifierKind.instanceMember) {
// Qualify with `this.` if we don't have a receiver.
if (!lastDirectivePart.trimRight().endsWith('.')) {
writeDirectivePart('this.');
}
} else {
} else if (prefix != null) {
writeDirectivePart('${prefix}.');
}
if (resolved.kind == IdentifierKind.staticInstanceMember) {

View file

@ -21,7 +21,9 @@ import '../builder/library_builder.dart';
import '../builder/member_builder.dart';
import '../builder/named_type_builder.dart';
import '../builder/nullability_builder.dart';
import '../builder/type_alias_builder.dart';
import '../builder/type_builder.dart';
import '../builder/type_declaration_builder.dart';
import '../identifiers.dart';
import '../source/source_class_builder.dart';
import '../source/source_constructor_builder.dart';
@ -76,13 +78,12 @@ class MacroApplication {
class MacroApplicationDataForTesting {
Map<SourceLibraryBuilder, LibraryMacroApplicationData> libraryData = {};
Map<SourceClassBuilder, List<macro.MacroExecutionResult>> classTypesResults =
{};
Map<SourceClassBuilder, String> classTypesResults = {};
Map<SourceClassBuilder, List<macro.MacroExecutionResult>>
classDeclarationsResults = {};
Map<SourceClassBuilder, List<macro.MacroExecutionResult>>
classDefinitionsResults = {};
Map<MemberBuilder, List<macro.MacroExecutionResult>> memberTypesResults = {};
Map<MemberBuilder, String> memberTypesResults = {};
Map<MemberBuilder, List<macro.MacroExecutionResult>>
memberDeclarationsResults = {};
Map<MemberBuilder, List<macro.MacroExecutionResult>>
@ -198,7 +199,54 @@ class MacroApplications {
// TODO(johnniwinther): Throw when all members are supported.
throw new UnimplementedError(
'Unsupported member ${memberBuilder} (${memberBuilder.runtimeType})');
//return null;
}
}
macro.ResolvedIdentifier _resolveIdentifier(macro.Identifier identifier) {
if (identifier is _IdentifierImpl) {
MemberBuilder? memberBuilder = identifier.memberBuilder;
if (memberBuilder != null) {
Uri? uri;
String? staticScope;
macro.IdentifierKind kind;
if (memberBuilder.isStatic || memberBuilder.isConstructor) {
ClassBuilder classBuilder = memberBuilder.classBuilder!;
staticScope = classBuilder.name;
uri = classBuilder.library.importUri;
kind = macro.IdentifierKind.staticInstanceMember;
} else if (memberBuilder.isTopLevel) {
uri = memberBuilder.library.importUri;
kind = macro.IdentifierKind.topLevelMember;
} else {
kind = macro.IdentifierKind.instanceMember;
}
return new macro.ResolvedIdentifier(
kind: kind,
name: identifier.name,
staticScope: staticScope,
uri: uri);
} else {
TypeDeclarationBuilder typeDeclarationBuilder =
identifier.typeBuilder!.declaration!;
Uri? uri;
if (typeDeclarationBuilder is ClassBuilder) {
uri = typeDeclarationBuilder.library.importUri;
} else if (typeDeclarationBuilder is TypeAliasBuilder) {
uri = typeDeclarationBuilder.library.importUri;
}
return new macro.ResolvedIdentifier(
kind: macro.IdentifierKind.topLevelMember,
name: identifier.name,
staticScope: null,
uri: uri);
}
} else {
// TODO(johnniwinther): Use [_IdentifierImpl] for all identifiers.
return new macro.ResolvedIdentifier(
kind: macro.IdentifierKind.topLevelMember,
name: identifier.name,
staticScope: null,
uri: null);
}
}
@ -253,11 +301,13 @@ class MacroApplications {
results.add(result);
}
}
String result =
_macroExecutor.buildAugmentationLibrary(results, _resolveIdentifier);
if (retainDataForTesting) {
if (builder is SourceClassBuilder) {
dataForTesting?.classTypesResults[builder] = results;
dataForTesting?.classTypesResults[builder] = result;
} else {
dataForTesting?.memberTypesResults[builder as MemberBuilder] = results;
dataForTesting?.memberTypesResults[builder as MemberBuilder] = result;
}
}
return results;
@ -352,8 +402,11 @@ class MacroApplications {
macro.ClassDeclaration _createClassDeclaration(SourceClassBuilder builder) {
macro.ClassDeclaration declaration = new macro.ClassDeclarationImpl(
id: macro.RemoteInstance.uniqueId,
identifier: new macro.IdentifierImpl(
id: macro.RemoteInstance.uniqueId, name: builder.name),
identifier: new _IdentifierImpl.forTypeDeclarationBuilder(
typeDeclarationBuilder: builder,
libraryBuilder: builder.library,
id: macro.RemoteInstance.uniqueId,
name: builder.name),
// TODO(johnniwinther): Support typeParameters
typeParameters: [],
// TODO(johnniwinther): Support interfaces
@ -417,8 +470,10 @@ class MacroApplications {
_getClassDeclaration(builder.classBuilder as SourceClassBuilder);
return new macro.ConstructorDeclarationImpl(
id: macro.RemoteInstance.uniqueId,
identifier: new macro.IdentifierImpl(
id: macro.RemoteInstance.uniqueId, name: builder.name),
identifier: new _IdentifierImpl.forMemberBuilder(
memberBuilder: builder,
id: macro.RemoteInstance.uniqueId,
name: builder.name),
definingClass: definingClass.identifier as macro.IdentifierImpl,
isFactory: builder.isFactory,
isAbstract: builder.isAbstract,
@ -444,8 +499,10 @@ class MacroApplications {
return new macro.ConstructorDeclarationImpl(
id: macro.RemoteInstance.uniqueId,
identifier: new macro.IdentifierImpl(
id: macro.RemoteInstance.uniqueId, name: builder.name),
identifier: new _IdentifierImpl.forMemberBuilder(
memberBuilder: builder,
id: macro.RemoteInstance.uniqueId,
name: builder.name),
definingClass: definingClass.identifier as macro.IdentifierImpl,
isFactory: builder.isFactory,
isAbstract: builder.isAbstract,
@ -477,8 +534,10 @@ class MacroApplications {
// declarations?
return new macro.MethodDeclarationImpl(
id: macro.RemoteInstance.uniqueId,
identifier: new macro.IdentifierImpl(
id: macro.RemoteInstance.uniqueId, name: builder.name),
identifier: new _IdentifierImpl.forMemberBuilder(
memberBuilder: builder,
id: macro.RemoteInstance.uniqueId,
name: builder.name),
definingClass: definingClass.identifier as macro.IdentifierImpl,
isAbstract: builder.isAbstract,
isExternal: builder.isExternal,
@ -494,8 +553,10 @@ class MacroApplications {
} else {
return new macro.FunctionDeclarationImpl(
id: macro.RemoteInstance.uniqueId,
identifier: new macro.IdentifierImpl(
id: macro.RemoteInstance.uniqueId, name: builder.name),
identifier: new _IdentifierImpl.forMemberBuilder(
memberBuilder: builder,
id: macro.RemoteInstance.uniqueId,
name: builder.name),
isAbstract: builder.isAbstract,
isExternal: builder.isExternal,
isGetter: builder.isGetter,
@ -561,7 +622,7 @@ class MacroApplications {
if (name is String) {
return new macro.NamedTypeAnnotationImpl(
id: macro.RemoteInstance.uniqueId,
identifier: new _IdentifierImpl(
identifier: new _IdentifierImpl.forTypeBuilder(
typeBuilder: typeBuilder,
libraryBuilder: libraryBuilder,
id: macro.RemoteInstance.uniqueId,
@ -572,7 +633,7 @@ class MacroApplications {
assert(name.qualifier is String);
return new macro.NamedTypeAnnotationImpl(
id: macro.RemoteInstance.uniqueId,
identifier: new _IdentifierImpl(
identifier: new _IdentifierImpl.forTypeBuilder(
typeBuilder: typeBuilder,
libraryBuilder: libraryBuilder,
id: macro.RemoteInstance.uniqueId,
@ -611,13 +672,23 @@ class MacroApplications {
if (typeAnnotation is macro.NamedTypeAnnotationCode) {
_IdentifierImpl typeIdentifier = typeAnnotation.name as _IdentifierImpl;
TypeBuilder? originalTypeBuilder = typeIdentifier.typeBuilder;
if (originalTypeBuilder == null) {
throw new StateError('No type builder for $typeIdentifier');
}
if (originalTypeBuilder is! NamedTypeBuilder) {
throw new StateError(
'Type $typeIdentifier was not a named type as expected!');
TypeDeclarationBuilder? typeDeclarationBuilder =
typeIdentifier.typeDeclarationBuilder;
InstanceTypeVariableAccessState instanceTypeVariableAccessState =
InstanceTypeVariableAccessState.Unexpected;
if (typeDeclarationBuilder == null) {
TypeBuilder? originalTypeBuilder = typeIdentifier.typeBuilder;
if (originalTypeBuilder == null) {
throw new StateError('No type builder for $typeIdentifier');
}
if (originalTypeBuilder is! NamedTypeBuilder) {
throw new StateError(
'Type $typeIdentifier was not a named type as expected!');
}
typeDeclarationBuilder = originalTypeBuilder.declaration!;
instanceTypeVariableAccessState =
originalTypeBuilder.instanceTypeVariableAccess;
}
List<TypeBuilder> arguments = [
for (macro.TypeAnnotationCode argumentCode
@ -626,9 +697,8 @@ class MacroApplications {
];
return new NamedTypeBuilder.fromTypeDeclarationBuilder(
originalTypeBuilder.declaration!, nullabilityBuilder,
instanceTypeVariableAccess:
originalTypeBuilder.instanceTypeVariableAccess,
typeDeclarationBuilder, nullabilityBuilder,
instanceTypeVariableAccess: instanceTypeVariableAccessState,
arguments: arguments);
}
// TODO: Implement support for function types.
@ -654,15 +724,37 @@ class MacroApplications {
}
class _IdentifierImpl extends macro.IdentifierImpl {
final TypeDeclarationBuilder? typeDeclarationBuilder;
final MemberBuilder? memberBuilder;
final TypeBuilder? typeBuilder;
final LibraryBuilder libraryBuilder;
_IdentifierImpl({
required this.typeBuilder,
_IdentifierImpl.forTypeBuilder({
required TypeBuilder this.typeBuilder,
required this.libraryBuilder,
required int id,
required String name,
}) : super(id: id, name: name);
}) : typeDeclarationBuilder = null,
memberBuilder = null,
super(id: id, name: name);
_IdentifierImpl.forTypeDeclarationBuilder({
required TypeDeclarationBuilder this.typeDeclarationBuilder,
required this.libraryBuilder,
required int id,
required String name,
}) : typeBuilder = null,
memberBuilder = null,
super(id: id, name: name);
_IdentifierImpl.forMemberBuilder(
{required MemberBuilder this.memberBuilder,
required int id,
required String name})
: typeBuilder = null,
typeDeclarationBuilder = null,
libraryBuilder = memberBuilder.library,
super(id: id, name: name);
}
class _StaticTypeImpl extends macro.StaticType {

View file

@ -47,7 +47,9 @@ class FunctionTypesMacro1 implements FunctionTypesMacro {
FutureOr<void> buildTypesForFunction(FunctionDeclaration function,
TypeBuilder builder) {
var name = '${function.identifier.name}GeneratedClass';
builder.declareType(name, new DeclarationCode.fromString('class $name {}'));
builder.declareType(
name, new DeclarationCode.fromParts(['class $name<T extends ',
function.returnType.code, '> {}']));
}
}

View file

@ -5,54 +5,63 @@
import 'package:macro/macro.dart';
/*member: topLevelFunction1:
void topLevelFunction1GeneratedMethod_() {}
*/
@FunctionDeclarationsMacro1()
void topLevelFunction1() {}
/*member: topLevelFunction2:
void topLevelFunction2GeneratedMethod_e() {}
*/
@FunctionDeclarationsMacro1()
external void topLevelFunction2();
/*member: topLevelField1:
void topLevelField1GeneratedMethod_() {}
*/
@VariableDeclarationsMacro1()
int? topLevelField1;
/*member: topLevelField2:
void topLevelField2GeneratedMethod_e() {}
*/
@VariableDeclarationsMacro1()
external int? topLevelField2;
/*member: topLevelField3:
void topLevelField3GeneratedMethod_f() {}
*/
@VariableDeclarationsMacro1()
final int? topLevelField3 = null;
/*member: topLevelField4:
void topLevelField4GeneratedMethod_l() {}
*/
@VariableDeclarationsMacro1()
late int? topLevelField4;
/*member: topLevelGetter1:
void topLevelGetter1GeneratedMethod_g() {}
*/
@FunctionDeclarationsMacro1()
int? get topLevelGetter1 => null;
/*member: topLevelSetter1=:
void topLevelSetter1GeneratedMethod_s() {}
*/
@FunctionDeclarationsMacro1()
void set topLevelSetter1(int? value) {}
/*class: Class1:
void Class1GeneratedMethod_() {}
void Class1Introspection() {
@ -65,6 +74,7 @@ void Class1Introspection() {
@ClassDeclarationsMacro2()
class Class1 {
/*member: Class1.:
augment class Class1 {
void Class1_GeneratedMethod_() {}
@ -73,6 +83,7 @@ void Class1_GeneratedMethod_() {}
Class1();
/*member: Class1.redirect:
augment class Class1 {
void Class1_redirectGeneratedMethod_f() {}
@ -81,6 +92,7 @@ void Class1_redirectGeneratedMethod_f() {}
factory Class1.redirect() = Class1;
/*member: Class1.fact:
augment class Class1 {
void Class1_factGeneratedMethod_f() {}
@ -89,42 +101,49 @@ void Class1_factGeneratedMethod_f() {}
factory Class1.fact() => new Class1();
/*member: Class1.instanceMethod1:
void Class1_instanceMethod1GeneratedMethod_() {}
*/
@MethodDeclarationsMacro1()
void instanceMethod1() {}
/*member: Class1.instanceGetter1:
void Class1_instanceGetter1GeneratedMethod_g() {}
*/
@MethodDeclarationsMacro1()
int? get instanceGetter1 => null;
/*member: Class1.instanceSetter1=:
void Class1_instanceSetter1GeneratedMethod_s() {}
*/
@MethodDeclarationsMacro1()
void set instanceSetter1(int? value) {}
/*member: Class1.[]:
void Class1_[]GeneratedMethod_o() {}
*/
@MethodDeclarationsMacro1()
int operator [](int i) => i;
/*member: Class1.instanceField1:
void Class1_instanceField1GeneratedMethod_() {}
*/
@FieldDeclarationsMacro1()
int? instanceField1;
/*member: Class1.instanceField2:
void Class1_instanceField2GeneratedMethod_f() {}
*/
@FieldDeclarationsMacro1()
final int? instanceField2 = null;
/*member: Class1.instanceField3:
void Class1_instanceField3GeneratedMethod_fl() {}
*/
@FieldDeclarationsMacro1()
@ -132,6 +151,7 @@ void Class1_instanceField3GeneratedMethod_fl() {}
}
/*class: Class2:
void Class2GeneratedMethod_a() {}
void Class2Introspection() {
@ -144,12 +164,14 @@ void Class2Introspection() {
@ClassDeclarationsMacro2()
abstract class Class2 {
/*member: Class2.instanceMethod1:
void Class2_instanceMethod1GeneratedMethod_a() {}
*/
@MethodDeclarationsMacro1()
void instanceMethod1();
/*member: Class2.instanceField1:
void Class2_instanceField1GeneratedMethod_() {}
*/
@FieldDeclarationsMacro1()

View file

@ -5,6 +5,7 @@
import 'package:macro/macro.dart';
/*member: topLevelFunction1:
augment void topLevelFunction1(int a, ) {
return 42;
}*/
@ -12,6 +13,7 @@ augment void topLevelFunction1(int a, ) {
external void topLevelFunction1(int a);
/*member: topLevelFunction2:
augment void topLevelFunction2(int a, int b, ) {
return 42;
}*/
@ -19,6 +21,7 @@ augment void topLevelFunction2(int a, int b, ) {
external void topLevelFunction2(int a, int b);
/*member: topLevelFunction3:
augment void topLevelFunction3(int a, [int? b, ]) {
return 42;
}*/
@ -26,6 +29,7 @@ augment void topLevelFunction3(int a, [int? b, ]) {
external void topLevelFunction3(int a, [int? b]);
/*member: topLevelFunction4:
augment void topLevelFunction4(int a, {int? b, int? c, }) {
return 42;
}*/

View file

@ -19,6 +19,7 @@ class D1 {}
class D2 {}
/*member: topLevelFunction1:
void topLevelFunction1GeneratedMethod_es() {}
augment A topLevelFunction1(A a, ) {
@ -30,6 +31,7 @@ augment A topLevelFunction1(A a, ) {
external A topLevelFunction1(A a);
/*member: topLevelFunction2:
void topLevelFunction2GeneratedMethod_s() {}
augment B2 topLevelFunction2(B1 a, ) {
@ -41,6 +43,7 @@ augment B2 topLevelFunction2(B1 a, ) {
external B2 topLevelFunction2(B1 a);
/*member: topLevelFunction3:
void topLevelFunction3GeneratedMethod_() {}
augment C2 topLevelFunction3(C1 a, ) {
@ -52,6 +55,7 @@ augment C2 topLevelFunction3(C1 a, ) {
external C2 topLevelFunction3(C1 a);
/*member: topLevelFunction4:
void topLevelFunction4GeneratedMethod_() {}
augment D2 topLevelFunction4(D1 a, ) {

View file

@ -7,6 +7,7 @@ import 'dart:math' as math;
import 'package:macro/macro.dart';
/*member: topLevelFunction1:
augment void topLevelFunction1() {
return 42;
}*/
@ -14,6 +15,7 @@ augment void topLevelFunction1() {
external void topLevelFunction1();
/*member: topLevelFunction2:
augment dynamic topLevelFunction2() {
return 42;
}*/
@ -21,6 +23,7 @@ augment dynamic topLevelFunction2() {
external dynamic topLevelFunction2();
/*member: topLevelFunction3:
augment int topLevelFunction3() {
return 42;
}*/
@ -28,6 +31,7 @@ augment int topLevelFunction3() {
external int topLevelFunction3();
/*member: topLevelFunction4:
augment dynamic topLevelFunction4() {
return 42;
}*/
@ -35,6 +39,7 @@ augment dynamic topLevelFunction4() {
external topLevelFunction4();
/*member: topLevelFunction5:
augment math.Random topLevelFunction5() {
return 42;
}*/
@ -42,6 +47,7 @@ augment math.Random topLevelFunction5() {
external math.Random topLevelFunction5();
/*member: topLevelFunction6:
augment List<int> topLevelFunction6() {
return 42;
}*/
@ -49,6 +55,7 @@ augment List<int> topLevelFunction6() {
external List<int> topLevelFunction6();
/*member: topLevelFunction7:
augment Map<math.Random, List<int>> topLevelFunction7() {
return 42;
}*/
@ -56,6 +63,7 @@ augment Map<math.Random, List<int>> topLevelFunction7() {
external Map<math.Random, List<int>> topLevelFunction7();
/*member: topLevelFunction8:
augment Map<int?, String>? topLevelFunction8() {
return 42;
}*/

View file

@ -4,12 +4,33 @@
import 'package:macro/macro.dart';
@FunctionTypesMacro1()
/*member: topLevelFunction1:
class topLevelFunction1GeneratedClass {}*/
class topLevelFunction1GeneratedClass<T extends void> {}*/
@FunctionTypesMacro1()
void topLevelFunction1() {}
@FunctionTypesMacro1()
/*member: topLevelFunction2:
class topLevelFunction2GeneratedClass {}*/
void topLevelFunction2() {}
class topLevelFunction2GeneratedClass<T extends dynamic> {}*/
@FunctionTypesMacro1()
dynamic topLevelFunction2() {}
/*member: topLevelFunction3:
import 'dart:core' as i0;
class topLevelFunction3GeneratedClass<T extends i0.int> {}*/
@FunctionTypesMacro1()
int topLevelFunction3() => 0;
/*member: topLevelFunction4:
import 'package:macro/macro.dart' as i0;
class topLevelFunction4GeneratedClass<T extends i0.FunctionTypesMacro1?> {}*/
@FunctionTypesMacro1()
FunctionTypesMacro1? topLevelFunction4() => null;
/*member: topLevelFunction5:
class topLevelFunction5GeneratedClass<T extends dynamic> {}*/
@FunctionTypesMacro1()
topLevelFunction5() {}

View file

@ -104,12 +104,10 @@ class MacroDataComputer extends DataComputer<String> {
.dataForTesting!
.macroApplicationData;
StringBuffer sb = new StringBuffer();
for (MapEntry<SourceClassBuilder, List<MacroExecutionResult>> entry
for (MapEntry<SourceClassBuilder, String> entry
in macroApplicationData.classTypesResults.entries) {
if (entry.key.cls == cls) {
for (MacroExecutionResult result in entry.value) {
sb.write('\n${codeToString(result.augmentations.first)}');
}
sb.write('\n${entry.value.trim()}');
}
}
for (MapEntry<SourceClassBuilder, List<MacroExecutionResult>> entry
@ -148,12 +146,10 @@ class MacroDataComputer extends DataComputer<String> {
.dataForTesting!
.macroApplicationData;
StringBuffer sb = new StringBuffer();
for (MapEntry<MemberBuilder, List<MacroExecutionResult>> entry
for (MapEntry<MemberBuilder, String> entry
in macroApplicationData.memberTypesResults.entries) {
if (_isMember(entry.key, member)) {
for (MacroExecutionResult result in entry.value) {
sb.write('\n${codeToString(result.augmentations.first)}');
}
sb.write('\n${entry.value.trim()}');
}
}
for (MapEntry<MemberBuilder, List<MacroExecutionResult>> entry

View file

@ -283,8 +283,7 @@ class TestMacroExecutor implements MacroExecutor {
@override
String buildAugmentationLibrary(Iterable<MacroExecutionResult> macroResults,
ResolvedIdentifier Function(Identifier) resolveIdentifier) {
// TODO: implement buildAugmentationLibrary
throw UnimplementedError();
return '';
}
@override