| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #library('elements'); | 5 #library('elements'); |
| 6 | 6 |
| 7 #import('../tree/tree.dart'); | 7 #import('../tree/tree.dart'); |
| 8 #import('../scanner/scannerlib.dart'); | 8 #import('../scanner/scannerlib.dart'); |
| 9 #import('../leg.dart'); // TODO(karlklose): we only need type. | 9 #import('../leg.dart'); // TODO(karlklose): we only need type. |
| 10 #import('../util/util.dart'); | 10 #import('../util/util.dart'); |
| 11 | 11 |
| 12 class ElementCategory { |
| 13 /** |
| 14 * Represents things that we don't expect to find when looking in a |
| 15 * scope. |
| 16 */ |
| 17 static final int NONE = 0; |
| 18 |
| 19 /** Field, parameter, or variable. */ |
| 20 static final int VARIABLE = 1; |
| 21 |
| 22 /** Function, method, or foreign function. */ |
| 23 static final int FUNCTION = 2; |
| 24 |
| 25 static final int CLASS = 4; |
| 26 |
| 27 static final int PREFIX = 8; |
| 28 |
| 29 /** Constructor or factory. */ |
| 30 static final int FACTORY = 16; |
| 31 |
| 32 static final int ALIAS = 32; |
| 33 |
| 34 static final int SUPER = 64; |
| 35 |
| 36 static final int IMPLIES_TYPE = CLASS | ALIAS; |
| 37 } |
| 38 |
| 12 class ElementKind { | 39 class ElementKind { |
| 13 final String id; | 40 final String id; |
| 41 final int category; |
| 14 | 42 |
| 15 const ElementKind(String this.id); | 43 const ElementKind(String this.id, this.category); |
| 16 | 44 |
| 17 static final ElementKind VARIABLE = const ElementKind('variable'); | 45 static final ElementKind VARIABLE = |
| 18 static final ElementKind PARAMETER = const ElementKind('parameter'); | 46 const ElementKind('variable', ElementCategory.VARIABLE); |
| 19 static final ElementKind FUNCTION = const ElementKind('function'); | 47 static final ElementKind PARAMETER = |
| 20 static final ElementKind CLASS = const ElementKind('class'); | 48 const ElementKind('parameter', ElementCategory.VARIABLE); |
| 21 static final ElementKind FOREIGN = const ElementKind('foreign'); | 49 static final ElementKind FUNCTION = |
| 50 const ElementKind('function', ElementCategory.FUNCTION); |
| 51 static final ElementKind CLASS = |
| 52 const ElementKind('class', ElementCategory.CLASS); |
| 53 static final ElementKind FOREIGN = |
| 54 const ElementKind('foreign', ElementCategory.FUNCTION); |
| 22 static final ElementKind GENERATIVE_CONSTRUCTOR = | 55 static final ElementKind GENERATIVE_CONSTRUCTOR = |
| 23 const ElementKind('generative_constructor'); | 56 const ElementKind('generative_constructor', ElementCategory.FACTORY); |
| 24 static final ElementKind FIELD = const ElementKind('field'); | 57 static final ElementKind FIELD = |
| 25 static final ElementKind VARIABLE_LIST = const ElementKind('variable_list'); | 58 const ElementKind('field', ElementCategory.VARIABLE); |
| 26 static final ElementKind FIELD_LIST = const ElementKind('field_list'); | 59 static final ElementKind VARIABLE_LIST = |
| 60 const ElementKind('variable_list', ElementCategory.NONE); |
| 61 static final ElementKind FIELD_LIST = |
| 62 const ElementKind('field_list', ElementCategory.NONE); |
| 27 static final ElementKind GENERATIVE_CONSTRUCTOR_BODY = | 63 static final ElementKind GENERATIVE_CONSTRUCTOR_BODY = |
| 28 const ElementKind('generative_constructor_body'); | 64 const ElementKind('generative_constructor_body', ElementCategory.NONE); |
| 29 static final ElementKind COMPILATION_UNIT = | 65 static final ElementKind COMPILATION_UNIT = |
| 30 const ElementKind('compilation_unit'); | 66 const ElementKind('compilation_unit', ElementCategory.NONE); |
| 31 static final ElementKind GETTER = const ElementKind('getter'); | 67 static final ElementKind GETTER = |
| 32 static final ElementKind SETTER = const ElementKind('setter'); | 68 const ElementKind('getter', |
| 33 static final ElementKind ABSTRACT_FIELD = const ElementKind('abstract_field'); | 69 ElementCategory.VARIABLE); // TODO(ahe): Sb. NONE. |
| 34 static final ElementKind LIBRARY = const ElementKind('library'); | 70 static final ElementKind SETTER = |
| 35 static final ElementKind PREFIX = const ElementKind('prefix'); | 71 const ElementKind('setter', |
| 36 static final ElementKind TYPEDEF = const ElementKind('typedef'); | 72 ElementCategory.VARIABLE); // TODO(ahe): Sb. NONE. |
| 73 static final ElementKind ABSTRACT_FIELD = |
| 74 const ElementKind('abstract_field', ElementCategory.VARIABLE); |
| 75 static final ElementKind LIBRARY = |
| 76 const ElementKind('library', ElementCategory.NONE); |
| 77 static final ElementKind PREFIX = |
| 78 const ElementKind('prefix', ElementCategory.PREFIX); |
| 79 static final ElementKind TYPEDEF = |
| 80 const ElementKind('typedef', ElementCategory.ALIAS); |
| 37 | 81 |
| 38 static final ElementKind STATEMENT = const ElementKind('statement'); | 82 static final ElementKind STATEMENT = |
| 39 static final ElementKind LABEL = const ElementKind('label'); | 83 const ElementKind('statement', ElementCategory.NONE); |
| 84 static final ElementKind LABEL = |
| 85 const ElementKind('label', ElementCategory.NONE); |
| 40 | 86 |
| 41 toString() => id; | 87 toString() => id; |
| 42 } | 88 } |
| 43 | 89 |
| 44 class Element implements Hashable { | 90 class Element implements Hashable { |
| 45 final SourceString name; | 91 final SourceString name; |
| 46 final ElementKind kind; | 92 final ElementKind kind; |
| 47 final Element enclosingElement; | 93 final Element enclosingElement; |
| 48 Modifiers get modifiers() => null; | 94 Modifiers get modifiers() => null; |
| 49 | 95 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 63 bool isGenerativeConstructor() => kind === ElementKind.GENERATIVE_CONSTRUCTOR; | 109 bool isGenerativeConstructor() => kind === ElementKind.GENERATIVE_CONSTRUCTOR; |
| 64 bool isCompilationUnit() { | 110 bool isCompilationUnit() { |
| 65 return kind === ElementKind.COMPILATION_UNIT || | 111 return kind === ElementKind.COMPILATION_UNIT || |
| 66 kind === ElementKind.LIBRARY; | 112 kind === ElementKind.LIBRARY; |
| 67 } | 113 } |
| 68 bool isClass() => kind === ElementKind.CLASS; | 114 bool isClass() => kind === ElementKind.CLASS; |
| 69 bool isVariable() => kind === ElementKind.VARIABLE; | 115 bool isVariable() => kind === ElementKind.VARIABLE; |
| 70 bool isParameter() => kind === ElementKind.PARAMETER; | 116 bool isParameter() => kind === ElementKind.PARAMETER; |
| 71 bool isStatement() => kind === ElementKind.STATEMENT; | 117 bool isStatement() => kind === ElementKind.STATEMENT; |
| 72 bool isTypedef() => kind === ElementKind.TYPEDEF; | 118 bool isTypedef() => kind === ElementKind.TYPEDEF; |
| 73 // TODO(ahe): Remove this method. | 119 bool impliesType() => (kind.category & ElementCategory.IMPLIES_TYPE) != 0; |
| 74 bool isClassOrInterfaceOrTypedef() { | |
| 75 return kind == ElementKind.CLASS || kind == ElementKind.TYPEDEF; | |
| 76 } | |
| 77 | 120 |
| 78 bool isAssignable() { | 121 bool isAssignable() { |
| 79 if (modifiers != null && modifiers.isFinal()) return false; | 122 if (modifiers != null && modifiers.isFinal()) return false; |
| 80 if (isFunction() || isGenerativeConstructor()) return false; | 123 if (isFunction() || isGenerativeConstructor()) return false; |
| 81 return true; | 124 return true; |
| 82 } | 125 } |
| 83 | 126 |
| 84 Token position() => null; | 127 Token position() => null; |
| 85 | 128 |
| 86 const Element(this.name, this.kind, this.enclosingElement); | 129 const Element(this.name, this.kind, this.enclosingElement); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 } | 237 } |
| 195 | 238 |
| 196 class PrefixElement extends Element { | 239 class PrefixElement extends Element { |
| 197 final LiteralString prefix; | 240 final LiteralString prefix; |
| 198 final LibraryElement library; | 241 final LibraryElement library; |
| 199 | 242 |
| 200 PrefixElement(LiteralString prefix, | 243 PrefixElement(LiteralString prefix, |
| 201 LibraryElement this.library, | 244 LibraryElement this.library, |
| 202 Element enclosing) | 245 Element enclosing) |
| 203 : this.prefix = prefix, | 246 : this.prefix = prefix, |
| 204 super(prefix.dartString.source, ElementKind.PREFIX, enclosing) { | 247 super(prefix.dartString.source, ElementKind.PREFIX, enclosing); |
| 205 } | 248 |
| 249 lookupLocalMember(SourceString name) => library.lookupLocalMember(name); |
| 206 } | 250 } |
| 207 | 251 |
| 208 class TypedefElement extends Element { | 252 class TypedefElement extends Element { |
| 209 TypedefElement(SourceString name, Element enclosing) | 253 TypedefElement(SourceString name, Element enclosing) |
| 210 : super(name, ElementKind.TYPEDEF, enclosing); | 254 : super(name, ElementKind.TYPEDEF, enclosing); |
| 211 } | 255 } |
| 212 | 256 |
| 213 class VariableElement extends Element { | 257 class VariableElement extends Element { |
| 214 final VariableListElement variables; | 258 final VariableListElement variables; |
| 215 Expression cachedNode; // The send or the identifier in the variables list. | 259 Expression cachedNode; // The send or the identifier in the variables list. |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 FunctionType computeType(Compiler compiler) { | 557 FunctionType computeType(Compiler compiler) { |
| 514 if (type != null) return type; | 558 if (type != null) return type; |
| 515 Type returnType = compiler.types.voidType; | 559 Type returnType = compiler.types.voidType; |
| 516 type = new FunctionType(returnType, const EmptyLink<Type>(), this); | 560 type = new FunctionType(returnType, const EmptyLink<Type>(), this); |
| 517 return type; | 561 return type; |
| 518 } | 562 } |
| 519 | 563 |
| 520 Node parseNode(DiagnosticListener listener) { | 564 Node parseNode(DiagnosticListener listener) { |
| 521 if (cachedNode != null) return cachedNode; | 565 if (cachedNode != null) return cachedNode; |
| 522 cachedNode = new FunctionExpression( | 566 cachedNode = new FunctionExpression( |
| 523 new Identifier.synthetic(''), | 567 new Identifier(enclosingElement.position()), |
| 524 new NodeList.empty(), | 568 new NodeList.empty(), |
| 525 new Block(new NodeList.empty()), | 569 new Block(new NodeList.empty()), |
| 526 null, null, null, null); | 570 null, null, null, null); |
| 527 return cachedNode; | 571 return cachedNode; |
| 528 } | 572 } |
| 529 | 573 |
| 530 Token position() => null; | 574 Token position() => null; |
| 531 } | 575 } |
| 532 | 576 |
| 533 class ClassElement extends ContainerElement { | 577 class ClassElement extends ContainerElement { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 compiler.resolveType(this); | 655 compiler.resolveType(this); |
| 612 isResolved = true; | 656 isResolved = true; |
| 613 } | 657 } |
| 614 return this; | 658 return this; |
| 615 } | 659 } |
| 616 | 660 |
| 617 Element lookupLocalMember(SourceString memberName) { | 661 Element lookupLocalMember(SourceString memberName) { |
| 618 return localMembers[memberName]; | 662 return localMembers[memberName]; |
| 619 } | 663 } |
| 620 | 664 |
| 665 Element lookupSuperMember(SourceString name) { |
| 666 for (ClassElement s = superclass; s != null; s = s.superclass) { |
| 667 Element e = s.lookupLocalMember(name); |
| 668 if (e !== null) return e; |
| 669 } |
| 670 return null; |
| 671 } |
| 672 |
| 621 Element lookupConstructor(SourceString className, | 673 Element lookupConstructor(SourceString className, |
| 622 [SourceString constructorName = | 674 [SourceString constructorName = |
| 623 const SourceString(''), | 675 const SourceString(''), |
| 624 Element noMatch(Element)]) { | 676 Element noMatch(Element)]) { |
| 625 // TODO(karlklose): have a map from class names to a map of constructors | 677 // TODO(karlklose): have a map from class names to a map of constructors |
| 626 // instead of creating the name here? | 678 // instead of creating the name here? |
| 627 SourceString normalizedName; | 679 SourceString normalizedName; |
| 628 if (constructorName !== const SourceString('')) { | 680 if (constructorName !== const SourceString('')) { |
| 629 normalizedName = Elements.constructConstructorName(className, | 681 normalizedName = Elements.constructConstructorName(className, |
| 630 constructorName); | 682 constructorName); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 | 858 |
| 807 LabelElement addLabel(Identifier label, String labelName) { | 859 LabelElement addLabel(Identifier label, String labelName) { |
| 808 LabelElement result = new LabelElement(label, labelName, this, | 860 LabelElement result = new LabelElement(label, labelName, this, |
| 809 enclosingElement); | 861 enclosingElement); |
| 810 labels = labels.prepend(result); | 862 labels = labels.prepend(result); |
| 811 return result; | 863 return result; |
| 812 } | 864 } |
| 813 | 865 |
| 814 Node parseNode(DiagnosticListener l) => statement; | 866 Node parseNode(DiagnosticListener l) => statement; |
| 815 } | 867 } |
| OLD | NEW |