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

Unified Diff: frog/leg/elements/elements.dart

Issue 9873021: Move frog/leg to lib/compiler/implementation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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 | « frog/leg/diagnostic_listener.dart ('k') | frog/leg/emitter.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: frog/leg/elements/elements.dart
===================================================================
--- frog/leg/elements/elements.dart (revision 5925)
+++ frog/leg/elements/elements.dart (working copy)
@@ -1,969 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#library('elements');
-
-#import('../tree/tree.dart');
-#import('../scanner/scannerlib.dart');
-#import('../leg.dart'); // TODO(karlklose): we only need type.
-#import('../util/util.dart');
-
-class ElementCategory {
- /**
- * Represents things that we don't expect to find when looking in a
- * scope.
- */
- static final int NONE = 0;
-
- /** Field, parameter, or variable. */
- static final int VARIABLE = 1;
-
- /** Function, method, or foreign function. */
- static final int FUNCTION = 2;
-
- static final int CLASS = 4;
-
- static final int PREFIX = 8;
-
- /** Constructor or factory. */
- static final int FACTORY = 16;
-
- static final int ALIAS = 32;
-
- static final int SUPER = 64;
-
- /** Type variable */
- static final int TYPE_VARIABLE = 128;
-
- static final int IMPLIES_TYPE = CLASS | ALIAS | TYPE_VARIABLE;
-
- static final int IS_EXTENDABLE = CLASS | ALIAS;
-}
-
-class ElementKind {
- final String id;
- final int category;
-
- const ElementKind(String this.id, this.category);
-
- static final ElementKind VARIABLE =
- const ElementKind('variable', ElementCategory.VARIABLE);
- static final ElementKind PARAMETER =
- const ElementKind('parameter', ElementCategory.VARIABLE);
- // Parameters in constructors that directly initialize fields. For example:
- // [:A(this.field):].
- static final ElementKind FIELD_PARAMETER =
- const ElementKind('field_parameter', ElementCategory.VARIABLE);
- static final ElementKind FUNCTION =
- const ElementKind('function', ElementCategory.FUNCTION);
- static final ElementKind CLASS =
- const ElementKind('class', ElementCategory.CLASS);
- static final ElementKind FOREIGN =
- const ElementKind('foreign', ElementCategory.FUNCTION);
- static final ElementKind GENERATIVE_CONSTRUCTOR =
- const ElementKind('generative_constructor', ElementCategory.FACTORY);
- static final ElementKind FIELD =
- const ElementKind('field', ElementCategory.VARIABLE);
- static final ElementKind VARIABLE_LIST =
- const ElementKind('variable_list', ElementCategory.NONE);
- static final ElementKind FIELD_LIST =
- const ElementKind('field_list', ElementCategory.NONE);
- static final ElementKind GENERATIVE_CONSTRUCTOR_BODY =
- const ElementKind('generative_constructor_body', ElementCategory.NONE);
- static final ElementKind COMPILATION_UNIT =
- const ElementKind('compilation_unit', ElementCategory.NONE);
- static final ElementKind GETTER =
- const ElementKind('getter', ElementCategory.NONE);
- static final ElementKind SETTER =
- const ElementKind('setter', ElementCategory.NONE);
- static final ElementKind TYPE_VARIABLE =
- const ElementKind('type_variable', ElementCategory.TYPE_VARIABLE);
- static final ElementKind ABSTRACT_FIELD =
- const ElementKind('abstract_field', ElementCategory.VARIABLE);
- static final ElementKind LIBRARY =
- const ElementKind('library', ElementCategory.NONE);
- static final ElementKind PREFIX =
- const ElementKind('prefix', ElementCategory.PREFIX);
- static final ElementKind TYPEDEF =
- const ElementKind('typedef', ElementCategory.ALIAS);
-
- static final ElementKind STATEMENT =
- const ElementKind('statement', ElementCategory.NONE);
- static final ElementKind LABEL =
- const ElementKind('label', ElementCategory.NONE);
-
- toString() => id;
-}
-
-class Element implements Hashable {
- final SourceString name;
- final ElementKind kind;
- final Element enclosingElement;
- Modifiers get modifiers() => null;
-
- Node parseNode(DiagnosticListener listener) {
- listener.cancel("Internal Error: $this.parseNode", token: position());
- }
-
- Type computeType(Compiler compiler) {
- compiler.internalError("$this.computeType.", token: position());
- }
-
- bool isFunction() => kind === ElementKind.FUNCTION;
- bool isMember() =>
- enclosingElement !== null && enclosingElement.kind === ElementKind.CLASS;
- bool isInstanceMember() => false;
- bool isFactoryConstructor() => modifiers !== null && modifiers.isFactory();
- bool isGenerativeConstructor() => kind === ElementKind.GENERATIVE_CONSTRUCTOR;
- bool isCompilationUnit() {
- return kind === ElementKind.COMPILATION_UNIT ||
- kind === ElementKind.LIBRARY;
- }
- bool isClass() => kind === ElementKind.CLASS;
- bool isVariable() => kind === ElementKind.VARIABLE;
- bool isParameter() => kind === ElementKind.PARAMETER;
- bool isStatement() => kind === ElementKind.STATEMENT;
- bool isTypedef() => kind === ElementKind.TYPEDEF;
- bool isTypeVariable() => kind === ElementKind.TYPE_VARIABLE;
- bool isGetter() => kind === ElementKind.GETTER;
- bool isSetter() => kind === ElementKind.SETTER;
- bool impliesType() => (kind.category & ElementCategory.IMPLIES_TYPE) != 0;
- bool isExtendable() => (kind.category & ElementCategory.IS_EXTENDABLE) != 0;
-
- bool isAssignable() {
- if (modifiers != null && modifiers.isFinal()) return false;
- if (isFunction() || isGenerativeConstructor()) return false;
- return true;
- }
-
- Token position() => null;
-
- Token findMyName(Token token) {
- for (Token t = token; t !== EOF_TOKEN; t = t.next) {
- if (t.value == name) return t;
- }
- return token;
- }
-
- Element(this.name, this.kind, this.enclosingElement) {
- assert(getLibrary() !== null);
- }
-
- // TODO(kasperl): This is a very bad hash code for the element and
- // there's no reason why two elements with the same name should have
- // the same hash code. Replace this with a simple id in the element?
- int hashCode() => name.hashCode();
-
- CompilationUnitElement getCompilationUnit() {
- Element element = this;
- while (element !== null && !element.isCompilationUnit()) {
- element = element.enclosingElement;
- }
- return element;
- }
-
- LibraryElement getLibrary() {
- Element element = this;
- while (element.kind !== ElementKind.LIBRARY) {
- element = element.enclosingElement;
- }
- return element;
- }
-
- ClassElement getEnclosingClass() {
- for (Element e = this; e !== null; e = e.enclosingElement) {
- if (e.kind === ElementKind.CLASS) return e;
- }
- return null;
- }
-
- toString() => '$kind(${name.slowToString()})';
-
- bool _isNative = false;
- void setNative() => _isNative = true;
- bool isNative() => _isNative;
-}
-
-class ContainerElement extends Element {
- ContainerElement(name, kind, enclosingElement) :
- super(name, kind, enclosingElement);
-
- abstract void addMember(Element element, DiagnosticListener listener);
-
- void addGetterOrSetter(Element element,
- Element existing,
- DiagnosticListener listener) {
- void reportError(Element other) {
- listener.cancel('duplicate definition of ${element.name.slowToString()}',
- element: element);
- listener.cancel('existing definition', element: other);
- }
-
- if (existing != null) {
- if (existing.kind !== ElementKind.ABSTRACT_FIELD) {
- reportError(existing);
- } else {
- AbstractFieldElement field = existing;
- if (element.kind == ElementKind.GETTER) {
- if (field.getter != null && field.getter != element) {
- reportError(field.getter);
- }
- field.getter = element;
- } else {
- if (field.setter != null && field.setter != element) {
- reportError(field.setter);
- }
- field.setter = element;
- }
- }
- } else {
- AbstractFieldElement field = new AbstractFieldElement(element.name, this);
- addMember(field, listener);
- if (element.kind == ElementKind.GETTER) {
- field.getter = element;
- } else {
- field.setter = element;
- }
- }
- }
-}
-
-class CompilationUnitElement extends ContainerElement {
- final Script script;
- Link<Element> topLevelElements = const EmptyLink<Element>();
-
- CompilationUnitElement(Script script, Element enclosing)
- : this.script = script,
- super(new SourceString(script.name),
- ElementKind.COMPILATION_UNIT,
- enclosing);
-
- CompilationUnitElement.library(Script script)
- : this.script = script,
- super(new SourceString(script.name), ElementKind.LIBRARY, null);
-
- void addMember(Element element, DiagnosticListener listener) {
- LibraryElement library = enclosingElement;
- library.addMember(element, listener);
- topLevelElements = topLevelElements.prepend(element);
- }
-
- void define(Element element, DiagnosticListener listener) {
- LibraryElement library = enclosingElement;
- library.define(element, listener);
- }
-
- void addTag(ScriptTag tag, DiagnosticListener listener) {
- listener.cancel("script tags not allowed here", node: tag);
- }
-}
-
-class LibraryElement extends CompilationUnitElement {
- // TODO(ahe): Library element should not be a subclass of
- // CompilationUnitElement.
-
- Link<CompilationUnitElement> compilationUnits =
- const EmptyLink<CompilationUnitElement>();
- Link<ScriptTag> tags = const EmptyLink<ScriptTag>();
- ScriptTag libraryTag;
- Map<SourceString, Element> elements;
- bool canUseNative = false;
-
- LibraryElement(Script script)
- : elements = new Map<SourceString, Element>(),
- super.library(script);
-
- void addCompilationUnit(CompilationUnitElement element) {
- compilationUnits = compilationUnits.prepend(element);
- }
-
- void addTag(ScriptTag tag, DiagnosticListener listener) {
- tags = tags.prepend(tag);
- }
-
- void addMember(Element element, DiagnosticListener listener) {
- topLevelElements = topLevelElements.prepend(element);
- define(element, listener);
- }
-
- void define(Element element, DiagnosticListener listener) {
- if (element.kind == ElementKind.GETTER
- || element.kind == ElementKind.SETTER) {
- addGetterOrSetter(element, elements[element.name], listener);
- } else {
- Element existing = elements.putIfAbsent(element.name, () => element);
- if (existing !== element) {
- listener.cancel('duplicate definition', token: element.position());
- listener.cancel('existing definition', token: existing.position());
- }
- }
- }
-
- Element find(SourceString elementName) {
- return elements[elementName];
- }
-
- void forEachExport(f(Element element)) {
- elements.forEach((SourceString _, Element e) {
- if (this === e.getLibrary()
- && e.kind !== ElementKind.PREFIX
- && e.kind !== ElementKind.FOREIGN) {
- if (!e.name.isPrivate()) f(e);
- }
- });
- }
-
- bool hasLibraryName() => libraryTag !== null;
-}
-
-class PrefixElement extends Element {
- Map<SourceString, Element> imported;
- Token firstPosition;
-
- 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;
-}
-
-class TypedefElement extends Element {
- Token token;
- TypedefElement(SourceString name, Element enclosing, this.token)
- : super(name, ElementKind.TYPEDEF, enclosing);
-
- position() => findMyName(token);
-}
-
-class VariableElement extends Element {
- final VariableListElement variables;
- Expression cachedNode; // The send or the identifier in the variables list.
-
- Modifiers get modifiers() => variables.modifiers;
-
- VariableElement(SourceString name,
- VariableListElement this.variables,
- ElementKind kind,
- Element enclosing,
- [Node node])
- : super(name, kind, enclosing), cachedNode = node;
-
- Node parseNode(DiagnosticListener listener) {
- if (cachedNode !== null) return cachedNode;
- VariableDefinitions definitions = variables.parseNode(listener);
- for (Link<Node> link = definitions.definitions.nodes;
- !link.isEmpty(); link = link.tail) {
- Expression initializedIdentifier = link.head;
- Identifier identifier = initializedIdentifier.asIdentifier();
- if (identifier === null) {
- identifier = initializedIdentifier.asSendSet().selector.asIdentifier();
- }
- if (name === identifier.source) {
- cachedNode = initializedIdentifier;
- return cachedNode;
- }
- }
- listener.cancel('internal error: could not find $name', node: variables);
- }
-
- Type computeType(Compiler compiler) {
- return variables.computeType(compiler);
- }
-
- Type get type() => variables.type;
-
- bool isInstanceMember() {
- return isMember() && !modifiers.isStatic();
- }
-
- // Note: cachedNode.getBeginToken() will not be correct in all
- // cases, for example, for function typed parameters.
- Token position() => findMyName(variables.position());
-}
-
-/**
- * Parameters in constructors that directly initialize fields. For example:
- * [:A(this.field):].
- */
-class FieldParameterElement extends VariableElement {
- VariableElement fieldElement;
-
- FieldParameterElement(SourceString name,
- this.fieldElement,
- VariableListElement variables,
- Element enclosing,
- Node node)
- : super(name, variables, ElementKind.FIELD_PARAMETER, enclosing, node);
-}
-
-// This element represents a list of variable or field declaration.
-// It contains the node, and the type. A [VariableElement] always
-// references its [VariableListElement]. It forwards its
-// [computeType] and [parseNode] methods to this element.
-class VariableListElement extends Element {
- VariableDefinitions cachedNode;
- Type type;
- final Modifiers modifiers;
-
- VariableListElement(ElementKind kind,
- Modifiers this.modifiers,
- Element enclosing)
- : super(null, kind, enclosing);
-
- VariableListElement.node(VariableDefinitions node,
- ElementKind kind,
- Element enclosing)
- : super(null, kind, enclosing),
- this.cachedNode = node,
- this.modifiers = node.modifiers;
-
- VariableDefinitions parseNode(DiagnosticListener listener) {
- return cachedNode;
- }
-
- Type computeType(Compiler compiler) {
- if (type != null) return type;
- type = getType(parseNode(compiler).type, compiler, getLibrary());
- return type;
- }
-
- Token position() => cachedNode.getBeginToken();
-}
-
-class ForeignElement extends Element {
- ForeignElement(SourceString name, ContainerElement enclosingElement)
- : super(name, ElementKind.FOREIGN, enclosingElement);
-
- Type computeType(Compiler compiler) {
- return compiler.types.dynamicType;
- }
-
- parseNode(DiagnosticListener listener) {
- throw "internal error: ForeignElement has no node";
- }
-}
-
-class AbstractFieldElement extends Element {
- FunctionElement getter;
- FunctionElement setter;
- Modifiers modifiers;
-
- AbstractFieldElement(SourceString name, Element enclosing)
- : super(name, ElementKind.ABSTRACT_FIELD, enclosing),
- modifiers = new Modifiers.empty();
-
- Type computeType(Compiler compiler) {
- throw "internal error: AbstractFieldElement has no type";
- }
-
- Node parseNode(DiagnosticListener listener) {
- throw "internal error: AbstractFieldElement has no node";
- }
-
- position() {
- // The getter and setter may be defined in two different
- // compilation units. However, we know that one of them is
- // non-null and defined in the same compilation unit as the
- // abstract element.
- //
- // We need to make sure that the position returned is relative to
- // the compilation unit of the abstract element.
- if (getter !== null && getter.enclosingElement === enclosingElement) {
- return getter.position();
- } else if (setter != null) {
- // TODO(ahe): checking for null should not be necessary.
- return setter.position();
- }
- }
-}
-
-/** DEPRECATED. */
-Type getType(TypeAnnotation typeAnnotation,
- Compiler compiler,
- LibraryElement library) {
- // TODO(karlklose,ngeoffray): This method should be removed and the
- // information should be computed by the resolver.
-
- if (typeAnnotation == null || typeAnnotation.typeName == null) {
- return compiler.types.dynamicType;
- }
- Identifier identifier = typeAnnotation.typeName.asIdentifier();
- if (identifier === null) {
- compiler.reportWarning(typeAnnotation.typeName,
- 'library prefixes not handled');
- return compiler.types.dynamicType;
- }
- SourceString name = identifier.source;
- Element element = library.find(name);
- if (element !== null) {
- if (element.isTypedef()) {
- // TODO(ngeoffray): This is a hack to help us get support for the
- // DOM library.
- // TODO(ngeoffray): The list of types for the argument is wrong.
- return new FunctionType(compiler.types.dynamicType,
- const EmptyLink<Type>(),
- element);
- }
- if (element.isClass()) {
- // TODO(karlklose): substitute type parameters.
- return element.computeType(compiler);
- }
- }
- Type type = compiler.types.lookup(name);
- if (type === null) {
- type = compiler.types.dynamicType;
- }
- return type;
-}
-
-class FunctionParameters {
- Link<Element> requiredParameters;
- Link<Element> optionalParameters;
- int requiredParameterCount;
- int optionalParameterCount;
- FunctionParameters(this.requiredParameters,
- this.optionalParameters,
- this.requiredParameterCount,
- this.optionalParameterCount);
-
- void forEachParameter(void function(Element parameter)) {
- for (Link<Element> link = requiredParameters;
- !link.isEmpty();
- link = link.tail) {
- function(link.head);
- }
- for (Link<Element> link = optionalParameters;
- !link.isEmpty();
- link = link.tail) {
- function(link.head);
- }
- }
-
- int get parameterCount() => requiredParameterCount + optionalParameterCount;
-}
-
-class FunctionElement extends Element {
- FunctionExpression cachedNode;
- Type type;
- final Modifiers modifiers;
-
- FunctionParameters functionParameters;
-
- /**
- * If this is an interface constructor, [defaultImplementation] will
- * changed by the resolver to point to the default
- * implementation. Otherwise, [:defaultImplementation === this:].
- */
- FunctionElement defaultImplementation;
-
- FunctionElement(SourceString name,
- ElementKind kind,
- Modifiers modifiers,
- Element enclosing)
- : this.tooMuchOverloading(name, null, kind, modifiers, enclosing, null);
-
- FunctionElement.node(SourceString name,
- FunctionExpression node,
- ElementKind kind,
- Modifiers modifiers,
- Element enclosing)
- : this.tooMuchOverloading(name, node, kind, modifiers, enclosing, null);
-
- FunctionElement.from(SourceString name,
- FunctionElement other,
- Element enclosing)
- : this.tooMuchOverloading(name, other.cachedNode, other.kind,
- other.modifiers, enclosing,
- other.functionParameters);
-
- FunctionElement.tooMuchOverloading(SourceString name,
- FunctionExpression this.cachedNode,
- ElementKind kind,
- Modifiers this.modifiers,
- Element enclosing,
- FunctionParameters this.functionParameters)
- : super(name, kind, enclosing)
- {
- defaultImplementation = this;
- }
-
- bool isInstanceMember() {
- return isMember()
- && kind != ElementKind.GENERATIVE_CONSTRUCTOR
- && !modifiers.isFactory()
- && !modifiers.isStatic();
- }
-
- FunctionParameters computeParameters(Compiler compiler) {
- if (functionParameters !== null) return functionParameters;
- functionParameters = compiler.resolveSignature(this);
- return functionParameters;
- }
-
- int requiredParameterCount(Compiler compiler) {
- return computeParameters(compiler).requiredParameterCount;
- }
-
- int optionalParameterCount(Compiler compiler) {
- return computeParameters(compiler).optionalParameterCount;
- }
-
- int parameterCount(Compiler compiler) {
- return computeParameters(compiler).parameterCount;
- }
-
- FunctionType computeType(Compiler compiler) {
- if (type != null) return type;
- FunctionParameters parameters = computeParameters(compiler);
- Types types = compiler.types;
- FunctionExpression node =
- compiler.parser.measure(() => parseNode(compiler));
- Type returnType = getType(node.returnType, compiler, getLibrary());
- if (returnType === null) returnType = types.dynamicType;
-
- LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>();
- for (Link<Element> link = parameters.requiredParameters;
- !link.isEmpty();
- link = link.tail) {
- parameterTypes.addLast(link.head.computeType(compiler));
- }
- type = new FunctionType(returnType, parameterTypes.toLink(), this);
- return type;
- }
-
- Node parseNode(DiagnosticListener listener) => cachedNode;
-
- Token position() => cachedNode.getBeginToken();
-}
-
-class ConstructorBodyElement extends FunctionElement {
- FunctionElement constructor;
-
- ConstructorBodyElement(FunctionElement constructor)
- : this.constructor = constructor,
- super(constructor.name,
- ElementKind.GENERATIVE_CONSTRUCTOR_BODY,
- null,
- constructor.enclosingElement) {
- functionParameters = constructor.functionParameters;
- }
-
- bool isInstanceMember() => true;
-
- FunctionType computeType(Compiler compiler) { unreachable(); }
-
- Node parseNode(DiagnosticListener listener) {
- if (cachedNode !== null) return cachedNode;
- cachedNode = constructor.parseNode(listener);
- assert(cachedNode !== null);
- return cachedNode;
- }
-
- Token position() => constructor.position();
-}
-
-class SynthesizedConstructorElement extends FunctionElement {
- SynthesizedConstructorElement(Element enclosing)
- : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR,
- null, enclosing);
-
- Token position() => enclosingElement.position();
-}
-
-class ClassElement extends ContainerElement {
- Type type;
- Type supertype;
- Type defaultClass;
- Link<Element> members = const EmptyLink<Element>();
- Map<SourceString, Element> localMembers;
- Map<SourceString, Element> constructors;
- Link<Type> interfaces = const EmptyLink<Type>();
- Map<SourceString, TypeVariableElement> typeParameters;
- bool isResolved = false;
- bool isBeingResolved = false;
- // backendMembers are members that have been added by the backend to simplify
- // compilation. They don't have any user-side counter-part.
- Link<Element> backendMembers = const EmptyLink<Element>();
-
- Link<Type> allSupertypes;
-
- ClassElement(SourceString name, CompilationUnitElement enclosing)
- : localMembers = new Map<SourceString, Element>(),
- constructors = new Map<SourceString, Element>(),
- typeParameters = new Map<SourceString, TypeVariableElement>(),
- super(name, ElementKind.CLASS, enclosing);
-
- void addMember(Element element, DiagnosticListener listener) {
- members = members.prepend(element);
- if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR ||
- element.modifiers.isFactory()) {
- constructors[element.name] = element;
- } else if (element.kind == ElementKind.GETTER
- || element.kind == ElementKind.SETTER) {
- addGetterOrSetter(element, localMembers[element.name], listener);
- } else {
- localMembers[element.name] = element;
- }
- }
-
- Type computeType(compiler) {
- if (type === null) {
- type = new SimpleType(name, this);
- }
- return type;
- }
-
- ClassElement ensureResolved(Compiler compiler) {
- if (!isResolved && !isBeingResolved) {
- isBeingResolved = true;
- compiler.resolveType(this);
- isBeingResolved = false;
- isResolved = true;
- }
- return this;
- }
-
- Element lookupTypeParameter(SourceString parameterName) {
- Element result = typeParameters[parameterName];
- return result;
- }
-
- Element lookupLocalMember(SourceString memberName) {
- return localMembers[memberName];
- }
-
- Element lookupSuperMember(SourceString memberName) {
- for (ClassElement s = superclass; s != null; s = s.superclass) {
- Element e = s.lookupLocalMember(memberName);
- if (e !== null) {
- if (!memberName.isPrivate() || getLibrary() === e.getLibrary()) {
- return e;
- }
- }
- }
- return null;
- }
-
- Element lookupConstructor(SourceString className,
- [SourceString constructorName =
- const SourceString(''),
- Element noMatch(Element)]) {
- // TODO(karlklose): have a map from class names to a map of constructors
- // instead of creating the name here?
- SourceString normalizedName;
- if (constructorName !== const SourceString('')) {
- normalizedName = Elements.constructConstructorName(className,
- constructorName);
- } else {
- normalizedName = className;
- }
- Element result = constructors[normalizedName];
- if (result === null && noMatch !== null) {
- result = noMatch(lookupLocalMember(constructorName));
- }
- return result;
- }
-
- /**
- * Returns the super class, if any.
- *
- * The returned element may not be resolved yet.
- */
- ClassElement get superclass() {
- assert(isResolved);
- return supertype === null ? null : supertype.element;
- }
-
- bool isInterface() => false;
- bool isNative() => nativeName != null;
- SourceString nativeName;
-}
-
-class Elements {
- static bool isLocal(Element element) {
- return ((element !== null)
- && !element.isInstanceMember()
- && !isStaticOrTopLevelField(element)
- && !isStaticOrTopLevelFunction(element)
- && (element.kind === ElementKind.VARIABLE ||
- element.kind === ElementKind.PARAMETER ||
- element.kind === ElementKind.FUNCTION));
- }
-
- static bool isInstanceField(Element element) {
- return (element !== null)
- && element.isInstanceMember()
- && (element.kind === ElementKind.FIELD
- || element.kind === ElementKind.GETTER
- || element.kind === ElementKind.SETTER);
- }
-
- static bool isStaticOrTopLevel(Element element) {
- return (element != null)
- && !element.isInstanceMember()
- && element.enclosingElement !== null
- && (element.enclosingElement.kind == ElementKind.CLASS ||
- element.enclosingElement.kind == ElementKind.COMPILATION_UNIT ||
- element.enclosingElement.kind == ElementKind.LIBRARY);
- }
-
- static bool isStaticOrTopLevelField(Element element) {
- return isStaticOrTopLevel(element)
- && (element.kind === ElementKind.FIELD
- || element.kind === ElementKind.GETTER
- || element.kind === ElementKind.SETTER);
- }
-
- static bool isStaticOrTopLevelFunction(Element element) {
- return isStaticOrTopLevel(element)
- && (element.kind === ElementKind.FUNCTION);
- }
-
- static bool isInstanceMethod(Element element) {
- return (element != null)
- && element.isInstanceMember()
- && (element.kind === ElementKind.FUNCTION);
- }
-
- static bool isInstanceSend(Send send, TreeElements elements) {
- Element element = elements[send];
- if (element === null) return !isClosureSend(send, elements);
- return isInstanceMethod(element) || isInstanceField(element);
- }
-
- static bool isClosureSend(Send send, TreeElements elements) {
- if (send.isPropertyAccess) return false;
- if (send.receiver !== null) return false;
- Element element = elements[send];
- // (o)() or foo()().
- if (element === null && send.selector.asIdentifier() === null) return true;
- if (element === null) return false;
- // foo() with foo a local or a parameter.
- return isLocal(element);
- }
-
- static SourceString constructConstructorName(SourceString receiver,
- SourceString selector) {
- String r = receiver.slowToString();
- String s = selector.slowToString();
- return new SourceString('$r\$$s');
- }
-
- static SourceString constructOperatorName(SourceString receiver,
- SourceString selector,
- [bool isPrefix = false]) {
- String str = selector.stringValue;
- if (str === '==' || str === '!=') return Namer.OPERATOR_EQUALS;
-
- if (str === '~') str = 'not';
- else if (str === 'negate' || (str === '-' && isPrefix)) str = 'negate';
- else if (str === '[]') str = 'index';
- else if (str === '[]=') str = 'indexSet';
- else if (str === '*' || str === '*=') str = 'mul';
- else if (str === '/' || str === '/=') str = 'div';
- else if (str === '%' || str === '%=') str = 'mod';
- else if (str === '~/' || str === '~/=') str = 'tdiv';
- else if (str === '+' || str === '+=') str = 'add';
- else if (str === '-' || str === '-=') str = 'sub';
- else if (str === '<<' || str === '<<=') str = 'shl';
- else if (str === '>>' || str === '>>=') str = 'shr';
- else if (str === '>=') str = 'ge';
- else if (str === '>') str = 'gt';
- else if (str === '<=') str = 'le';
- else if (str === '<') str = 'lt';
- else if (str === '&' || str === '&=') str = 'and';
- else if (str === '^' || str === '^=') str = 'xor';
- else if (str === '|' || str === '|=') str = 'or';
- else {
- throw new Exception('Unhandled selector: ${selector.slowToString()}');
- }
- return new SourceString('$receiver\$$str');
- }
-
- static bool isStringSupertype(Element element, Compiler compiler) {
- LibraryElement coreLibrary = compiler.coreLibrary;
- return (element == coreLibrary.find(const SourceString('Comparable')))
- || (element == coreLibrary.find(const SourceString('Hashable')))
- || (element == coreLibrary.find(const SourceString('Pattern')));
- }
-
- static bool isListSupertype(Element element, Compiler compiler) {
- LibraryElement coreLibrary = compiler.coreLibrary;
- return (element == coreLibrary.find(const SourceString('Collection')))
- || (element == coreLibrary.find(const SourceString('Iterable')));
- }
-}
-
-
-class LabelElement extends Element {
- final Identifier label;
- final String labelName;
- final TargetElement target;
- bool isBreakTarget = false;
- bool isContinueTarget = false;
- LabelElement(Identifier label, this.labelName, this.target,
- Element enclosingElement)
- : this.label = label,
- super(label.source, ElementKind.LABEL, enclosingElement);
-
- void setBreakTarget() {
- isBreakTarget = true;
- target.isBreakTarget = true;
- }
- void setContinueTarget() {
- isContinueTarget = true;
- target.isContinueTarget = true;
- }
-
- bool get isTarget() => isBreakTarget || isContinueTarget;
- Node parseNode(DiagnosticListener l) => label;
-
- Token position() => label.token;
- String toString() => "${labelName}:";
-}
-
-// Represents a reference to a statement, either a label or the
-// default target of a break or continue.
-class TargetElement extends Element {
- // TODO(lrn): StatementElement is not just referencing statements anymore.
- final Node statement;
- final int nestingLevel;
- Link<LabelElement> labels = const EmptyLink<LabelElement>();
- bool isBreakTarget = false;
- bool isContinueTarget = false;
-
- TargetElement(this.statement, this.nestingLevel, Element enclosingElement)
- : super(const SourceString(""), ElementKind.STATEMENT, enclosingElement);
- bool get isTarget() => isBreakTarget || isContinueTarget;
-
- LabelElement addLabel(Identifier label, String labelName) {
- LabelElement result = new LabelElement(label, labelName, this,
- enclosingElement);
- labels = labels.prepend(result);
- return result;
- }
-
- Node parseNode(DiagnosticListener l) => statement;
-
- bool get isSwitch() => statement is SwitchStatement;
-
- Token position() => statement.getBeginToken();
- String toString() => statement.toString();
-}
-
-class TypeVariableElement extends Element {
- final Node node;
- Type bound;
- Type type;
- TypeVariableElement(name, Element enclosing, this.node, this.type,
- [this.bound])
- : super(name, ElementKind.TYPE_VARIABLE, enclosing);
- Type computeType(compiler) => type;
- Node parseNode(compiler) => node;
- toString() => "${enclosingElement.toString()}.${name.slowToString()}";
-}
« no previous file with comments | « frog/leg/diagnostic_listener.dart ('k') | frog/leg/emitter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698