diff --git a/pkg/analyzer/lib/src/summary2/macro_declarations.dart b/pkg/analyzer/lib/src/summary2/macro_declarations.dart index d7eba154407f..f4ee6396b58a 100644 --- a/pkg/analyzer/lib/src/summary2/macro_declarations.dart +++ b/pkg/analyzer/lib/src/summary2/macro_declarations.dart @@ -108,19 +108,8 @@ class DeclarationBuilder { macro.TypeAnnotation inferOmittedType( macro.OmittedTypeAnnotation omittedType, ) { - switch (omittedType) { - case _OmittedTypeAnnotationDynamic(): - final type = DynamicTypeImpl.instance; - return fromElement._dartType(type); - case _OmittedTypeAnnotationMethodReturnType(): - final type = omittedType.element.returnType; - return fromElement._dartType(type); - case _OmittedTypeAnnotationVariable(): - final type = omittedType.element.type; - return fromElement._dartType(type); - default: - throw UnimplementedError('${omittedType.runtimeType}'); - } + final type = resolveType(omittedType.code); + return fromElement._dartType(type); } macro.ResolvedIdentifier resolveIdentifier(macro.Identifier identifier) { @@ -173,6 +162,13 @@ class DeclarationBuilder { uri: element.source.uri, staticScope: null, ); + case TypeParameterElement(): + return macro.ResolvedIdentifier( + kind: macro.IdentifierKind.local, + name: element.name, + uri: null, + staticScope: null, + ); default: // TODO(scheglov): other elements throw UnimplementedError('${element.runtimeType}'); @@ -190,8 +186,7 @@ class DeclarationBuilder { case macro.NamedTypeAnnotationCode(): return _resolveTypeCodeNamed(typeCode); case macro.OmittedTypeAnnotationCode(): - // TODO(scheglov): implement - throw UnimplementedError('(${typeCode.runtimeType}) $typeCode'); + return _resolveTypeCodeOmitted(typeCode); case macro.RawTypeAnnotationCode(): // TODO(scheglov): implement throw UnimplementedError('(${typeCode.runtimeType}) $typeCode'); @@ -369,6 +364,20 @@ class DeclarationBuilder { } } + DartType _resolveTypeCodeOmitted(macro.OmittedTypeAnnotationCode typeCode) { + final omittedType = typeCode.typeAnnotation; + switch (omittedType) { + case _OmittedTypeAnnotationDynamic(): + return DynamicTypeImpl.instance; + case _OmittedTypeAnnotationMethodReturnType(): + return omittedType.element.returnType; + case _OmittedTypeAnnotationVariable(): + return omittedType.element.type; + default: + throw UnimplementedError('${omittedType.runtimeType}'); + } + } + static macro.ExpressionCode _expressionCode(ast.Expression node) { return macro.ExpressionCode.fromString('$node'); } diff --git a/pkg/analyzer/test/src/summary/macro/static_type.dart b/pkg/analyzer/test/src/summary/macro/static_type.dart index 88eab28ea669..8701539a5f1c 100644 --- a/pkg/analyzer/test/src/summary/macro/static_type.dart +++ b/pkg/analyzer/test/src/summary/macro/static_type.dart @@ -4,12 +4,12 @@ import 'package:_fe_analyzer_shared/src/macros/api.dart'; -/*macro*/ class IsExactly implements MethodDeclarationsMacro { +/*macro*/ class IsExactly implements FunctionDefinitionMacro { const IsExactly(); @override - buildDeclarationsForMethod(method, builder) async { - final positional = method.positionalParameters.toList(); + buildDefinitionForFunction(declaration, builder) async { + final positional = declaration.positionalParameters.toList(); final first = positional[0]; final second = positional[1]; @@ -20,9 +20,8 @@ import 'package:_fe_analyzer_shared/src/macros/api.dart'; final secondStaticType = await builder.resolve(secondTypeCode); final result = await firstStaticType.isExactly(secondStaticType); - final code = ' void isExactly_$result() {}'; - builder.declareInType( - DeclarationCode.fromString(code), + builder.augment( + FunctionBodyCode.fromString('=> $result; // isExactly'), ); } } diff --git a/pkg/analyzer/test/src/summary/macro_test.dart b/pkg/analyzer/test/src/summary/macro_test.dart index 5906d596656c..705a38539f6f 100644 --- a/pkg/analyzer/test/src/summary/macro_test.dart +++ b/pkg/analyzer/test/src/summary/macro_test.dart @@ -6291,32 +6291,64 @@ mixin A {} ); } - test_isExactly_typeParameter_notSame() async { + test_isExactly_omittedType_notSame() async { final library = await buildLibrary(''' import 'static_type.dart'; class A { + void foo(int a, double b) {} +} + +class B extends A { @IsExactly() - void foo(T a, U b) {} + void foo(a, b) {} } '''); final generated = _getMacroGeneratedCode(library); - expect(generated, contains('void isExactly_false() {}')); + _assertIsExactlyValue(generated, false); } - test_isExactly_typeParameter_same() async { + test_isExactly_omittedType_same() async { final library = await buildLibrary(''' import 'static_type.dart'; class A { + void foo(int a, int b) {} +} + +class B extends A { @IsExactly() - void foo(T a, T b) {} + void foo(a, b) {} } '''); final generated = _getMacroGeneratedCode(library); - expect(generated, contains('void isExactly_true() {}')); + _assertIsExactlyValue(generated, true); + } + + test_isExactly_typeParameter_notSame() async { + final library = await buildLibrary(''' +import 'static_type.dart'; + +@IsExactly() +void foo(T a, U b) {} +'''); + + final generated = _getMacroGeneratedCode(library); + _assertIsExactlyValue(generated, false); + } + + test_isExactly_typeParameter_same() async { + final library = await buildLibrary(''' +import 'static_type.dart'; + +@IsExactly() +void foo(T a, T b) {} +'''); + + final generated = _getMacroGeneratedCode(library); + _assertIsExactlyValue(generated, true); } Future _assertIsExactly({ @@ -6337,7 +6369,7 @@ class A { '''); final generated = _getMacroGeneratedCode(library); - final expected = 'void isExactly_$isExactly() {}'; + final expected = _isExactlyExpected(isExactly); if (!generated.contains(expected)) { fail( '`$firstTypeCode` isExactly `$secondTypeCode`' @@ -6345,6 +6377,15 @@ class A { ); } } + + void _assertIsExactlyValue(String generated, bool isExactly) { + final expected = _isExactlyExpected(isExactly); + expect(generated, contains(expected)); + } + + String _isExactlyExpected(bool isExactly) { + return '=> $isExactly; // isExactly'; + } } abstract class MacroTypesTest extends MacroElementsBaseTest {