mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 21:50:11 +00:00
Macro. Introspect top-level functions.
Change-Id: Ida8e7768efb3072870fd32bb48d0905d235ad343 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/340740 Reviewed-by: Phil Quitslund <pquitslund@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
c31dfad2df
commit
8371eb481f
|
@ -173,8 +173,14 @@ class LibraryMacroApplier {
|
|||
members: declaration.members,
|
||||
);
|
||||
case ast.FunctionDeclarationImpl():
|
||||
// TODO(scheglov): implement it
|
||||
break;
|
||||
await _addAnnotations(
|
||||
libraryElement: libraryElement,
|
||||
container: container,
|
||||
declarationsPhaseElement: null,
|
||||
targetNode: declaration,
|
||||
targetDeclarationKind: macro.DeclarationKind.function,
|
||||
annotations: declaration.metadata,
|
||||
);
|
||||
case ast.FunctionTypeAliasImpl():
|
||||
// TODO(scheglov): implement it
|
||||
break;
|
||||
|
|
|
@ -90,6 +90,8 @@ class DeclarationBuilder {
|
|||
return fromNode.extensionDeclaration(node);
|
||||
case ast.ExtensionTypeDeclarationImpl():
|
||||
return fromNode.extensionTypeDeclaration(node);
|
||||
case ast.FunctionDeclarationImpl():
|
||||
return fromNode.functionDeclaration(node);
|
||||
case ast.MethodDeclarationImpl():
|
||||
return fromNode.methodDeclaration(node);
|
||||
case ast.MixinDeclarationImpl():
|
||||
|
@ -638,6 +640,30 @@ class DeclarationBuilderFromNode {
|
|||
);
|
||||
}
|
||||
|
||||
macro.FunctionDeclarationImpl functionDeclaration(
|
||||
ast.FunctionDeclarationImpl node,
|
||||
) {
|
||||
final element = node.declaredElement!;
|
||||
final function = node.functionExpression;
|
||||
|
||||
return FunctionDeclarationImpl._(
|
||||
id: macro.RemoteInstance.uniqueId,
|
||||
element: element,
|
||||
identifier: _declaredIdentifier(node.name, element),
|
||||
library: library(element),
|
||||
metadata: _buildMetadata(element),
|
||||
hasBody: function.body is! ast.EmptyFunctionBody,
|
||||
hasExternal: node.externalKeyword != null,
|
||||
isGetter: node.isGetter,
|
||||
isOperator: false,
|
||||
isSetter: node.isSetter,
|
||||
namedParameters: _namedFormalParameters(function.parameters),
|
||||
positionalParameters: _positionalFormalParameters(function.parameters),
|
||||
returnType: _typeAnnotation(node.returnType),
|
||||
typeParameters: _typeParameters(function.typeParameters),
|
||||
);
|
||||
}
|
||||
|
||||
macro.LibraryImpl library(Element element) {
|
||||
final library = element.library!;
|
||||
|
||||
|
@ -1038,6 +1064,29 @@ class FieldDeclarationImpl extends macro.FieldDeclarationImpl
|
|||
});
|
||||
}
|
||||
|
||||
class FunctionDeclarationImpl extends macro.FunctionDeclarationImpl
|
||||
implements HasElement {
|
||||
@override
|
||||
final ExecutableElementImpl element;
|
||||
|
||||
FunctionDeclarationImpl._({
|
||||
required super.id,
|
||||
required super.identifier,
|
||||
required super.library,
|
||||
required super.metadata,
|
||||
required super.hasBody,
|
||||
required super.hasExternal,
|
||||
required super.isGetter,
|
||||
required super.isOperator,
|
||||
required super.isSetter,
|
||||
required super.namedParameters,
|
||||
required super.positionalParameters,
|
||||
required super.returnType,
|
||||
required super.typeParameters,
|
||||
required this.element,
|
||||
});
|
||||
}
|
||||
|
||||
/// A macro declaration that has an [Element].
|
||||
abstract interface class HasElement {
|
||||
ElementImpl get element;
|
||||
|
|
|
@ -551,6 +551,7 @@ class _ElementWriter {
|
|||
_writeTypeParameterElements(e.typeParameters);
|
||||
_writeParameterElements(e.parameters);
|
||||
_writeReturnType(e.returnType);
|
||||
_writeMacroDiagnostics(e);
|
||||
_writeAugmentationTarget(e);
|
||||
_writeAugmentation(e);
|
||||
});
|
||||
|
|
|
@ -13,6 +13,7 @@ import 'package:_fe_analyzer_shared/src/macros/api.dart';
|
|||
ExtensionDeclarationsMacro,
|
||||
ExtensionTypeDeclarationsMacro,
|
||||
FieldDeclarationsMacro,
|
||||
FunctionDeclarationsMacro,
|
||||
MethodDeclarationsMacro,
|
||||
MixinDeclarationsMacro {
|
||||
final Set<Object?> withDetailsFor;
|
||||
|
@ -72,6 +73,13 @@ import 'package:_fe_analyzer_shared/src/macros/api.dart';
|
|||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> buildDeclarationsForFunction(declaration, builder) async {
|
||||
await _write(builder, declaration, (printer) async {
|
||||
await printer.writeFunctionDeclaration(declaration);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> buildDeclarationsForMethod(declaration, builder) async {
|
||||
await _write(builder, declaration, (printer) async {
|
||||
|
@ -330,6 +338,25 @@ class _Printer {
|
|||
});
|
||||
}
|
||||
|
||||
Future<void> writeFunctionDeclaration(FunctionDeclaration e) async {
|
||||
sink.writelnWithIndent(e.identifier.name);
|
||||
|
||||
await sink.withIndent(() async {
|
||||
await sink.writeFlags({
|
||||
'hasBody': e.hasBody,
|
||||
'hasExternal': e.hasExternal,
|
||||
'isGetter': e.isGetter,
|
||||
'isOperator': e.isOperator,
|
||||
'isSetter': e.isSetter,
|
||||
});
|
||||
await _writeMetadata(e);
|
||||
await _writeNamedFormalParameters(e.namedParameters);
|
||||
await _writePositionalFormalParameters(e.positionalParameters);
|
||||
await _writeNamedTypeAnnotation('returnType', e.returnType);
|
||||
await _writeTypeParameters(e.typeParameters);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> writeMethodDeclaration(MethodDeclaration e) async {
|
||||
_assertEnclosingClass(e);
|
||||
sink.writelnWithIndent(e.identifier.name);
|
||||
|
|
|
@ -5751,6 +5751,112 @@ class A
|
|||
''');
|
||||
}
|
||||
|
||||
test_unit_function() async {
|
||||
await _assertIntrospectText(r'''
|
||||
@Introspect()
|
||||
void foo() {}
|
||||
''', r'''
|
||||
foo
|
||||
flags: hasBody
|
||||
returnType: void
|
||||
''');
|
||||
}
|
||||
|
||||
test_unit_function_flags_hasExternal() async {
|
||||
await _assertIntrospectText(r'''
|
||||
@Introspect()
|
||||
external void foo();
|
||||
''', r'''
|
||||
foo
|
||||
flags: hasExternal
|
||||
returnType: void
|
||||
''');
|
||||
}
|
||||
|
||||
test_unit_function_metadata() async {
|
||||
await _assertIntrospectText(r'''
|
||||
@Introspect(withMetadata: true)
|
||||
@a1
|
||||
@a2
|
||||
void foo() {}
|
||||
|
||||
const a1 = 0;
|
||||
const a2 = 0;
|
||||
''', r'''
|
||||
foo
|
||||
flags: hasBody
|
||||
metadata
|
||||
ConstructorMetadataAnnotation
|
||||
type: Introspect
|
||||
IdentifierMetadataAnnotation
|
||||
identifier: a1
|
||||
IdentifierMetadataAnnotation
|
||||
identifier: a2
|
||||
returnType: void
|
||||
''');
|
||||
}
|
||||
|
||||
test_unit_function_namedParameters() async {
|
||||
await _assertIntrospectText(r'''
|
||||
@Introspect()
|
||||
void foo({required int a, String? b}) {}
|
||||
''', r'''
|
||||
foo
|
||||
flags: hasBody
|
||||
namedParameters
|
||||
a
|
||||
flags: isNamed isRequired
|
||||
type: int
|
||||
b
|
||||
flags: isNamed
|
||||
type: String?
|
||||
returnType: void
|
||||
''');
|
||||
}
|
||||
|
||||
test_unit_function_positionalParameters() async {
|
||||
await _assertIntrospectText(r'''
|
||||
@Introspect()
|
||||
void foo(int a, [String? b]) {}
|
||||
''', r'''
|
||||
foo
|
||||
flags: hasBody
|
||||
positionalParameters
|
||||
a
|
||||
flags: isRequired
|
||||
type: int
|
||||
b
|
||||
type: String?
|
||||
returnType: void
|
||||
''');
|
||||
}
|
||||
|
||||
test_unit_getter() async {
|
||||
await _assertIntrospectText(r'''
|
||||
@Introspect()
|
||||
int get foo => 0;
|
||||
''', r'''
|
||||
foo
|
||||
flags: hasBody isGetter
|
||||
returnType: int
|
||||
''');
|
||||
}
|
||||
|
||||
test_unit_setter() async {
|
||||
await _assertIntrospectText(r'''
|
||||
@Introspect()
|
||||
set foo(int value) {}
|
||||
''', r'''
|
||||
foo
|
||||
flags: hasBody isSetter
|
||||
positionalParameters
|
||||
value
|
||||
flags: isRequired
|
||||
type: int
|
||||
returnType: OmittedType
|
||||
''');
|
||||
}
|
||||
|
||||
/// Assert that the textual dump of the introspection information produced
|
||||
/// by `IntrospectTypesPhaseMacro` in [code], is the [expected].
|
||||
Future<void> _assertIntrospectText(
|
||||
|
|
Loading…
Reference in a new issue