Skip to content

Commit

Permalink
Macro. Support for resolving OmittedTypeAnnotationCode.
Browse files Browse the repository at this point in the history
Change-Id: Ida96aae6e2c2e64c4deb00ad029de64b69a2dccc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/341386
Reviewed-by: Phil Quitslund <[email protected]>
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Konstantin Shcheglov <[email protected]>
  • Loading branch information
scheglov authored and Commit Queue committed Dec 12, 2023
1 parent f3be94a commit 706d105
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 28 deletions.
39 changes: 24 additions & 15 deletions pkg/analyzer/lib/src/summary2/macro_declarations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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}');
Expand All @@ -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');
Expand Down Expand Up @@ -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');
}
Expand Down
11 changes: 5 additions & 6 deletions pkg/analyzer/test/src/summary/macro/static_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand All @@ -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'),
);
}
}
55 changes: 48 additions & 7 deletions pkg/analyzer/test/src/summary/macro_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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, U>(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>(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, U>(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>(T a, T b) {}
''');

final generated = _getMacroGeneratedCode(library);
_assertIsExactlyValue(generated, true);
}

Future<void> _assertIsExactly({
Expand All @@ -6337,14 +6369,23 @@ class A {
''');

final generated = _getMacroGeneratedCode(library);
final expected = 'void isExactly_$isExactly() {}';
final expected = _isExactlyExpected(isExactly);
if (!generated.contains(expected)) {
fail(
'`$firstTypeCode` isExactly `$secondTypeCode`'
' expected to be `$isExactly`, but is not.\n',
);
}
}

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 {
Expand Down

0 comments on commit 706d105

Please sign in to comment.