| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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'); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 final String id; | 23 final String id; |
| 24 | 24 |
| 25 const ElementKind(String this.id); | 25 const ElementKind(String this.id); |
| 26 | 26 |
| 27 static final ElementKind VARIABLE = const ElementKind('variable'); | 27 static final ElementKind VARIABLE = const ElementKind('variable'); |
| 28 static final ElementKind PARAMETER = const ElementKind('parameter'); | 28 static final ElementKind PARAMETER = const ElementKind('parameter'); |
| 29 static final ElementKind FUNCTION = const ElementKind('function'); | 29 static final ElementKind FUNCTION = const ElementKind('function'); |
| 30 static final ElementKind CLASS = const ElementKind('class'); | 30 static final ElementKind CLASS = const ElementKind('class'); |
| 31 static final ElementKind FOREIGN = const ElementKind('foreign'); | 31 static final ElementKind FOREIGN = const ElementKind('foreign'); |
| 32 static final ElementKind CONSTRUCTOR = const ElementKind('constructor'); | 32 static final ElementKind CONSTRUCTOR = const ElementKind('constructor'); |
| 33 static final ElementKind CONSTRUCTOR_BODY = |
| 34 const ElementKind('constructor_body'); |
| 33 | 35 |
| 34 toString() => id; | 36 toString() => id; |
| 35 } | 37 } |
| 36 | 38 |
| 37 class Element implements Hashable { | 39 class Element implements Hashable { |
| 38 final SourceString name; | 40 final SourceString name; |
| 39 final ElementKind kind; | 41 final ElementKind kind; |
| 40 final Element enclosingElement; | 42 final Element enclosingElement; |
| 41 abstract Node parseNode(Canceler canceler, Logger logger); | 43 abstract Node parseNode(Canceler canceler, Logger logger); |
| 42 abstract Type computeType(Compiler compiler, Types types); | 44 abstract Type computeType(Compiler compiler, Types types); |
| 43 bool isClassMember() => | 45 bool isClassMember() => |
| 44 enclosingElement !== null && enclosingElement.kind == ElementKind.CLASS; | 46 enclosingElement !== null && enclosingElement.kind == ElementKind.CLASS; |
| 45 // TODO(ngeoffray): override in function element to check for modifiers. | 47 // TODO(ngeoffray): override in function element to check for modifiers. |
| 46 bool isStatic() => !isClassMember(); | 48 bool isInstanceMember() => isClassMember(); |
| 47 | 49 |
| 48 const Element(this.name, this.kind, this.enclosingElement); | 50 const Element(this.name, this.kind, this.enclosingElement); |
| 49 | 51 |
| 50 // TODO(kasperl): This is a very bad hash code for the element and | 52 // TODO(kasperl): This is a very bad hash code for the element and |
| 51 // there's no reason why two elements with the same name should have | 53 // there's no reason why two elements with the same name should have |
| 52 // the same hash code. Replace this with a simple id in the element? | 54 // the same hash code. Replace this with a simple id in the element? |
| 53 int hashCode() => name.hashCode(); | 55 int hashCode() => name.hashCode(); |
| 54 | 56 |
| 55 toString() => '$name'; | 57 toString() => '$name'; |
| 56 } | 58 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 FunctionElement(SourceString name, | 113 FunctionElement(SourceString name, |
| 112 ElementKind kind, | 114 ElementKind kind, |
| 113 Element enclosing) | 115 Element enclosing) |
| 114 : super(name, kind, enclosing); | 116 : super(name, kind, enclosing); |
| 115 FunctionElement.node(FunctionExpression node, | 117 FunctionElement.node(FunctionExpression node, |
| 116 ElementKind kind, | 118 ElementKind kind, |
| 117 Element enclosing) | 119 Element enclosing) |
| 118 : super(node.name.asIdentifier().source, kind, enclosing), | 120 : super(node.name.asIdentifier().source, kind, enclosing), |
| 119 this.node = node; | 121 this.node = node; |
| 120 | 122 |
| 123 bool isInstanceMember() { |
| 124 // TODO(ngeoffray): use modifiers. |
| 125 return super.isInstanceMember() && kind != ElementKind.CONSTRUCTOR; |
| 126 } |
| 127 |
| 121 FunctionType computeType(Compiler compiler, types) { | 128 FunctionType computeType(Compiler compiler, types) { |
| 122 if (type != null) return type; | 129 if (type != null) return type; |
| 123 if (parameters == null) compiler.resolveSignature(this); | 130 if (parameters == null) compiler.resolveSignature(this); |
| 124 FunctionExpression node = | 131 FunctionExpression node = |
| 125 compiler.parser.measure(() => parseNode(compiler, compiler)); | 132 compiler.parser.measure(() => parseNode(compiler, compiler)); |
| 126 Type returnType = getType(node.returnType, compiler, types); | 133 Type returnType = getType(node.returnType, compiler, types); |
| 127 if (returnType === null) compiler.cancel('unknown type ${node.returnType}'); | 134 if (returnType === null) compiler.cancel('unknown type ${node.returnType}'); |
| 128 | 135 |
| 129 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); | 136 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); |
| 130 for (Link<Element> link = parameters; !link.isEmpty(); link = link.tail) { | 137 for (Link<Element> link = parameters; !link.isEmpty(); link = link.tail) { |
| 131 parameterTypes.addLast(link.head.computeType(compiler, types)); | 138 parameterTypes.addLast(link.head.computeType(compiler, types)); |
| 132 } | 139 } |
| 133 type = new FunctionType(returnType, parameterTypes.toLink(), this); | 140 type = new FunctionType(returnType, parameterTypes.toLink(), this); |
| 134 return type; | 141 return type; |
| 135 } | 142 } |
| 136 | 143 |
| 137 Node parseNode(Canceler canceler, Logger logger) => node; | 144 Node parseNode(Canceler canceler, Logger logger) => node; |
| 138 } | 145 } |
| 139 | 146 |
| 147 class ConstructorBodyElement extends FunctionElement { |
| 148 FunctionElement constructor; |
| 149 |
| 150 ConstructorBodyElement(FunctionElement constructor) |
| 151 : this.constructor = constructor, |
| 152 super(constructor.name, |
| 153 ElementKind.CONSTRUCTOR_BODY, |
| 154 constructor.enclosingElement) { |
| 155 assert(constructor.node !== null); |
| 156 this.parameters = constructor.parameters; |
| 157 this.node = constructor.node; |
| 158 this.type = constructor.type; |
| 159 } |
| 160 |
| 161 bool isInstanceMember() => true; |
| 162 |
| 163 FunctionType computeType(Compiler compiler, types) { unreachable(); } |
| 164 Node parseNode(Canceler canceler, Logger logger) { unreachable(); } |
| 165 } |
| 166 |
| 140 class SynthesizedConstructorElement extends FunctionElement { | 167 class SynthesizedConstructorElement extends FunctionElement { |
| 141 SynthesizedConstructorElement(Element enclosing) | 168 SynthesizedConstructorElement(Element enclosing) |
| 142 : super(enclosing.name, ElementKind.CONSTRUCTOR, enclosing) { | 169 : super(enclosing.name, ElementKind.CONSTRUCTOR, enclosing) { |
| 143 parameters = const EmptyLink<Element>(); | 170 parameters = const EmptyLink<Element>(); |
| 144 } | 171 } |
| 145 | 172 |
| 146 FunctionType computeType(Compiler compiler, types) { | 173 FunctionType computeType(Compiler compiler, types) { |
| 147 if (type != null) return type; | 174 if (type != null) return type; |
| 148 type = new FunctionType(types.voidType, const EmptyLink<Type>(), this); | 175 type = new FunctionType(types.voidType, const EmptyLink<Type>(), this); |
| 149 return type; | 176 return type; |
| 150 } | 177 } |
| 151 | 178 |
| 152 Node parseNode(Canceler canceler, Logger logger) { | 179 Node parseNode(Canceler canceler, Logger logger) { |
| 153 if (node != null) return node; | 180 if (node != null) return node; |
| 154 node = new FunctionExpression( | 181 node = new FunctionExpression( |
| 155 new Identifier.synthetic(''), | 182 new Identifier.synthetic(''), |
| 156 new NodeList.empty(), | 183 new NodeList.empty(), |
| 157 new Block(new NodeList.empty())); | 184 new Block(new NodeList.empty())); |
| 158 return node; | 185 return node; |
| 159 } | 186 } |
| 160 } | 187 } |
| 161 | 188 |
| 162 class ClassElement extends Element { | 189 class ClassElement extends Element { |
| 163 Type type; | 190 Type type; |
| 164 Type supertype; | 191 Type supertype; |
| 165 Link<Element> members = const EmptyLink<Element>(); | 192 Link<Element> members = const EmptyLink<Element>(); |
| 166 Link<Type> interfaces = const EmptyLink<Type>(); | 193 Link<Type> interfaces = const EmptyLink<Type>(); |
| 167 bool isResolved = false; | 194 bool isResolved = false; |
| 168 ClassNode node; | 195 ClassNode node; |
| 196 // backendMembers are members that have been added by the backend to simplify |
| 197 // compilation. They don't have any user-side counter-part. |
| 198 Link<Element> backendMembers = const EmptyLink<Element>(); |
| 169 SynthesizedConstructorElement synthesizedConstructor; | 199 SynthesizedConstructorElement synthesizedConstructor; |
| 170 | 200 |
| 171 ClassElement(SourceString name) : super(name, ElementKind.CLASS, null); | 201 ClassElement(SourceString name) : super(name, ElementKind.CLASS, null); |
| 172 | 202 |
| 173 void addMember(Element element) { | 203 void addMember(Element element) { |
| 174 members = members.prepend(element); | 204 members = members.prepend(element); |
| 175 } | 205 } |
| 176 | 206 |
| 177 Type computeType(compiler, types) { | 207 Type computeType(compiler, types) { |
| 178 if (type === null) { | 208 if (type === null) { |
| 179 type = new SimpleType(name, this); | 209 type = new SimpleType(name, this); |
| 180 } | 210 } |
| 181 return type; | 211 return type; |
| 182 } | 212 } |
| 183 | 213 |
| 184 void resolve(Compiler compiler) { | 214 void resolve(Compiler compiler) { |
| 185 if (isResolved) return; | 215 if (isResolved) return; |
| 186 compiler.resolveType(this); | 216 compiler.resolveType(this); |
| 187 isResolved = true; | 217 isResolved = true; |
| 188 } | 218 } |
| 189 | 219 |
| 190 Element lookupLocalElement(SourceString name) { | 220 Element lookupLocalElement(SourceString name) { |
| 191 // TODO(karlklose): replace with more eficient solution. | 221 // TODO(karlklose): replace with more efficient solution. |
| 192 for (Link<Element> link = members; | 222 for (Link<Element> link = members; |
| 193 link !== null && !link.isEmpty(); | 223 link !== null && !link.isEmpty(); |
| 194 link = link.tail) { | 224 link = link.tail) { |
| 195 if (link.head.name == name) return link.head; | 225 if (link.head.name == name) return link.head; |
| 196 } | 226 } |
| 197 return null; | 227 return null; |
| 198 } | 228 } |
| 199 | 229 |
| 200 // TODO(ngeoffray): Implement these. | 230 // TODO(ngeoffray): Implement these. |
| 201 bool canHaveDefaultConstructor() => true; | 231 bool canHaveDefaultConstructor() => true; |
| 202 | 232 |
| 203 SynthesizedConstructorElement getSynthesizedConstructor() { | 233 SynthesizedConstructorElement getSynthesizedConstructor() { |
| 204 if (synthesizedConstructor === null && canHaveDefaultConstructor()) { | 234 if (synthesizedConstructor === null && canHaveDefaultConstructor()) { |
| 205 synthesizedConstructor = new SynthesizedConstructorElement(this); | 235 synthesizedConstructor = new SynthesizedConstructorElement(this); |
| 206 } | 236 } |
| 207 return synthesizedConstructor; | 237 return synthesizedConstructor; |
| 208 } | 238 } |
| 209 } | 239 } |
| OLD | NEW |