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

Unified Diff: pkg/compiler/lib/src/elements/modelx.dart

Issue 1162603006: Element model cleanup + prepare for easier reimplementation. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 7 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
« no previous file with comments | « pkg/compiler/lib/src/elements/elements.dart ('k') | pkg/compiler/lib/src/enqueue.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 e5e4f394211e5055a11b006e6dd0fdff4ae6724b..964cb741f3ed68b3d23340319d8c771fd1c40845 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -4,6 +4,7 @@
library elements.modelx;
+import 'common.dart';
import 'elements.dart';
import '../constants/expressions.dart';
import '../constants/constructors.dart';
@@ -25,6 +26,7 @@ import '../dart2jslib.dart' show
MessageKind,
Script,
Selector,
+ SourceSpan,
TypeVariableType,
TypedefType,
invariant,
@@ -44,7 +46,7 @@ import 'visitor.dart' show ElementVisitor;
abstract class DeclarationSite {
}
-abstract class ElementX extends Element {
+abstract class ElementX extends Element with ElementCommon {
static int elementHashCode = 0;
final String name;
@@ -94,29 +96,6 @@ abstract class ElementX extends Element {
bool get isFinal => modifiers.isFinal;
bool get isStatic => modifiers.isStatic;
bool get isOperator => Elements.isOperatorName(name);
- bool get impliesType => (kind.category & ElementCategory.IMPLIES_TYPE) != 0;
-
- bool get isPatched => false;
-
- bool get isPatch => false;
-
- bool get isImplementation => true;
-
- bool get isDeclaration => true;
-
- bool get isInjected => !isPatch && implementationLibrary.isPatch;
-
- Element get implementation => this;
-
- Element get declaration => this;
-
- Element get patch {
- throw new UnsupportedError('patch is not supported on $this');
- }
-
- Element get origin {
- throw new UnsupportedError('origin is not supported on $this');
- }
bool get isSynthesized => false;
@@ -140,6 +119,13 @@ abstract class ElementX extends Element {
Token get position => null;
+ SourceSpan get sourcePosition {
+ if (position == null) return null;
+ Uri uri = compilationUnit.script.readableUri;
+ return new SourceSpan(
+ uri, position.charOffset, position.charOffset + position.charCount);
+ }
+
Token findMyName(Token token) {
return findNameToken(token, isConstructor, name, enclosingElement.name);
}
@@ -251,7 +237,6 @@ abstract class ElementX extends Element {
FunctionElement asFunctionElement() => null;
bool get isAbstract => modifiers.isAbstract;
- bool isForeign(Backend backend) => backend.isForeign(this);
void diagnose(Element context, DiagnosticListener listener) {}
@@ -857,7 +842,10 @@ class ImportScope {
}
class LibraryElementX
- extends ElementX with AnalyzableElementX, PatchMixin<LibraryElementX>
+ extends ElementX
+ with LibraryElementCommon,
+ AnalyzableElementX,
+ PatchMixin<LibraryElementX>
implements LibraryElement {
final Uri canonicalUri;
@@ -903,8 +891,6 @@ class LibraryElementX
}
}
- bool get isDartCore => canonicalUri == Compiler.DART_CORE;
-
Link<MetadataAnnotation> get metadata {
return (libraryTag == null) ? super.metadata : libraryTag.metadata;
}
@@ -1048,6 +1034,11 @@ class LibraryElementX
Link<Import> getImportsFor(Element element) => importers.getImports(element);
+ @override
+ void forEachImport(f(Element element)) {
+ importScope.importScope.values.forEach(f);
+ }
+
void forEachLocalMember(f(Element element)) {
if (isPatch) {
// Patch libraries traverse both origin and injected members.
@@ -1104,13 +1095,6 @@ class LibraryElementX
Scope buildScope() => new LibraryScope(this);
- bool get isPlatformLibrary => canonicalUri.scheme == 'dart';
-
- bool get isPackageLibrary => canonicalUri.scheme == 'package';
-
- bool get isInternalLibrary =>
- isPlatformLibrary && canonicalUri.path.startsWith('_');
-
String toString() {
if (origin != null) {
return 'patch library(${canonicalUri})';
@@ -1273,12 +1257,21 @@ abstract class ConstantVariableMixin implements VariableElement {
ConstantExpression _constant;
ConstantExpression get constant {
+ if (isPatch) {
+ ConstantVariableMixin originVariable = origin;
+ return originVariable.constant;
+ }
assert(invariant(this, _constant != null,
message: "Constant has not been computed for $this."));
return _constant;
}
void set constant(ConstantExpression value) {
+ if (isPatch) {
+ ConstantVariableMixin originVariable = origin;
+ originVariable.constant = value;
+ return null;
+ }
assert(invariant(this, _constant == null || _constant == value,
message: "Constant has already been computed for $this."));
_constant = value;
@@ -1591,7 +1584,8 @@ class FormalElementX extends ElementX
/// to ensure that default values on parameters are computed once (on the
/// origin parameter) but can be found through both the origin and the patch.
abstract class ParameterElementX extends FormalElementX
- with PatchMixin<ParameterElement>, ConstantVariableMixin
+ with PatchMixin<ParameterElement>,
+ ConstantVariableMixin
implements ParameterElement {
final Expression initializer;
final bool isOptional;
@@ -1617,6 +1611,15 @@ abstract class ParameterElementX extends FormalElementX
}
bool get isLocal => true;
+
+ String toString() {
+ if (isPatched) {
+ return 'origin ${super.toString()}';
+ } else if (isPatch) {
+ return 'patch ${super.toString()}';
+ }
+ return super.toString();
+ }
}
class LocalParameterElementX extends ParameterElementX
@@ -1747,7 +1750,8 @@ class AbstractFieldElementX extends ElementX implements AbstractFieldElement {
// TODO(johnniwinther): [FunctionSignature] should be merged with
// [FunctionType].
// TODO(karlklose): all these lists should have element type [FormalElement].
-class FunctionSignatureX implements FunctionSignature {
+class FunctionSignatureX extends FunctionSignatureCommon
+ implements FunctionSignature {
final List<Element> requiredParameters;
final List<Element> optionalParameters;
final int requiredParameterCount;
@@ -1766,64 +1770,6 @@ class FunctionSignatureX implements FunctionSignature {
this.type})
: optionalParameters = optionalParameters,
hasOptionalParameters = !optionalParameters.isEmpty;
-
- void forEachRequiredParameter(void function(Element parameter)) {
- requiredParameters.forEach(function);
- }
-
- void forEachOptionalParameter(void function(Element parameter)) {
- optionalParameters.forEach(function);
- }
-
- Element get firstOptionalParameter => optionalParameters.first;
-
- void forEachParameter(void function(Element parameter)) {
- forEachRequiredParameter(function);
- forEachOptionalParameter(function);
- }
-
- void orderedForEachParameter(void function(Element parameter)) {
- forEachRequiredParameter(function);
- orderedOptionalParameters.forEach(function);
- }
-
- int get parameterCount => requiredParameterCount + optionalParameterCount;
-
- /**
- * Check whether a function with this signature can be used instead of a
- * function with signature [signature] without causing a `noSuchMethod`
- * exception/call.
- */
- bool isCompatibleWith(FunctionSignature signature) {
- if (optionalParametersAreNamed) {
- if (!signature.optionalParametersAreNamed) {
- return requiredParameterCount == signature.parameterCount;
- }
- // If both signatures have named parameters, then they must have
- // the same number of required parameters, and the names in
- // [signature] must all be in [:this:].
- if (requiredParameterCount != signature.requiredParameterCount) {
- return false;
- }
- Set<String> names = optionalParameters.map(
- (Element element) => element.name).toSet();
- for (Element namedParameter in signature.optionalParameters) {
- if (!names.contains(namedParameter.name)) {
- return false;
- }
- }
- } else {
- if (signature.optionalParametersAreNamed) return false;
- // There must be at least as many arguments as in the other signature, but
- // this signature must not have more required parameters. Having more
- // optional parameters is not a problem, they simply are never provided
- // by call sites of a call to a method with the other signature.
- int otherTotalCount = signature.parameterCount;
- return requiredParameterCount <= otherTotalCount
- && parameterCount >= otherTotalCount;
- }
- return true;
- }
}
abstract class BaseFunctionElementX
@@ -2110,8 +2056,6 @@ class DeferredLoaderGetterElementX extends GetterElementX
bool get isClassMember => false;
- bool isForeign(Backend backend) => true;
-
bool get isSynthesized => true;
bool get isDeferredLoaderGetter => true;
@@ -2332,11 +2276,14 @@ abstract class TypeDeclarationElementX<T extends GenericType>
}
bool get isResolved => resolutionState == STATE_DONE;
+
+ int get resolutionState;
}
abstract class BaseClassElementX extends ElementX
with AstElementMixin,
AnalyzableElementX,
+ ClassElementCommon,
TypeDeclarationElementX<InterfaceType>,
PatchMixin<ClassElement>,
ClassMemberMixin
@@ -2357,10 +2304,6 @@ abstract class BaseClassElementX extends ElementX
OrderedTypeSet allSupertypesAndSelf;
- Link<DartType> get allSupertypes => allSupertypesAndSelf.supertypes;
-
- int get hierarchyDepth => allSupertypesAndSelf.maxDepth;
-
BaseClassElementX(String name,
Element enclosing,
this.id,
@@ -2396,17 +2339,13 @@ abstract class BaseClassElementX extends ElementX
}
}
+ @override
InterfaceType createType(List<DartType> typeArguments) {
return new InterfaceType(this, typeArguments);
}
List<DartType> computeTypeParameters(Compiler compiler);
- InterfaceType asInstanceOf(ClassElement cls) {
- if (cls == this) return thisType;
- return allSupertypesAndSelf.asInstanceOf(cls);
- }
-
bool get isObject {
assert(invariant(this, isResolved,
message: "isObject has not been computed for $this."));
@@ -2431,15 +2370,6 @@ abstract class BaseClassElementX extends ElementX
backendMembers = backendMembers.reverse();
}
- /**
- * Lookup local members in the class. This will ignore constructors.
- */
- Element lookupLocalMember(String memberName) {
- var result = localLookup(memberName);
- if (result != null && result.isConstructor) return null;
- return result;
- }
-
/// Lookup a synthetic element created by the backend.
Element lookupBackendMember(String memberName) {
for (Element element in backendMembers) {
@@ -2449,132 +2379,6 @@ abstract class BaseClassElementX extends ElementX
}
return null;
}
- /**
- * Lookup super members for the class. This will ignore constructors.
- */
- Element lookupSuperMember(String memberName) {
- return lookupSuperMemberInLibrary(memberName, library);
- }
-
- /**
- * Lookup super members for the class that is accessible in [library].
- * This will ignore constructors.
- */
- Element lookupSuperMemberInLibrary(String memberName,
- LibraryElement library) {
- bool isPrivate = isPrivateName(memberName);
- for (ClassElement s = superclass; s != null; s = s.superclass) {
- // Private members from a different library are not visible.
- if (isPrivate && !identical(library, s.library)) continue;
- Element e = s.lookupLocalMember(memberName);
- if (e == null) continue;
- // Static members are not inherited.
- if (e.isStatic) continue;
- return e;
- }
- return null;
- }
-
- /**
- * Find the first member in the class chain with the given [memberName].
- *
- * This method is NOT to be used for resolving
- * unqualified sends because it does not implement the scoping
- * rules, where library scope comes before superclass scope.
- *
- * When called on the implementation element both members declared in the
- * origin and the patch class are returned.
- */
- Element lookupByName(Name memberName) {
- return internalLookupByName(memberName, isSuperLookup: false);
- }
-
- Element lookupSuperByName(Name memberName) {
- return internalLookupByName(memberName, isSuperLookup: true);
- }
-
- Element internalLookupByName(Name memberName, {bool isSuperLookup}) {
- String name = memberName.text;
- bool isPrivate = memberName.isPrivate;
- LibraryElement library = memberName.library;
- for (ClassElement current = isSuperLookup ? superclass : this;
- current != null;
- current = current.superclass) {
- Element member = current.lookupLocalMember(name);
- if (member == null && current.isPatched) {
- // Doing lookups on selectors is done after resolution, so it
- // is safe to look in the patch class.
- member = current.patch.lookupLocalMember(name);
- }
- if (member == null) continue;
- // Private members from a different library are not visible.
- if (isPrivate && !identical(library, member.library)) continue;
- // Static members are not inherited.
- if (member.isStatic && !identical(this, current)) continue;
- // If we find an abstract field we have to make sure that it has
- // the getter or setter part we're actually looking
- // for. Otherwise, we continue up the superclass chain.
- if (member.isAbstractField) {
- AbstractFieldElement field = member;
- FunctionElement getter = field.getter;
- FunctionElement setter = field.setter;
- if (memberName.isSetter) {
- // Abstract members can be defined in a super class.
- if (setter != null && !setter.isAbstract) {
- return setter;
- }
- } else {
- if (getter != null && !getter.isAbstract) {
- return getter;
- }
- }
- // Abstract members can be defined in a super class.
- } else if (!member.isAbstract) {
- return member;
- }
- }
- return null;
- }
-
- /**
- * Find the first member in the class chain with the given
- * [memberName]. This method is NOT to be used for resolving
- * unqualified sends because it does not implement the scoping
- * rules, where library scope comes before superclass scope.
- */
- Element lookupMember(String memberName) {
- Element localMember = lookupLocalMember(memberName);
- return localMember == null ? lookupSuperMember(memberName) : localMember;
- }
-
- /**
- * Returns true if the [fieldMember] shadows another field. The given
- * [fieldMember] must be a member of this class, i.e. if there is a field of
- * the same name in the superclass chain.
- *
- * This method also works if the [fieldMember] is private.
- */
- bool hasFieldShadowedBy(Element fieldMember) {
- assert(fieldMember.isField);
- String fieldName = fieldMember.name;
- bool isPrivate = isPrivateName(fieldName);
- LibraryElement memberLibrary = fieldMember.library;
- ClassElement lookupClass = this.superclass;
- while (lookupClass != null) {
- Element foundMember = lookupClass.lookupLocalMember(fieldName);
- if (foundMember != null) {
- if (foundMember.isField) {
- if (!isPrivate || memberLibrary == foundMember.library) {
- // Private fields can only be shadowed by a field declared in the
- // same library.
- return true;
- }
- }
- }
- lookupClass = lookupClass.superclass;
- }
- return false;
- }
ConstructorElement lookupDefaultConstructor() {
ConstructorElement constructor = lookupConstructor("");
@@ -2589,21 +2393,6 @@ abstract class BaseClassElementX extends ElementX
return null;
}
- ConstructorElement lookupConstructor(String name) {
- Element result = localLookup(name);
- return result != null && result.isConstructor ? result : null;
- }
-
- Link<Element> get constructors {
- // TODO(ajohnsen): See if we can avoid this method at some point.
- Link<Element> result = const Link<Element>();
- // TODO(johnniwinther): Should we include injected constructors?
- forEachMember((_, Element member) {
- if (member.isConstructor) result = result.prepend(member);
- });
- return result;
- }
-
/**
* Returns the super class, if any.
*
@@ -2614,78 +2403,6 @@ abstract class BaseClassElementX extends ElementX
return supertype == null ? null : supertype.element;
}
- /**
- * Runs through all members of this class.
- *
- * The enclosing class is passed to the callback. This is useful when
- * [includeSuperAndInjectedMembers] is [:true:].
- *
- * When called on an implementation element both the members in the origin
- * and patch class are included.
- */
- // TODO(johnniwinther): Clean up lookup to get rid of the include predicates.
- void forEachMember(void f(ClassElement enclosingClass, Element member),
- {includeBackendMembers: false,
- includeSuperAndInjectedMembers: false}) {
- bool includeInjectedMembers = includeSuperAndInjectedMembers || isPatch;
- ClassElement classElement = declaration;
- do {
- // Iterate through the members in textual order, which requires
- // to reverse the data structure [localMembers] we created.
- // Textual order may be important for certain operations, for
- // example when emitting the initializers of fields.
- classElement.forEachLocalMember((e) => f(classElement, e));
- if (includeBackendMembers) {
- classElement.forEachBackendMember((e) => f(classElement, e));
- }
- if (includeInjectedMembers) {
- if (classElement.patch != null) {
- classElement.patch.forEachLocalMember((e) {
- if (!e.isPatch) f(classElement, e);
- });
- }
- }
- classElement = includeSuperAndInjectedMembers
- ? classElement.superclass
- : null;
- } while (classElement != null);
- }
-
- /**
- * Runs through all instance-field members of this class.
- *
- * The enclosing class is passed to the callback. This is useful when
- * [includeSuperAndInjectedMembers] is [:true:].
- *
- * When called on the implementation element both the fields declared in the
- * origin and in the patch are included.
- */
- void forEachInstanceField(void f(ClassElement enclosingClass,
- FieldElement field),
- {bool includeSuperAndInjectedMembers: false}) {
- // Filters so that [f] is only invoked with instance fields.
- void fieldFilter(ClassElement enclosingClass, Element member) {
- if (member.isInstanceMember && member.kind == ElementKind.FIELD) {
- f(enclosingClass, member);
- }
- }
-
- forEachMember(fieldFilter,
- includeSuperAndInjectedMembers: includeSuperAndInjectedMembers);
- }
-
- /// Similar to [forEachInstanceField] but visits static fields.
- void forEachStaticField(void f(ClassElement enclosingClass, Element field)) {
- // Filters so that [f] is only invoked with static fields.
- void fieldFilter(ClassElement enclosingClass, Element member) {
- if (!member.isInstanceMember && member.kind == ElementKind.FIELD) {
- f(enclosingClass, member);
- }
- }
-
- forEachMember(fieldFilter);
- }
-
void forEachBackendMember(void f(Element member)) {
backendMembers.forEach(f);
}
@@ -2694,33 +2411,6 @@ abstract class BaseClassElementX extends ElementX
return asInstanceOf(compiler.functionClass) != null || callType != null;
}
- bool implementsInterface(ClassElement intrface) {
- for (DartType implementedInterfaceType in allSupertypes) {
- ClassElement implementedInterface = implementedInterfaceType.element;
- if (identical(implementedInterface, intrface)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns true if [this] is a subclass of [cls].
- *
- * This method is not to be used for checking type hierarchy and
- * assignments, because it does not take parameterized types into
- * account.
- */
- bool isSubclassOf(ClassElement cls) {
- // Use [declaration] for both [this] and [cls], because
- // declaration classes hold the superclass hierarchy.
- cls = cls.declaration;
- for (ClassElement s = declaration; s != null; s = s.superclass) {
- if (identical(s, cls)) return true;
- }
- return false;
- }
-
bool get isNative => nativeTagInfo != null;
void setNative(String name) {
@@ -2734,12 +2424,6 @@ abstract class BaseClassElementX extends ElementX
nativeTagInfo = name;
}
- FunctionType get callType {
- MemberSignature member =
- lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME));
- return member != null && member.isMethod ? member.type : null;
- }
-
// TODO(johnniwinther): Remove these when issue 18630 is fixed.
ClassElement get patch => super.patch;
ClassElement get origin => super.origin;
« no previous file with comments | « pkg/compiler/lib/src/elements/elements.dart ('k') | pkg/compiler/lib/src/enqueue.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698