| 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 interface TreeElements { | 5 interface TreeElements { |
| 6 Element operator[](Node node); | 6 Element operator[](Node node); |
| 7 Selector getSelector(Send send); | 7 Selector getSelector(Send send); |
| 8 } | 8 } |
| 9 | 9 |
| 10 class TreeElementMapping implements TreeElements { | 10 class TreeElementMapping implements TreeElements { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 case ElementKind.PARAMETER: | 50 case ElementKind.PARAMETER: |
| 51 return resolveVariableElement(element); | 51 return resolveVariableElement(element); |
| 52 | 52 |
| 53 default: | 53 default: |
| 54 compiler.unimplemented( | 54 compiler.unimplemented( |
| 55 "resolver", node: element.parseNode(compiler)); | 55 "resolver", node: element.parseNode(compiler)); |
| 56 } | 56 } |
| 57 }); | 57 }); |
| 58 } | 58 } |
| 59 | 59 |
| 60 SourceString getConstructorName(Send node) { |
| 61 if (node.receiver !== null) { |
| 62 return node.selector.asIdentifier().source; |
| 63 } else { |
| 64 return const SourceString(''); |
| 65 } |
| 66 } |
| 67 |
| 68 FunctionElement lookupConstructor(ClassElement classElement, Send send, |
| 69 [noConstructor(Element)]) { |
| 70 final SourceString constructorName = getConstructorName(send); |
| 71 final SourceString className = classElement.name; |
| 72 FunctionElement result = classElement.lookupConstructor(className, |
| 73 constructorName, |
| 74 noConstructor); |
| 75 if (result === null && send.arguments.isEmpty()) { |
| 76 result = classElement.getSynthesizedConstructor(); |
| 77 } |
| 78 return result; |
| 79 } |
| 80 |
| 81 FunctionElement resolveConstructorRedirection(FunctionElement constructor) { |
| 82 FunctionExpression node = constructor.parseNode(compiler); |
| 83 // A synthetic constructor does not have a node. |
| 84 if (node === null) return null; |
| 85 if (node.initializers === null) return null; |
| 86 Link<Node> initializers = node.initializers.nodes; |
| 87 if (!initializers.isEmpty() && |
| 88 Initializers.isConstructorRedirect(initializers.head)) { |
| 89 return lookupConstructor(constructor.enclosingElement, initializers.head); |
| 90 } |
| 91 return null; |
| 92 } |
| 93 |
| 94 void resolveRedirectingConstructor(InitializerResolver resolver, |
| 95 Node node, |
| 96 FunctionElement constructor, |
| 97 FunctionElement redirection) { |
| 98 Set<FunctionElement> seen = new Set<FunctionElement>(); |
| 99 seen.add(constructor); |
| 100 while (redirection !== null) { |
| 101 if (seen.contains(redirection)) { |
| 102 resolver.visitor.error(node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE); |
| 103 return; |
| 104 } |
| 105 seen.add(redirection); |
| 106 redirection = resolveConstructorRedirection(redirection); |
| 107 } |
| 108 } |
| 109 |
| 60 TreeElements resolveMethodElement(FunctionElement element) { | 110 TreeElements resolveMethodElement(FunctionElement element) { |
| 61 if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR && | 111 if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR && |
| 62 constructorElements[element] !== null) { | 112 constructorElements[element] !== null) { |
| 63 return constructorElements[element]; | 113 return constructorElements[element]; |
| 64 } | 114 } |
| 65 FunctionExpression tree = element.parseNode(compiler); | 115 FunctionExpression tree = element.parseNode(compiler); |
| 66 ResolverVisitor visitor = new ResolverVisitor(compiler, element); | 116 ResolverVisitor visitor = new ResolverVisitor(compiler, element); |
| 67 visitor.useElement(tree, element); | 117 visitor.useElement(tree, element); |
| 68 visitor.setupFunction(tree, element); | 118 visitor.setupFunction(tree, element); |
| 69 | 119 |
| 70 if (tree.initializers != null) { | 120 if (element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR_BODY && |
| 71 new InitializerResolver(visitor, element).resolveInitializers(tree); | 121 tree.initializers != null) { |
| 122 if (element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR) { |
| 123 error(tree, MessageKind.FUNCTION_WITH_INITIALIZER); |
| 124 } |
| 125 InitializerResolver resolver = new InitializerResolver(visitor); |
| 126 FunctionElement redirection = resolver.resolveInitializers(element, tree); |
| 127 if (redirection !== null) { |
| 128 resolveRedirectingConstructor(resolver, tree, element, redirection); |
| 129 } |
| 72 } | 130 } |
| 73 visitor.visit(tree.body); | 131 visitor.visit(tree.body); |
| 74 | 132 |
| 75 // Resolve the type annotations encountered in the method. | 133 // Resolve the type annotations encountered in the method. |
| 76 Link<ClassElement> newResolvedClasses = const EmptyLink<ClassElement>(); | 134 Link<ClassElement> newResolvedClasses = const EmptyLink<ClassElement>(); |
| 77 while (!toResolve.isEmpty()) { | 135 while (!toResolve.isEmpty()) { |
| 78 ClassElement classElement = toResolve.removeFirst(); | 136 ClassElement classElement = toResolve.removeFirst(); |
| 79 if (!classElement.isResolved) { | 137 if (!classElement.isResolved) { |
| 80 classElement.resolve(compiler); | 138 classElement.resolve(compiler); |
| 81 } | 139 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 // TODO(karlklose): check if type arguments match, if a classelement occurs | 191 // TODO(karlklose): check if type arguments match, if a classelement occurs |
| 134 // more than once in the supertypes. | 192 // more than once in the supertypes. |
| 135 if (classElement.allSupertypes !== null) return; | 193 if (classElement.allSupertypes !== null) return; |
| 136 final Type supertype = classElement.supertype; | 194 final Type supertype = classElement.supertype; |
| 137 if (seen.contains(classElement)) { | 195 if (seen.contains(classElement)) { |
| 138 error(classElement.parseNode(compiler), | 196 error(classElement.parseNode(compiler), |
| 139 MessageKind.CYCLIC_CLASS_HIERARCHY, | 197 MessageKind.CYCLIC_CLASS_HIERARCHY, |
| 140 [classElement.name]); | 198 [classElement.name]); |
| 141 classElement.allSupertypes = const EmptyLink<Type>(); | 199 classElement.allSupertypes = const EmptyLink<Type>(); |
| 142 } else if (supertype != null) { | 200 } else if (supertype != null) { |
| 143 Type supertype = classElement.supertype; | |
| 144 seen.add(classElement); | 201 seen.add(classElement); |
| 145 Link<Type> superSupertypes = | 202 Link<Type> superSupertypes = |
| 146 getOrCalculateAllSupertypes(supertype.element, seen); | 203 getOrCalculateAllSupertypes(supertype.element, seen); |
| 147 Link<Type> supertypes = new Link<Type>(supertype, superSupertypes); | 204 Link<Type> supertypes = new Link<Type>(supertype, superSupertypes); |
| 148 for (Link<Type> interfaces = classElement.interfaces; | 205 for (Link<Type> interfaces = classElement.interfaces; |
| 149 !interfaces.isEmpty(); | 206 !interfaces.isEmpty(); |
| 150 interfaces = interfaces.tail) { | 207 interfaces = interfaces.tail) { |
| 151 Element element = interfaces.head.element; | 208 Element element = interfaces.head.element; |
| 152 Link<Type> interfaceSupertypes = | 209 Link<Type> interfaceSupertypes = |
| 153 getOrCalculateAllSupertypes(element, seen); | 210 getOrCalculateAllSupertypes(element, seen); |
| 154 supertypes = supertypes.reversePrependAll(interfaceSupertypes); | 211 supertypes = supertypes.reversePrependAll(interfaceSupertypes); |
| 155 } | 212 } |
| 156 seen.remove(classElement); | 213 seen.remove(classElement); |
| 157 classElement.allSupertypes = supertypes; | 214 classElement.allSupertypes = supertypes; |
| 158 } else { | 215 } else { |
| 159 classElement.allSupertypes = const EmptyLink<Type>(); | 216 classElement.allSupertypes = const EmptyLink<Type>(); |
| 160 } | 217 } |
| 161 } | 218 } |
| 162 | 219 |
| 163 error(Node node, MessageKind kind, [arguments = const []]) { | 220 error(Node node, MessageKind kind, [arguments = const []]) { |
| 164 ResolutionError error = new ResolutionError(kind, arguments); | 221 ResolutionError message = new ResolutionError(kind, arguments); |
| 165 compiler.reportError(node, error); | 222 compiler.reportError(node, message); |
| 166 } | 223 } |
| 167 } | 224 } |
| 168 | 225 |
| 169 class InitializerResolver { | 226 class InitializerResolver { |
| 170 final ResolverVisitor visitor; | 227 final ResolverVisitor visitor; |
| 171 final FunctionElement constructor; | |
| 172 final Map<SourceString, Node> initialized; | 228 final Map<SourceString, Node> initialized; |
| 173 Link<Node> initializers; | 229 Link<Node> initializers; |
| 174 bool hasSuper; | 230 bool hasSuper; |
| 175 | 231 |
| 176 InitializerResolver(this.visitor, this.constructor) | 232 InitializerResolver(this.visitor) |
| 177 : initialized = new Map<SourceString, Node>(), hasSuper = false; | 233 : initialized = new Map<SourceString, Node>(), hasSuper = false; |
| 178 | 234 |
| 179 error(Node node, MessageKind kind, [arguments = const []]) { | 235 error(Node node, MessageKind kind, [arguments = const []]) { |
| 180 visitor.error(node, kind, arguments); | 236 visitor.error(node, kind, arguments); |
| 181 } | 237 } |
| 182 | 238 |
| 183 warning(Node node, MessageKind kind, [arguments = const []]) { | 239 warning(Node node, MessageKind kind, [arguments = const []]) { |
| 184 visitor.warning(node, kind, arguments); | 240 visitor.warning(node, kind, arguments); |
| 185 } | 241 } |
| 186 | 242 |
| 187 bool isFieldInitializer(SendSet node) { | 243 bool isFieldInitializer(SendSet node) { |
| 188 if (node.selector.asIdentifier() == null) return false; | 244 if (node.selector.asIdentifier() == null) return false; |
| 189 if (node.receiver == null) return true; | 245 if (node.receiver == null) return true; |
| 190 if (node.receiver.asIdentifier() == null) return false; | 246 if (node.receiver.asIdentifier() == null) return false; |
| 191 return node.receiver.asIdentifier().isThis(); | 247 return node.receiver.asIdentifier().isThis(); |
| 192 } | 248 } |
| 193 | 249 |
| 194 void resolveFieldInitializer(SendSet init) { | 250 void resolveFieldInitializer(FunctionElement constructor, SendSet init) { |
| 195 // init is of the form [this.]field = value. | 251 // init is of the form [this.]field = value. |
| 196 final Node selector = init.selector; | 252 final Node selector = init.selector; |
| 197 final SourceString name = selector.asIdentifier().source; | 253 final SourceString name = selector.asIdentifier().source; |
| 198 // Lookup target field. | 254 // Lookup target field. |
| 199 Element target; | 255 Element target; |
| 200 if (isFieldInitializer(init)) { | 256 if (isFieldInitializer(init)) { |
| 201 final ClassElement classElement = constructor.enclosingElement; | 257 final ClassElement classElement = constructor.enclosingElement; |
| 202 target = classElement.lookupLocalMember(name); | 258 target = classElement.lookupLocalMember(name); |
| 203 if (target === null) { | 259 if (target === null) { |
| 204 error(selector, MessageKind.CANNOT_RESOLVE, [name]); | 260 error(selector, MessageKind.CANNOT_RESOLVE, [name]); |
| 205 } else if (target.kind != ElementKind.FIELD) { | 261 } else if (target.kind != ElementKind.FIELD) { |
| 206 error(selector, MessageKind.NOT_A_FIELD, [name]); | 262 error(selector, MessageKind.NOT_A_FIELD, [name]); |
| 207 } else if (!target.isInstanceMember()) { | 263 } else if (!target.isInstanceMember()) { |
| 208 error(selector, MessageKind.INIT_STATIC_FIELD, [name]); | 264 error(selector, MessageKind.INIT_STATIC_FIELD, [name]); |
| 209 } | 265 } |
| 210 } else { | 266 } else { |
| 211 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); | 267 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); |
| 212 } | 268 } |
| 213 visitor.useElement(init, target); | 269 visitor.useElement(init, target); |
| 214 // Check for duplicate initializers. | 270 // Check for duplicate initializers. |
| 215 if (initialized.containsKey(name)) { | 271 if (initialized.containsKey(name)) { |
| 216 error(init, MessageKind.DUPLICATE_INITIALIZER, [name]); | 272 error(init, MessageKind.DUPLICATE_INITIALIZER, [name]); |
| 217 warning(initialized[name], MessageKind.ALREADY_INITIALIZED, [name]); | 273 warning(initialized[name], MessageKind.ALREADY_INITIALIZED, [name]); |
| 218 } | 274 } |
| 219 initialized[name] = init; | 275 initialized[name] = init; |
| 220 // Resolve initializing value. | 276 // Resolve initializing value. |
| 221 visitor.visitInStaticContext(init.arguments.head); | 277 visitor.visitInStaticContext(init.arguments.head); |
| 222 } | 278 } |
| 223 | 279 |
| 224 SourceString getConstructorName(Send node) { | 280 Element resolveSuperOrThis(FunctionElement constructor, |
| 225 if (node.receiver !== null) { | 281 FunctionExpression functionNode, |
| 226 return node.selector.asIdentifier().source; | 282 Send call) { |
| 227 } else { | |
| 228 return const SourceString(''); | |
| 229 } | |
| 230 } | |
| 231 | |
| 232 void resolveSuperOrThis(Send call) { | |
| 233 noConstructor(e) { | 283 noConstructor(e) { |
| 234 if (e !== null) error(call, MessageKind.NO_CONSTRUCTOR, [e.name, e.kind]); | 284 if (e !== null) error(call, MessageKind.NO_CONSTRUCTOR, [e.name, e.kind]); |
| 235 } | 285 } |
| 236 | 286 |
| 237 ClassElement lookupTarget = constructor.enclosingElement; | 287 ClassElement lookupTarget = constructor.enclosingElement; |
| 238 bool validTarget = true; | 288 bool validTarget = true; |
| 289 FunctionElement result; |
| 239 if (Initializers.isSuperConstructorCall(call)) { | 290 if (Initializers.isSuperConstructorCall(call)) { |
| 240 // Check for invalid initializers. | 291 // Check for invalid initializers. |
| 241 if (hasSuper) { | 292 if (hasSuper) { |
| 242 error(call, MessageKind.DUPLICATE_SUPER_INITIALIZER); | 293 error(call, MessageKind.DUPLICATE_SUPER_INITIALIZER); |
| 243 } | 294 } |
| 244 hasSuper = true; | 295 hasSuper = true; |
| 245 // Calculate correct lookup target and constructor name. | 296 // Calculate correct lookup target and constructor name. |
| 246 if (lookupTarget.name == Types.OBJECT) { | 297 if (lookupTarget.name == Types.OBJECT) { |
| 247 error(call, MessageKind.SUPER_INITIALIZER_IN_OBJECT); | 298 error(call, MessageKind.SUPER_INITIALIZER_IN_OBJECT); |
| 248 } else { | 299 } else { |
| 249 lookupTarget = lookupTarget.supertype.element; | 300 lookupTarget = lookupTarget.supertype.element; |
| 250 } | 301 } |
| 251 } else if (Initializers.isConstructorRedirect(call)) { | 302 } else if (Initializers.isConstructorRedirect(call)) { |
| 303 // Check that there is no body (Language specification 7.5.1). |
| 304 if (functionNode.hasBody()) { |
| 305 error(functionNode, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY); |
| 306 } |
| 252 // Check that there are no other initializers. | 307 // Check that there are no other initializers. |
| 253 if (!initializers.tail.isEmpty()) { | 308 if (!initializers.tail.isEmpty()) { |
| 254 error(call, MessageKind.REDIRECTING_CTOR_HAS_INITIALIZER); | 309 error(call, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER); |
| 255 } | 310 } |
| 256 } else { | 311 } else { |
| 257 visitor.error(call, MessageKind.CONSTRUCTOR_CALL_EXPECTED); | 312 visitor.error(call, MessageKind.CONSTRUCTOR_CALL_EXPECTED); |
| 258 validTarget = false; | 313 validTarget = false; |
| 259 } | 314 } |
| 260 | 315 |
| 261 if (validTarget) { | 316 if (validTarget) { |
| 262 final SourceString className = lookupTarget.name; | 317 ResolverTask resolver = visitor.compiler.resolver; |
| 263 final SourceString constructorName = getConstructorName(call); | 318 result = resolver.lookupConstructor(lookupTarget, call); |
| 264 FunctionElement target = | 319 if (result === null) { |
| 265 lookupTarget.lookupConstructor(className, constructorName, | 320 SourceString constructorName = resolver.getConstructorName(call); |
| 266 noConstructor); | 321 SourceString className = lookupTarget.name; |
| 267 if (target === null && call.arguments.isEmpty()) { | |
| 268 target = lookupTarget.getSynthesizedConstructor(); | |
| 269 } | |
| 270 if (target === null) { | |
| 271 String name = (constructorName === const SourceString('')) | 322 String name = (constructorName === const SourceString('')) |
| 272 ? className.stringValue | 323 ? className.stringValue |
| 273 : "$className.$constructorName"; | 324 : "$className.$constructorName"; |
| 274 error(call, MessageKind.CANNOT_RESOLVE_CONSTRUCTOR, [name]); | 325 error(call, MessageKind.CANNOT_RESOLVE_CONSTRUCTOR, [name]); |
| 275 } else { | 326 } else { |
| 276 final Compiler compiler = visitor.compiler; | 327 final Compiler compiler = visitor.compiler; |
| 277 // TODO(karlklose): support optional arguments. | 328 // TODO(karlklose): support optional arguments. |
| 278 if (target.parameterCount(compiler) != call.argumentCount()) { | 329 if (result.parameterCount(compiler) != call.argumentCount()) { |
| 279 error(call, MessageKind.NO_MATCHING_CONSTRUCTOR); | 330 error(call, MessageKind.NO_MATCHING_CONSTRUCTOR); |
| 280 } | 331 } |
| 281 } | 332 } |
| 282 visitor.useElement(call, target); | 333 visitor.useElement(call, result); |
| 283 } | 334 } |
| 284 // Resolve the arguments of the call. | 335 // Resolve the arguments of the call. |
| 285 for (Link<Node> arguments = call.arguments; | 336 for (Link<Node> arguments = call.arguments; |
| 286 !arguments.isEmpty(); | 337 !arguments.isEmpty(); |
| 287 arguments = arguments.tail) { | 338 arguments = arguments.tail) { |
| 288 visitor.visitInStaticContext(arguments.head); | 339 visitor.visitInStaticContext(arguments.head); |
| 289 } | 340 } |
| 341 return result; |
| 290 } | 342 } |
| 291 | 343 |
| 292 void resolveInitializers(FunctionExpression node) { | 344 FunctionElement resolveRedirection(FunctionElement constructor, |
| 293 if (node.initializers === null) return; | 345 FunctionExpression functionNode) { |
| 294 initializers = node.initializers.nodes; | 346 if (functionNode.initializers === null) return null; |
| 295 Compiler compiler = visitor.compiler; | 347 Link<Node> link = functionNode.initializers.nodes; |
| 348 if (!link.isEmpty() && Initializers.isConstructorRedirect(link.head)) { |
| 349 return resolveSuperOrThis(constructor, functionNode, link.head); |
| 350 } |
| 351 return null; |
| 352 } |
| 353 |
| 354 /** |
| 355 * Resolve all initializers of this constructor. In the case of a redirecting |
| 356 * constructor, the resolved constructor's function element is returned. |
| 357 */ |
| 358 FunctionElement resolveInitializers(FunctionElement constructor, |
| 359 FunctionExpression functionNode) { |
| 360 if (functionNode.initializers === null) return null; |
| 361 initializers = functionNode.initializers.nodes; |
| 362 FunctionElement result; |
| 296 for (Link<Node> link = initializers; | 363 for (Link<Node> link = initializers; |
| 297 !link.isEmpty(); | 364 !link.isEmpty(); |
| 298 link = link.tail) { | 365 link = link.tail) { |
| 299 if (link.head.asSendSet() != null) { | 366 if (link.head.asSendSet() != null) { |
| 300 final SendSet init = link.head.asSendSet(); | 367 final SendSet init = link.head.asSendSet(); |
| 301 resolveFieldInitializer(init); | 368 resolveFieldInitializer(constructor, init); |
| 302 } else if (link.head.asSend() !== null) { | 369 } else if (link.head.asSend() !== null) { |
| 303 final Send call = link.head.asSend(); | 370 final Send call = link.head.asSend(); |
| 304 resolveSuperOrThis(call); | 371 result = resolveSuperOrThis(constructor, functionNode, call); |
| 305 } else { | 372 } else { |
| 306 visitor.compiler.cancel('internal error: invalid initializer', | 373 error(link.head, MessageKind.INVALID_INITIALIZER); |
| 307 node: link.head); | |
| 308 } | 374 } |
| 309 } | 375 } |
| 376 return result; |
| 310 } | 377 } |
| 311 } | 378 } |
| 312 | 379 |
| 313 class CommonResolverVisitor<R> extends AbstractVisitor<Element> { | 380 class CommonResolverVisitor<R> extends AbstractVisitor<R> { |
| 314 final Compiler compiler; | 381 final Compiler compiler; |
| 315 | 382 |
| 316 CommonResolverVisitor(Compiler this.compiler); | 383 CommonResolverVisitor(Compiler this.compiler); |
| 317 | 384 |
| 318 R visitNode(Node node) { | 385 R visitNode(Node node) { |
| 319 cancel(node, 'internal error'); | 386 cancel(node, 'internal error'); |
| 320 } | 387 } |
| 321 | 388 |
| 322 /** Convenience method for visiting nodes that may be null. */ | 389 /** Convenience method for visiting nodes that may be null. */ |
| 323 R visit(Node node) => (node == null) ? null : node.accept(this); | 390 R visit(Node node) => (node == null) ? null : node.accept(this); |
| 324 | 391 |
| 325 void error(Node node, MessageKind kind, [arguments = const []]) { | 392 void error(Node node, MessageKind kind, [arguments = const []]) { |
| 326 ResolutionError error = new ResolutionError(kind, arguments); | 393 ResolutionError message = new ResolutionError(kind, arguments); |
| 327 compiler.reportError(node, error); | 394 compiler.reportError(node, message); |
| 328 } | 395 } |
| 329 | 396 |
| 330 void warning(Node node, MessageKind kind, [arguments = const []]) { | 397 void warning(Node node, MessageKind kind, [arguments = const []]) { |
| 331 ResolutionWarning warning = new ResolutionWarning(kind, arguments); | 398 ResolutionWarning message = new ResolutionWarning(kind, arguments); |
| 332 compiler.reportWarning(node, warning); | 399 compiler.reportWarning(node, message); |
| 333 } | 400 } |
| 334 | 401 |
| 335 void cancel(Node node, String message) { | 402 void cancel(Node node, String message) { |
| 336 compiler.cancel(message, node: node); | 403 compiler.cancel(message, node: node); |
| 337 } | 404 } |
| 338 | 405 |
| 339 void internalError(Node node, String message) { | 406 void internalError(Node node, String message) { |
| 340 compiler.internalError(message, node: node); | 407 compiler.internalError(message, node: node); |
| 341 } | 408 } |
| 342 | 409 |
| (...skipping 948 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 class TopScope extends Scope { | 1358 class TopScope extends Scope { |
| 1292 LibraryElement get library() => element; | 1359 LibraryElement get library() => element; |
| 1293 | 1360 |
| 1294 TopScope(LibraryElement library) : super(null, library); | 1361 TopScope(LibraryElement library) : super(null, library); |
| 1295 Element lookup(SourceString name) => library.find(name); | 1362 Element lookup(SourceString name) => library.find(name); |
| 1296 | 1363 |
| 1297 Element add(Element element) { | 1364 Element add(Element element) { |
| 1298 throw "Cannot add an element in the top scope"; | 1365 throw "Cannot add an element in the top scope"; |
| 1299 } | 1366 } |
| 1300 } | 1367 } |
| OLD | NEW |