Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Unified Diff: pkg/front_end/lib/src/fasta/kernel/body_builder.dart

Issue 2938793002: Implement metadata on classes and additional semantic checks. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/front_end/lib/src/fasta/kernel/body_builder.dart
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index e3c0d1638c9ddc8a0e8f153a29bc86a4c94eaea1..4524983da5e11658cfc1e957aa54cce7b3db4fe4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -78,7 +78,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
@override
final KernelLibraryBuilder library;
- final MemberBuilder member;
+ final ModifierBuilder member;
final KernelClassBuilder classBuilder;
@@ -349,20 +349,41 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
debugEvent("Metadata");
var arguments = pop();
+ pushQualifiedReference(beginToken.next, periodBeforeName);
if (arguments != null) {
- endConstructorReference(beginToken, periodBeforeName, endToken);
push(arguments);
endNewExpression(beginToken);
push(popForValue());
} else {
- var postfix = popIfNotNull(periodBeforeName);
- if (postfix != null) {
- addCompileTimeError(offsetForToken(beginToken), "Not implemented.");
+ String name = pop();
+ pop(); // Type arguments (ignored, already reported by parser).
+ var expression = pop();
+ if (expression is Identifier) {
+ Identifier identifier = expression;
+ expression = new UnresolvedAccessor(
+ this, new Name(identifier.name, library.library), identifier.token);
+ }
+ if (name?.isNotEmpty ?? false) {
+ Token period = periodBeforeName ?? beginToken.next;
+ FastaAccessor accessor = expression;
+ expression = accessor.buildPropertyAccess(
+ new IncompletePropertyAccessor(
+ this, period.next, new Name(name, library.library)),
+ period.next.offset,
+ false);
+ }
+
+ bool savedConstantExpressionRequired = pop();
+ if (expression is! StaticAccessor) {
+ push(wrapInCompileTimeError(
+ toValue(expression),
+ "This can't be used as metadata; metadata should be a reference to "
+ "a compile-time constant variable, or "
+ "a call to a constant constructor."));
+ } else {
+ push(toValue(expression));
}
- pop(); // Type arguments.
- var e = popForValue(); // Expression.
- constantExpressionRequired = pop();
- push(e);
+ constantExpressionRequired = savedConstantExpressionRequired;
}
}
@@ -2023,25 +2044,43 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
void endConstructorReference(
Token start, Token periodBeforeName, Token endToken) {
debugEvent("ConstructorReference");
- // A constructor reference can contain up to three identifiers:
- //
- // a) type <type-arguments>?
- // b) type <type-arguments>? . name
- // c) prefix . type <type-arguments>?
- // d) prefix . type <type-arguments>? . name
- //
- // This isn't a legal constructor reference:
- //
- // type . name <type-arguments>
- //
- // But the parser can't tell this from type c) above.
- //
- // This method pops 2 (or 3 if periodBeforeName != null) values from the
- // stack and pushes 3 values: a type, a list of type arguments, and a name.
- //
- // If the constructor reference can be resolved, type is either a
- // ClassBuilder, or a ThisPropertyAccessor. Otherwise, it's an error that
- // should be handled later.
+ pushQualifiedReference(start, periodBeforeName);
+ }
+
+ /// A qualfied reference is something that matches one of:
+ ///
+ /// identifier
+ /// identifier typeArguments? '.' identifier
+ /// identifier '.' identifier typeArguments? '.' identifier
+ ///
+ /// That is, one to three identifiers separated by periods and optionally one
+ /// list of type arguments.
+ ///
+ /// A qualified reference can be used to represent both a reference to
+ /// compile-time constant variable (metadata) or a constructor reference
+ /// (used by metadata, new/const expression, and redirecting factories).
+ ///
+ /// Note that the parser will report errors if metadata includes type
+ /// arguments, but will other preserve them for error recovery.
+ ///
+ /// A constructor reference can contain up to three identifiers:
+ ///
+ /// a) type typeArguments?
+ /// b) type typeArguments? '.' name
+ /// c) prefix '.' type typeArguments?
+ /// d) prefix '.' type typeArguments? '.' name
+ ///
+ /// This isn't a legal constructor reference:
+ ///
+ /// type '.' name typeArguments?
+ ///
+ /// But the parser can't tell this from type c) above.
+ ///
+ /// This method pops 2 (or 3 if `periodBeforeName != null`) values from the
+ /// stack and pushes 3 values: an accessor (the type in a constructor
+ /// reference, or an expression in metadata), a list of type arguments, and a
+ /// name.
+ void pushQualifiedReference(Token start, Token periodBeforeName) {
Identifier suffix = popIfNotNull(periodBeforeName);
Identifier identifier;
List<DartType> typeArguments = pop();
« no previous file with comments | « pkg/front_end/lib/src/fasta/builder/modifier_builder.dart ('k') | pkg/front_end/lib/src/fasta/source/diet_listener.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698