add declarationKind for extensions and libraries, support augmenting extensions and add test

Change-Id: I510976cac641800e664e92e7db786962d539ec9c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/325021
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Jake Macdonald <jakemac@google.com>
Auto-Submit: Jake Macdonald <jakemac@google.com>
This commit is contained in:
Jake Macdonald 2023-09-11 15:56:23 +00:00 committed by Commit Queue
parent 0ac6f0846a
commit 0ffd54738a
5 changed files with 150 additions and 44 deletions

View file

@ -188,8 +188,10 @@ enum DeclarationKind {
constructor,
enumType,
enumValue,
extension,
field,
function,
library,
method,
mixinType,
variable,

View file

@ -135,14 +135,14 @@ mixin AugmentationLibraryBuilder on MacroExecutor {
};
for (Identifier type in mergedAugmentedTypes) {
final TypeDeclaration typeDeclaration = resolveDeclaration(type);
String declarationKind = typeDeclaration is ClassDeclaration
? 'class'
: typeDeclaration is EnumDeclaration
? 'enum'
: typeDeclaration is MixinDeclaration
? 'mixin'
: throw new UnsupportedError(
'Unsupported augmentation type $typeDeclaration');
String declarationKind = switch (typeDeclaration) {
ClassDeclaration() => 'class',
EnumDeclaration() => 'enum',
ExtensionDeclaration() => 'extension',
MixinDeclaration() => 'mixin',
_ => throw new UnsupportedError(
'Unsupported augmentation type $typeDeclaration'),
};
final List<String> keywords = [
if (typeDeclaration is ClassDeclaration) ...[
if (typeDeclaration.hasAbstract) 'abstract',
@ -181,6 +181,7 @@ mixin AugmentationLibraryBuilder on MacroExecutor {
' '
]));
}
writeDirectiveStringPart('{\n');
if (typeDeclaration is EnumDeclaration) {
for (DeclarationCode entryAugmentation

View file

@ -33,171 +33,165 @@ class MacroInstanceIdentifierImpl implements MacroInstanceIdentifier {
if (macro is ClassTypesMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.declarations:
if (macro is ClassDeclarationsMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.definitions:
if (macro is ClassDefinitionMacro) {
interfaces |= interfaceMask;
}
break;
}
break;
case DeclarationKind.constructor:
switch (phase) {
case Phase.types:
if (macro is ConstructorTypesMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.declarations:
if (macro is ConstructorDeclarationsMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.definitions:
if (macro is ConstructorDefinitionMacro) {
interfaces |= interfaceMask;
}
break;
}
break;
case DeclarationKind.extension:
switch (phase) {
case Phase.types:
if (macro is ExtensionTypesMacro) {
interfaces |= interfaceMask;
}
case Phase.declarations:
if (macro is ExtensionDeclarationsMacro) {
interfaces |= interfaceMask;
}
case Phase.definitions:
if (macro is ExtensionDefinitionMacro) {
interfaces |= interfaceMask;
}
}
case DeclarationKind.field:
switch (phase) {
case Phase.types:
if (macro is FieldTypesMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.declarations:
if (macro is FieldDeclarationsMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.definitions:
if (macro is FieldDefinitionMacro) {
interfaces |= interfaceMask;
}
break;
}
break;
case DeclarationKind.function:
switch (phase) {
case Phase.types:
if (macro is FunctionTypesMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.declarations:
if (macro is FunctionDeclarationsMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.definitions:
if (macro is FunctionDefinitionMacro) {
interfaces |= interfaceMask;
}
break;
}
break;
case DeclarationKind.library:
switch (phase) {
case Phase.types:
if (macro is LibraryTypesMacro) {
interfaces |= interfaceMask;
}
case Phase.declarations:
if (macro is LibraryDeclarationsMacro) {
interfaces |= interfaceMask;
}
case Phase.definitions:
if (macro is LibraryDefinitionMacro) {
interfaces |= interfaceMask;
}
}
case DeclarationKind.method:
switch (phase) {
case Phase.types:
if (macro is MethodTypesMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.declarations:
if (macro is MethodDeclarationsMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.definitions:
if (macro is MethodDefinitionMacro) {
interfaces |= interfaceMask;
}
break;
}
break;
case DeclarationKind.enumType:
switch (phase) {
case Phase.types:
if (macro is EnumTypesMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.declarations:
if (macro is EnumDeclarationsMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.definitions:
if (macro is EnumDefinitionMacro) {
interfaces |= interfaceMask;
}
break;
}
break;
case DeclarationKind.enumValue:
switch (phase) {
case Phase.types:
if (macro is EnumValueTypesMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.declarations:
if (macro is EnumValueDeclarationsMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.definitions:
if (macro is EnumValueDefinitionMacro) {
interfaces |= interfaceMask;
}
break;
}
break;
case DeclarationKind.mixinType:
switch (phase) {
case Phase.types:
if (macro is MixinTypesMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.declarations:
if (macro is MixinDeclarationsMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.definitions:
if (macro is MixinDefinitionMacro) {
interfaces |= interfaceMask;
}
break;
}
break;
case DeclarationKind.variable:
switch (phase) {
case Phase.types:
if (macro is VariableTypesMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.declarations:
if (macro is VariableDeclarationsMacro) {
interfaces |= interfaceMask;
}
break;
case Phase.definitions:
if (macro is VariableDefinitionMacro) {
interfaces |= interfaceMask;
}
break;
}
break;
}
}
}

View file

@ -443,6 +443,83 @@ void main() {
'''));
});
test('can augment extensions', () async {
final myExtension = ExtensionDeclarationImpl(
id: RemoteInstance.uniqueId,
identifier: TestIdentifier(
id: RemoteInstance.uniqueId,
name: 'MyExtension',
kind: IdentifierKind.topLevelMember,
uri: Uri.parse('a.dart'),
staticScope: null),
library: Fixtures.library,
metadata: [],
typeParameters: [],
onType: Fixtures.myClassType,
);
final myGetter = MethodDeclarationImpl(
id: RemoteInstance.uniqueId,
identifier: TestIdentifier(
id: RemoteInstance.uniqueId,
name: 'x',
kind: IdentifierKind.instanceMember,
uri: Uri.parse('a.dart'),
staticScope: null),
library: Fixtures.library,
metadata: [],
definingType: myExtension.identifier,
hasExternal: false,
isStatic: false,
returnType: NamedTypeAnnotationImpl(
id: RemoteInstance.uniqueId,
isNullable: false,
identifier: intIdentifier,
typeArguments: []),
hasAbstract: false,
hasBody: true,
isGetter: true,
isOperator: false,
isSetter: false,
namedParameters: [],
positionalParameters: [],
typeParameters: []);
var results = [
MacroExecutionResultImpl(
diagnostics: [],
enumValueAugmentations: {},
typeAugmentations: {
myExtension.identifier: [
DeclarationCode.fromParts([
intIdentifier,
' get ',
myGetter.identifier.name,
' => 1;\n'
]),
],
},
interfaceAugmentations: {},
mixinAugmentations: {},
newTypeNames: [],
libraryAugmentations: []),
];
var library = _TestExecutor().buildAugmentationLibrary(
results,
(Identifier i) => i == myExtension.identifier
? myExtension
: throw UnimplementedError(),
(Identifier i) => (i as TestIdentifier).resolved,
(OmittedTypeAnnotation i) =>
(i as TestOmittedTypeAnnotation).inferredType);
expect(library, equalsIgnoringWhitespace('''
import 'dart:core' as prefix0;
augment extension MyExtension {
prefix0.int get x => 1;
}
'''));
});
test('copies keywords for classes', () async {
for (final hasKeywords in [true, false]) {
final clazz = ClassDeclarationImpl(

View file

@ -99,6 +99,14 @@ final Map<DeclarationKind, Map<Phase, MacroInstanceIdentifierImpl>>
Phase.definitions: MacroInstanceIdentifierImpl(
FakeEnumValueDefinitionMacro(), RemoteInstance.uniqueId),
},
DeclarationKind.extension: {
Phase.types: MacroInstanceIdentifierImpl(
FakeExtensionTypesMacro(), RemoteInstance.uniqueId),
Phase.declarations: MacroInstanceIdentifierImpl(
FakeExtensionDeclarationsMacro(), RemoteInstance.uniqueId),
Phase.definitions: MacroInstanceIdentifierImpl(
FakeExtensionDefinitionMacro(), RemoteInstance.uniqueId),
},
DeclarationKind.field: {
Phase.types: MacroInstanceIdentifierImpl(
FakeFieldTypesMacro(), RemoteInstance.uniqueId),
@ -115,6 +123,14 @@ final Map<DeclarationKind, Map<Phase, MacroInstanceIdentifierImpl>>
Phase.definitions: MacroInstanceIdentifierImpl(
FakeFunctionDefinitionMacro(), RemoteInstance.uniqueId),
},
DeclarationKind.library: {
Phase.types: MacroInstanceIdentifierImpl(
FakeLibraryTypesMacro(), RemoteInstance.uniqueId),
Phase.declarations: MacroInstanceIdentifierImpl(
FakeLibraryDeclarationsMacro(), RemoteInstance.uniqueId),
Phase.definitions: MacroInstanceIdentifierImpl(
FakeLibraryDefinitionMacro(), RemoteInstance.uniqueId),
},
DeclarationKind.method: {
Phase.types: MacroInstanceIdentifierImpl(
FakeMethodTypesMacro(), RemoteInstance.uniqueId),
@ -206,3 +222,19 @@ class FakeEnumValueDeclarationsMacro extends Fake
class FakeEnumValueDefinitionMacro extends Fake
implements EnumValueDefinitionMacro {}
class FakeExtensionTypesMacro extends Fake implements ExtensionTypesMacro {}
class FakeExtensionDeclarationsMacro extends Fake
implements ExtensionDeclarationsMacro {}
class FakeExtensionDefinitionMacro extends Fake
implements ExtensionDefinitionMacro {}
class FakeLibraryTypesMacro extends Fake implements LibraryTypesMacro {}
class FakeLibraryDeclarationsMacro extends Fake
implements LibraryDeclarationsMacro {}
class FakeLibraryDefinitionMacro extends Fake
implements LibraryDefinitionMacro {}