Index: pkg/compiler/lib/src/elements/modelx.dart |
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart |
index 65742316c66ff25e990a162e3b8f69e1f1b68f9f..7853f44b80482742d84014d7550bb2d549ea6593 100644 |
--- a/pkg/compiler/lib/src/elements/modelx.dart |
+++ b/pkg/compiler/lib/src/elements/modelx.dart |
@@ -59,7 +59,7 @@ abstract class ElementX extends Element with ElementCommon { |
final ElementKind kind; |
final Element enclosingElement; |
final int hashCode = ++elementHashCode; |
- Link<MetadataAnnotation> metadata = const Link<MetadataAnnotation>(); |
+ List<MetadataAnnotation> metadataInternal; |
ElementX(this.name, this.kind, this.enclosingElement) { |
assert(isErroneous || implementationLibrary != null); |
@@ -73,14 +73,27 @@ abstract class ElementX extends Element with ElementCommon { |
return null; |
} |
- void addMetadata(MetadataAnnotationX annotation) { |
- assert(annotation.annotatedElement == null); |
- annotation.annotatedElement = this; |
- addMetadataInternal(annotation); |
+ void set metadata(List<MetadataAnnotation> metadata) { |
+ assert(metadataInternal == null); |
+ for (MetadataAnnotationX annotation in metadata) { |
+ assert(annotation.annotatedElement == null); |
+ annotation.annotatedElement = this; |
+ } |
+ metadataInternal = metadata; |
} |
- void addMetadataInternal(MetadataAnnotation annotation) { |
- metadata = metadata.prepend(annotation); |
+ Iterable<MetadataAnnotation> get metadata { |
+ if (isPatch && metadataInternal != null) { |
+ if (origin.metadata.isEmpty) { |
+ return metadataInternal; |
+ } else { |
+ return <MetadataAnnotation>[] |
+ ..addAll(origin.metadata) |
+ ..addAll(metadataInternal); |
+ } |
+ } |
+ return metadataInternal != null |
+ ? metadataInternal : const <MetadataAnnotation>[]; |
} |
bool get isClosure => false; |
@@ -280,7 +293,7 @@ class ErroneousElementX extends ElementX implements ErroneousElement { |
} |
get asyncMarker => AsyncMarker.SYNC; |
- Link<MetadataAnnotation> get metadata => unsupported(); |
+ Iterable<MetadataAnnotation> get metadata => unsupported(); |
bool get hasNode => false; |
get node => unsupported(); |
get hasResolvedAst => false; |
@@ -678,6 +691,19 @@ class CompilationUnitElementX extends ElementX |
@override |
LibraryElementX get library => enclosingElement.declaration; |
+ void set metadata(List<MetadataAnnotation> metadata) { |
+ for (MetadataAnnotationX annotation in metadata) { |
+ assert(annotation.annotatedElement == null); |
+ annotation.annotatedElement = this; |
+ } |
+ // TODO(johnniwinther): Remove this work-around when import, export, |
+ // part, and part-of declarations are elements. |
+ if (metadataInternal == null) { |
+ metadataInternal = <MetadataAnnotation>[]; |
+ } |
+ metadataInternal.addAll(metadata); |
+ } |
+ |
void forEachLocalMember(f(Element element)) { |
localMembers.forEach(f); |
} |
@@ -892,11 +918,14 @@ class LibraryElementX |
} |
} |
- Link<MetadataAnnotation> get metadata { |
- return (libraryTag == null) ? super.metadata : libraryTag.metadata; |
+ Iterable<MetadataAnnotation> get metadata { |
+ if (libraryTag != null) { |
+ return libraryTag.metadata; |
+ } |
+ return const <MetadataAnnotation>[]; |
} |
- set metadata(value) { |
+ void set metadata(value) { |
// The metadata is stored on [libraryTag]. |
throw new SpannableAssertionFailure(this, 'Cannot set metadata on Library'); |
} |
@@ -1218,7 +1247,7 @@ class VariableList implements DeclarationSite { |
VariableDefinitions definitions; |
DartType type; |
final Modifiers modifiers; |
- Link<MetadataAnnotation> metadata = const Link<MetadataAnnotation>(); |
+ List<MetadataAnnotation> metadataInternal; |
VariableList(Modifiers this.modifiers); |
@@ -1228,6 +1257,25 @@ class VariableList implements DeclarationSite { |
assert(modifiers != null); |
} |
+ Iterable<MetadataAnnotation> get metadata { |
+ return metadataInternal != null |
+ ? metadataInternal : const <MetadataAnnotation>[]; |
+ } |
+ |
+ void set metadata(List<MetadataAnnotation> metadata) { |
+ if (metadata.isEmpty) { |
+ // For a multi declaration like: |
+ // |
+ // @foo @bar var a, b, c |
+ // |
+ // the metadata list is reported through the declaration of `a`, and `b` |
+ // and `c` report an empty list of metadata. |
+ return; |
+ } |
+ assert(metadataInternal == null); |
+ metadataInternal = metadata; |
+ } |
+ |
VariableDefinitions parseNode(Element element, DiagnosticListener listener) { |
return definitions; |
} |
@@ -1284,10 +1332,14 @@ abstract class VariableElementX extends ElementX |
// TODO(johnniwinther): Ensure that the [TreeElements] for this variable hold |
// the mappings for all its metadata. |
- Link<MetadataAnnotation> get metadata => variables.metadata; |
+ Iterable<MetadataAnnotation> get metadata => variables.metadata; |
- void addMetadataInternal(MetadataAnnotation annotation) { |
- variables.metadata = variables.metadata.prepend(annotation); |
+ void set metadata(List<MetadataAnnotation> metadata) { |
+ for (MetadataAnnotationX annotation in metadata) { |
+ assert(annotation.annotatedElement == null); |
+ annotation.annotatedElement = this; |
+ } |
+ variables.metadata = metadata; |
} |
// A variable cannot be patched therefore defines itself. |
@@ -2097,7 +2149,7 @@ class ConstructorBodyElementX extends BaseFunctionElementX |
FunctionExpression get node => constructor.node; |
- Link<MetadataAnnotation> get metadata => constructor.metadata; |
+ List<MetadataAnnotation> get metadata => constructor.metadata; |
bool get isInstanceMember => true; |