| Index: lib/compiler/implementation/elements/elements.dart
|
| diff --git a/lib/compiler/implementation/elements/elements.dart b/lib/compiler/implementation/elements/elements.dart
|
| index 6736b57ef0d87732f74056afb838ea413bb7c20b..0c51eb972192aff1e0381c3e793d202e4091d69a 100644
|
| --- a/lib/compiler/implementation/elements/elements.dart
|
| +++ b/lib/compiler/implementation/elements/elements.dart
|
| @@ -102,6 +102,7 @@ class Element implements Hashable {
|
| final SourceString name;
|
| final ElementKind kind;
|
| final Element enclosingElement;
|
| + Script scriptOverride = null;
|
| Link<Node> metadata = const EmptyLink<Node>();
|
| Modifiers get modifiers() => null;
|
|
|
| @@ -175,6 +176,11 @@ class Element implements Hashable {
|
| // the same hash code. Replace this with a simple id in the element?
|
| int hashCode() => name.hashCode();
|
|
|
| + Script getScript() {
|
| + if (scriptOverride !== null) return scriptOverride;
|
| + return getCompilationUnit().script;
|
| + }
|
| +
|
| CompilationUnitElement getCompilationUnit() {
|
| Element element = this;
|
| while (element !== null && !element.isCompilationUnit()) {
|
| @@ -230,6 +236,10 @@ class Element implements Hashable {
|
| bool isNative() => _isNative;
|
|
|
| FunctionElement asFunctionElement() => null;
|
| +
|
| + Element cloneTo(Element enclosing, DiagnosticListener listener) {
|
| + listener.cancel("Unimplemented cloneTo", element: this);
|
| + }
|
| }
|
|
|
| class ContainerElement extends Element {
|
| @@ -396,23 +406,22 @@ class LibraryElement extends CompilationUnitElement {
|
| class PrefixElement extends Element {
|
| Map<SourceString, Element> imported;
|
| Token firstPosition;
|
| - final CompilationUnitElement patchSource;
|
|
|
| - PrefixElement(SourceString prefix, Element enclosing, this.firstPosition,
|
| - [this.patchSource])
|
| - : imported = new Map<SourceString, Element>(),
|
| - super(prefix, ElementKind.PREFIX, enclosing);
|
| -
|
| - CompilationUnitElement getCompilationUnit() {
|
| - if (patchSource !== null) return patchSource;
|
| - return super.getCompilationUnit();
|
| - }
|
| + PrefixElement(SourceString prefix, Element enclosing, this.firstPosition)
|
| + : imported = new Map<SourceString, Element>(),
|
| + super(prefix, ElementKind.PREFIX, enclosing);
|
|
|
| lookupLocalMember(SourceString memberName) => imported[memberName];
|
|
|
| Type computeType(Compiler compiler) => compiler.types.dynamicType;
|
|
|
| Token position() => firstPosition;
|
| +
|
| + PrefixElement cloneTo(Element enclosing, DiagnosticListener listener) {
|
| + PrefixElement result = new PrefixElement(name, enclosing, firstPosition);
|
| + result.scriptOverride = getScript();
|
| + return result;
|
| + }
|
| }
|
|
|
| class TypedefElement extends Element {
|
| @@ -428,6 +437,12 @@ class TypedefElement extends Element {
|
| this, compiler.resolveTypedef(this));
|
| return cachedType;
|
| }
|
| +
|
| + TypedefElement cloneTo(Element enclosing, DiagnosticListener listener) {
|
| + TypedefElement result = new TypedefElement(name, enclosing);
|
| + result.scriptOverride = getScript();
|
| + return result;
|
| + }
|
| }
|
|
|
| class VariableElement extends Element {
|
| @@ -474,6 +489,15 @@ class VariableElement extends Element {
|
| // Note: cachedNode.getBeginToken() will not be correct in all
|
| // cases, for example, for function typed parameters.
|
| Token position() => findMyName(variables.position());
|
| +
|
| + VariableElement cloneTo(Element enclosing, DiagnosticListener listener) {
|
| + VariableListElement clonedVariables =
|
| + variables.cloneTo(enclosing, listener);
|
| + VariableElement result = new VariableElement(
|
| + name, clonedVariables, kind, enclosing, cachedNode);
|
| + result.scriptOverride = getScript();
|
| + return result;
|
| + }
|
| }
|
|
|
| /**
|
| @@ -489,6 +513,16 @@ class FieldParameterElement extends VariableElement {
|
| Element enclosing,
|
| Node node)
|
| : super(name, variables, ElementKind.FIELD_PARAMETER, enclosing, node);
|
| +
|
| + FieldParameterElement cloneTo(Element enclosing,
|
| + DiagnosticListener listener) {
|
| + FieldParameterElement result =
|
| + new FieldParameterElement(name, fieldElement,
|
| + variables.cloneTo(enclosing, listener),
|
| + enclosing, cachedNode);
|
| + result.scriptOverride = getScript();
|
| + return result;
|
| + }
|
| }
|
|
|
| // This element represents a list of variable or field declaration.
|
| @@ -523,6 +557,17 @@ class VariableListElement extends Element {
|
| }
|
|
|
| Token position() => cachedNode.getBeginToken();
|
| +
|
| + VariableListElement cloneTo(Element enclosing, DiagnosticListener listener) {
|
| + VariableListElement result;
|
| + if (cachedNode !== null) {
|
| + result = new VariableListElement(cachedNode, kind, enclosing);
|
| + } else {
|
| + result = new VariableListElement(kind, modifiers, enclosing);
|
| + }
|
| + result.scriptOverride = getScript();
|
| + return result;
|
| + }
|
| }
|
|
|
| class ForeignElement extends Element {
|
| @@ -536,6 +581,12 @@ class ForeignElement extends Element {
|
| parseNode(DiagnosticListener listener) {
|
| throw "internal error: ForeignElement has no node";
|
| }
|
| +
|
| + ForeignElement cloneTo(Element enclosing, DiagnosticListener listener) {
|
| + ForeignElement result = new ForeignElement(name, kind, enclosing);
|
| + result.scriptOverride = getScript();
|
| + return result;
|
| + }
|
| }
|
|
|
| class AbstractFieldElement extends Element {
|
| @@ -580,6 +631,11 @@ class AbstractFieldElement extends Element {
|
| setter.modifiers.flags | Modifiers.FLAG_ABSTRACT);
|
| }
|
| }
|
| +
|
| + AbstractFieldElement cloneTo(Element enclosing, DiagnosticListener listener) {
|
| + listener.cancel("Cannot clone synthetic AbstractFieldElement",
|
| + element: this);
|
| + }
|
| }
|
|
|
| class FunctionSignature {
|
| @@ -662,9 +718,9 @@ class FunctionElement extends Element {
|
| defaultImplementation = this;
|
| }
|
|
|
| - CompilationUnitElement getCompilationUnit() {
|
| - if (patch !== null) return patch.getCompilationUnit();
|
| - return super.getCompilationUnit();
|
| + Script getScript() {
|
| + if (patch !== null) return patch.getScript();
|
| + return super.getScript();
|
| }
|
|
|
| bool get isPatched() => patch !== null;
|
| @@ -732,8 +788,18 @@ class FunctionElement extends Element {
|
| Token position() => cachedNode.getBeginToken();
|
|
|
| FunctionElement asFunctionElement() => this;
|
| +
|
| + FunctionElement cloneTo(Element enclosing, DiagnosticListener listener) {
|
| + FunctionElement result = new FunctionElement.tooMuchOverloading(
|
| + name, cachedNode, kind, modifiers, enclosing, functionSignature);
|
| + result.defaultImplementation = defaultImplementation;
|
| + result.type = type;
|
| + result.scriptOverride = getScript();
|
| + return result;
|
| + }
|
| }
|
|
|
| +
|
| class ConstructorBodyElement extends FunctionElement {
|
| FunctionElement constructor;
|
|
|
| @@ -760,6 +826,14 @@ class ConstructorBodyElement extends FunctionElement {
|
| }
|
|
|
| Token position() => constructor.position();
|
| +
|
| + ConstructorBodyElement cloneTo(Element enclosing,
|
| + DiagnosticListener listener) {
|
| + ConstructorBodyElement result =
|
| + new ConstructorBodyElement(constructor.cloneTo(enclosing, listener));
|
| + result.scriptOverride = getScript();
|
| + return result;
|
| + }
|
| }
|
|
|
| class SynthesizedConstructorElement extends FunctionElement {
|
| @@ -768,6 +842,11 @@ class SynthesizedConstructorElement extends FunctionElement {
|
| null, enclosing);
|
|
|
| Token position() => enclosingElement.position();
|
| +
|
| + SynthesizedConstructorElement cloneTo(Element enclosing,
|
| + DiagnosticListener listener) {
|
| + return new SynthesizedConstructorElement(enclosing);
|
| + }
|
| }
|
|
|
| class VoidElement extends Element {
|
| @@ -790,6 +869,7 @@ class ClassElement extends ContainerElement {
|
| Map<SourceString, Element> constructors;
|
| Link<Type> interfaces = const EmptyLink<Type>();
|
| LinkedHashMap<SourceString, TypeVariableElement> typeParameters;
|
| + SourceString nativeName;
|
| bool isResolved = false;
|
| bool isBeingResolved = false;
|
| // backendMembers are members that have been added by the backend to simplify
|
| @@ -797,7 +877,6 @@ class ClassElement extends ContainerElement {
|
| Link<Element> backendMembers = const EmptyLink<Element>();
|
|
|
| Link<Type> allSupertypes;
|
| - ClassElement patch = null;
|
|
|
| ClassElement(SourceString name, CompilationUnitElement enclosing, this.id)
|
| : localMembers = new Map<SourceString, Element>(),
|
| @@ -968,8 +1047,40 @@ class ClassElement extends ContainerElement {
|
|
|
| bool isInterface() => false;
|
| bool isNative() => nativeName != null;
|
| - SourceString nativeName;
|
| int hashCode() => id;
|
| +
|
| + void cloneMembersTo(Element target, DiagnosticListener listener) {
|
| + target.type = type;
|
| + target.supertype = supertype;
|
| + target.defaultClass = defaultClass;
|
| + target.interfaces = interfaces;
|
| + target.typeParameters =
|
| + new LinkedHashMap<SourceString, TypeVariableElement>();
|
| + typeParameters.forEach((SourceString name, TypeVariableElement type) {
|
| + target.typeParameters[name] = type.cloneTo(target, listener);
|
| + });
|
| + target.nativeName = nativeName;
|
| + target.isResolved = isResolved;
|
| + target.isBeingResolved = isBeingResolved;
|
| + target.allSupertypes = allSupertypes;
|
| + if (!backendMembers.isEmpty()) {
|
| + listener.cancel("Cloning backend-modified class.", element: this);
|
| + }
|
| +
|
| + Link<Element> elementList = this.members;
|
| + while (!elementList.isEmpty()) {
|
| + target.addMember(elementList.head.cloneTo(target, listener), listener);
|
| + elementList = elementList.tail;
|
| + }
|
| + }
|
| +
|
| + ClassElement cloneTo(Element enclosing, DiagnosticListener listener) {
|
| + // TODO(lrn): Is copying id acceptable?
|
| + ClassElement result = new ClassElement(name, enclosing, id);
|
| + cloneMembersTo(result, listener);
|
| + result.scriptOverride = getScript();
|
| + return result;
|
| + }
|
| }
|
|
|
| class Elements {
|
| @@ -1090,7 +1201,6 @@ class Elements {
|
| }
|
| }
|
|
|
| -
|
| class LabelElement extends Element {
|
| // We store the original label here so it can be returned by [parseNode].
|
| final Label label;
|
| @@ -1157,4 +1267,11 @@ class TypeVariableElement extends Element {
|
| Type computeType(compiler) => type;
|
| Node parseNode(compiler) => node;
|
| toString() => "${enclosingElement.toString()}.${name.slowToString()}";
|
| +
|
| + TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) {
|
| + TypeVariableElement result =
|
| + new TypeVariableElement(name, enclosing, node, type, bound);
|
| + result.scriptOverride = getScript();
|
| + return result;
|
| + }
|
| }
|
|
|