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

Side by Side Diff: frog/leg/resolver.dart

Issue 9616058: Implement parsing and resolving of type-variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix merge error. 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 compiler.internalError(message, node: node); 403 compiler.internalError(message, node: node);
404 } 404 }
405 405
406 void unimplemented(Node node, String message) { 406 void unimplemented(Node node, String message) {
407 compiler.unimplemented(message, node: node); 407 compiler.unimplemented(message, node: node);
408 } 408 }
409 } 409 }
410 410
411 interface LabelScope { 411 interface LabelScope {
412 LabelScope get outer(); 412 LabelScope get outer();
413 LabelElement lookup(String label); 413 LabelElement lookup(String label, [bool inStaticContext]);
ngeoffray 2012/03/15 11:47:40 Why would labels care about a static context?
karlklose 2012/03/16 14:58:47 Done, removed all the static context booleans.
414 } 414 }
415 415
416 class LabeledStatementLabelScope implements LabelScope { 416 class LabeledStatementLabelScope implements LabelScope {
417 final LabelScope outer; 417 final LabelScope outer;
418 final LabelElement label; 418 final LabelElement label;
419 LabeledStatementLabelScope(this.outer, this.label); 419 LabeledStatementLabelScope(this.outer, this.label);
420 LabelElement lookup(String labelName) { 420 LabelElement lookup(String labelName, [bool inStaticContext = false]) {
421 if (this.label.labelName == labelName) return label; 421 if (this.label.labelName == labelName) return label;
422 return outer.lookup(labelName); 422 return outer.lookup(labelName, inStaticContext);
423 } 423 }
424 } 424 }
425 425
426 class SwitchLabelScope implements LabelScope { 426 class SwitchLabelScope implements LabelScope {
427 final LabelScope outer; 427 final LabelScope outer;
428 final Map<String, LabelElement> caseLabels; 428 final Map<String, LabelElement> caseLabels;
429 429
430 SwitchLabelScope(this.outer, this.caseLabels); 430 SwitchLabelScope(this.outer, this.caseLabels);
431 431
432 LabelElement lookup(String labelName) { 432 LabelElement lookup(String labelName, [bool inStaticContext = false]) {
433 LabelElement result = caseLabels[labelName]; 433 LabelElement result = caseLabels[labelName];
434 if (result !== null) return result; 434 if (result !== null) return result;
435 return outer.lookup(labelName); 435 return outer.lookup(labelName, inStaticContext);
436 } 436 }
437 } 437 }
438 438
439 class EmptyLabelScope implements LabelScope { 439 class EmptyLabelScope implements LabelScope {
440 const EmptyLabelScope(); 440 const EmptyLabelScope();
441 LabelElement lookup(String label) => null; 441 LabelElement lookup(String label, [bool inStaticContext = false]) => null;
442 LabelScope get outer() { 442 LabelScope get outer() {
443 throw 'internal error: empty label scope has no outer'; 443 throw 'internal error: empty label scope has no outer';
444 } 444 }
445 } 445 }
446 446
447 class StatementScope { 447 class StatementScope {
448 LabelScope labels; 448 LabelScope labels;
449 Link<TargetElement> breakTargetStack; 449 Link<TargetElement> breakTargetStack;
450 Link<TargetElement> continueTargetStack; 450 Link<TargetElement> continueTargetStack;
451 // Used to provide different numbers to statements if one is inside the other. 451 // Used to provide different numbers to statements if one is inside the other.
452 // Can be used to make otherwise duplicate labels unique. 452 // Can be used to make otherwise duplicate labels unique.
453 int nestingLevel = 0; 453 int nestingLevel = 0;
454 454
455 StatementScope() 455 StatementScope()
456 : labels = const EmptyLabelScope(), 456 : labels = const EmptyLabelScope(),
457 breakTargetStack = const EmptyLink<TargetElement>(), 457 breakTargetStack = const EmptyLink<TargetElement>(),
458 continueTargetStack = const EmptyLink<TargetElement>(); 458 continueTargetStack = const EmptyLink<TargetElement>();
459 459
460 LabelElement lookupLabel(String label) => 460 LabelElement lookupLabel(String label, [bool inStaticContext = false]) {
461 labels.lookup(label); 461 return labels.lookup(label, inStaticContext);
462 462 }
463 TargetElement currentBreakTarget() => 463 TargetElement currentBreakTarget() =>
464 breakTargetStack.isEmpty() ? null : breakTargetStack.head; 464 breakTargetStack.isEmpty() ? null : breakTargetStack.head;
465 465
466 TargetElement currentContinueTarget() => 466 TargetElement currentContinueTarget() =>
467 continueTargetStack.isEmpty() ? null : continueTargetStack.head; 467 continueTargetStack.isEmpty() ? null : continueTargetStack.head;
468 468
469 void enterLabelScope(LabelElement element) { 469 void enterLabelScope(LabelElement element) {
470 labels = new LabeledStatementLabelScope(labels, element); 470 labels = new LabeledStatementLabelScope(labels, element);
471 nestingLevel++; 471 nestingLevel++;
472 } 472 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 inInstanceContext = element.isInstanceMember() 518 inInstanceContext = element.isInstanceMember()
519 || element.isGenerativeConstructor(), 519 || element.isGenerativeConstructor(),
520 this.context = element.isMember() 520 this.context = element.isMember()
521 ? new ClassScope(element.enclosingElement, element.getLibrary()) 521 ? new ClassScope(element.enclosingElement, element.getLibrary())
522 : new TopScope(element.getLibrary()), 522 : new TopScope(element.getLibrary()),
523 this.currentClass = element.isMember() ? element.enclosingElement : null, 523 this.currentClass = element.isMember() ? element.enclosingElement : null,
524 this.statementScope = new StatementScope(), 524 this.statementScope = new StatementScope(),
525 super(compiler); 525 super(compiler);
526 526
527 Element lookup(Node node, SourceString name) { 527 Element lookup(Node node, SourceString name) {
528 Element result = context.lookup(name); 528 Element result = context.lookup(name, !inInstanceContext);
529 if (!inInstanceContext && result != null && result.isInstanceMember()) { 529 if (!inInstanceContext && result != null && result.isInstanceMember()) {
530 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]); 530 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]);
531 } 531 }
532 return result; 532 return result;
533 } 533 }
534 534
535 // Create, or reuse an already created, statement element for a statement. 535 // Create, or reuse an already created, statement element for a statement.
536 TargetElement getOrCreateTargetElement(Node statement) { 536 TargetElement getOrCreateTargetElement(Node statement) {
537 TargetElement element = mapping[statement]; 537 TargetElement element = mapping[statement];
538 if (element === null) { 538 if (element === null) {
539 element = new TargetElement(statement, 539 element = new TargetElement(statement,
540 statementScope.nestingLevel, 540 statementScope.nestingLevel,
541 enclosingElement); 541 enclosingElement);
542 mapping[statement] = element; 542 mapping[statement] = element;
543 } 543 }
544 return element; 544 return element;
545 } 545 }
546 546
547 inStaticContext(action()) { 547 inStaticContext(action()) {
548 bool wasInstanceContext = inInstanceContext; 548 bool wasInstanceContext = inInstanceContext;
549 inInstanceContext = false; 549 inInstanceContext = false;
550 action(); 550 var result = action();
551 inInstanceContext = wasInstanceContext; 551 inInstanceContext = wasInstanceContext;
552 return result;
552 } 553 }
553 554
554 visitInStaticContext(Node node) { 555 visitInStaticContext(Node node) {
555 inStaticContext(() => visit(node)); 556 inStaticContext(() => visit(node));
556 } 557 }
557 558
558 Element visitIdentifier(Identifier node) { 559 Element visitIdentifier(Identifier node) {
559 if (node.isThis()) { 560 if (node.isThis()) {
560 if (!inInstanceContext) { 561 if (!inInstanceContext) {
561 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]); 562 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]);
(...skipping 24 matching lines...) Expand all
586 if (node.typeName.asSend() !== null) { 587 if (node.typeName.asSend() !== null) {
587 // In new and const expressions, the type name can be a Send to 588 // In new and const expressions, the type name can be a Send to
588 // denote named constructors or library prefixes. 589 // denote named constructors or library prefixes.
589 Send send = node.typeName.asSend(); 590 Send send = node.typeName.asSend();
590 className = send.receiver.asIdentifier().source; 591 className = send.receiver.asIdentifier().source;
591 } else { 592 } else {
592 className = node.typeName.asIdentifier().source; 593 className = node.typeName.asIdentifier().source;
593 } 594 }
594 if (className == const SourceString('var')) return null; 595 if (className == const SourceString('var')) return null;
595 if (className == const SourceString('void')) return null; 596 if (className == const SourceString('void')) return null;
596 Element element = context.lookup(className); 597 Element element = context.lookup(className, !inInstanceContext);
597 if (element === null) { 598 if (element === null) {
598 if (typeRequired) { 599 if (typeRequired) {
599 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [className]); 600 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [className]);
600 } else { 601 } else {
601 warning(node, MessageKind.CANNOT_RESOLVE_TYPE, [className]); 602 warning(node, MessageKind.CANNOT_RESOLVE_TYPE, [className]);
602 } 603 }
603 } else if (!element.impliesType()) { 604 } else if (!element.impliesType()) {
604 if (typeRequired) { 605 if (typeRequired) {
605 error(node, MessageKind.NOT_A_TYPE, [className]); 606 error(node, MessageKind.NOT_A_TYPE, [className]);
606 } else { 607 } else {
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 // TODO(ngeoffray): resolution error with wrong number of 950 // TODO(ngeoffray): resolution error with wrong number of
950 // parameters. We cannot do this rigth now because of the 951 // parameters. We cannot do this rigth now because of the
951 // List constructor. 952 // List constructor.
952 } 953 }
953 useElement(node.send, constructor); 954 useElement(node.send, constructor);
954 return null; 955 return null;
955 } 956 }
956 957
957 FunctionElement resolveConstructor(NewExpression node) { 958 FunctionElement resolveConstructor(NewExpression node) {
958 FunctionElement constructor = 959 FunctionElement constructor =
959 node.accept(new ConstructorResolver(compiler, this)); 960 node.accept(new ConstructorResolver(compiler, this));
960 if (constructor === null) { 961 if (constructor === null) {
961 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); 962 Element resolved = resolveTypeRequired(node.send.selector);
963 if (resolved !== null && resolved.kind === ElementKind.TYPE_VARIABLE) {
964 error(node, WarningKind.TYPE_VARIABLE_AS_CONSTRUCTOR);
965 return null;
966 } else {
967 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]);
968 }
962 } 969 }
963 return constructor; 970 return constructor;
964 } 971 }
965 972
966 Element resolveTypeRequired(Node node) { 973 Element resolveTypeRequired(Node node) {
967 bool old = typeRequired; 974 bool old = typeRequired;
968 typeRequired = true; 975 typeRequired = true;
969 Element element = visit(node); 976 Element element = visit(node);
970 typeRequired = old; 977 typeRequired = old;
971 return element; 978 return element;
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 visitIn(node.block, scope); 1196 visitIn(node.block, scope);
1190 } 1197 }
1191 1198
1192 visitTypedef(Typedef node) { 1199 visitTypedef(Typedef node) {
1193 unimplemented(node, 'typedef'); 1200 unimplemented(node, 'typedef');
1194 } 1201 }
1195 } 1202 }
1196 1203
1197 class ClassResolverVisitor extends CommonResolverVisitor<Type> { 1204 class ClassResolverVisitor extends CommonResolverVisitor<Type> {
1198 Scope context; 1205 Scope context;
1206 ClassElement classElement;
1199 1207
1200 ClassResolverVisitor(Compiler compiler, LibraryElement library) 1208 ClassResolverVisitor(Compiler compiler, LibraryElement library)
1201 : context = new TopScope(library), 1209 : context = new TopScope(library),
1202 super(compiler); 1210 super(compiler);
1203 1211
1204 Type visitClassNode(ClassNode node) { 1212 Type visitClassNode(ClassNode node) {
1205 ClassElement element = context.lookup(node.name.source); 1213 classElement = context.lookup(node.name.source);
1206 compiler.ensure(element !== null); 1214 compiler.ensure(classElement !== null);
1207 compiler.ensure(!element.isResolved); 1215 compiler.ensure(!classElement.isResolved);
1208 element.supertype = visit(node.superclass); 1216 final Link<TypeVariable> parameters =
1209 if (element.name != Types.OBJECT && element.supertype === null) { 1217 node.typeParameters !== null ? node.typeParameters.nodes
1218 : const EmptyLink<TypeVariable>();
1219 // Create types and elements for type variable.
1220 for (Link<TypeVariable> link = parameters;
1221 !link.isEmpty();
1222 link = link.tail) {
1223 TypeVariable typeNode = link.head;
1224 SourceString variableName = typeNode.name.source;
1225 TypeVariableType variableType = new TypeVariableType(variableName);
1226 TypeVariableElement variableElement =
1227 new TypeVariableElement(variableName, classElement, node,
1228 variableType);
1229 variableType.element = variableElement;
1230 classElement.typeParameters[variableName] = variableElement;
1231 context = new TypeVariableScope(context, variableElement);
1232 }
1233 // Resolve the bounds of type variables.
1234 for (Link<TypeVariable> link = parameters;
1235 !link.isEmpty();
1236 link = link.tail) {
1237 TypeVariable typeNode = link.head;
1238 SourceString variableName = typeNode.name.source;
1239 TypeVariableElement variableElement =
1240 classElement.typeParameters[variableName];
1241 if (typeNode.bound !== null) {
1242 Type boundType = visit(typeNode.bound);
1243 if (boundType !== null && boundType.element == variableElement) {
1244 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE,
1245 [variableElement.name]);
1246 } else if (boundType !== null) {
1247 variableElement.bound = boundType;
1248 } else {
1249 variableElement.bound = compiler.objectClass.computeType(compiler);
1250 }
1251 }
1252 }
1253 // Find super type.
1254 Type supertype = visit(node.superclass);
1255 if (supertype !== null && supertype.element.impliesType()) {
1256 classElement.supertype = supertype;
1257 } else if (supertype !== null) {
1258 error(node.superclass, MessageKind.TYPE_NAME_EXPECTED);
1259 }
1260 if (classElement.name != Types.OBJECT && classElement.supertype === null) {
1210 ClassElement objectElement = context.lookup(Types.OBJECT); 1261 ClassElement objectElement = context.lookup(Types.OBJECT);
1211 if (objectElement !== null && !objectElement.isResolved) { 1262 if (objectElement !== null && !objectElement.isResolved) {
1212 compiler.resolver.toResolve.add(objectElement); 1263 compiler.resolver.toResolve.add(objectElement);
1213 } else if (objectElement === null){ 1264 } else if (objectElement === null){
1214 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [Types.OBJECT]); 1265 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [Types.OBJECT]);
1215 } 1266 }
1216 element.supertype = new SimpleType(Types.OBJECT, objectElement); 1267 classElement.supertype = new SimpleType(Types.OBJECT, objectElement);
1217 } 1268 }
1218 if (node.defaultClause !== null) { 1269 if (node.defaultClause !== null) {
1219 element.defaultClass = visit(node.defaultClause.nodes.head); 1270 classElement.defaultClass = visit(node.defaultClause);
1220 } 1271 }
1221 for (Link<Node> link = node.interfaces.nodes; 1272 for (Link<Node> link = node.interfaces.nodes;
1222 !link.isEmpty(); 1273 !link.isEmpty();
1223 link = link.tail) { 1274 link = link.tail) {
1224 element.interfaces = element.interfaces.prepend(visit(link.head)); 1275 Type interfaceType = visit(link.head);
1276 if (interfaceType !== null && interfaceType.element.impliesType()) {
ngeoffray 2012/03/15 11:47:40 IMO interfaceType.element.impliesType should alway
karlklose 2012/03/16 14:58:47 It could be a type variable, which is illegal.
1277 classElement.interfaces =
1278 classElement.interfaces.prepend(interfaceType);
1279 } else {
1280 error(link.head, MessageKind.TYPE_NAME_EXPECTED);
1281 }
1225 } 1282 }
1226 calculateAllSupertypes(element, new Set<ClassElement>()); 1283 calculateAllSupertypes(classElement, new Set<ClassElement>());
1227 addDefaultConstructorIfNeeded(element); 1284 addDefaultConstructorIfNeeded(classElement);
1228 return element.computeType(compiler); 1285 return classElement.computeType(compiler);
1229 } 1286 }
1230 1287
1231 Type visitTypeAnnotation(TypeAnnotation node) { 1288 Type visitTypeAnnotation(TypeAnnotation node) {
1232 return visit(node.typeName); 1289 return visit(node.typeName);
1233 } 1290 }
1234 1291
1292 Type visitTypeVariable(TypeVariable node) {
ngeoffray 2012/03/15 11:47:40 Is that really necessary? And it's not obvious tha
karlklose 2012/03/16 14:58:47 Done, removed.
1293 if (node.bound === null) {
1294 return compiler.objectClass;
1295 }
1296 return visit(node.bound);
1297 }
1298
1235 Type visitIdentifier(Identifier node) { 1299 Type visitIdentifier(Identifier node) {
1236 Element element = context.lookup(node.source); 1300 Element element = context.lookup(node.source);
1237 if (element === null) { 1301 if (element === null) {
1238 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); 1302 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]);
1239 } else if (!element.impliesType()) { 1303 return null;
1304 } else if (!element.impliesType() && !element.isTypeVariable()) {
1240 error(node, MessageKind.NOT_A_TYPE, [node]); 1305 error(node, MessageKind.NOT_A_TYPE, [node]);
1306 return null;
1241 } else { 1307 } else {
1242 if (element.isClass()) { 1308 if (element.isClass()) {
1243 compiler.resolver.toResolve.add(element); 1309 compiler.resolver.toResolve.add(element);
1244 } 1310 }
1245 // TODO(ngeoffray): Use type variables. 1311 if (element.isTypeVariable()) {
1246 return element.computeType(compiler); 1312 TypeVariableElement variableElement = element;
1313 return variableElement.type;
1314 } else if (element.isTypedef()) {
1315 compiler.unimplemented('visitIdentifier for typedefs');
1316 } else {
1317 // TODO(ngeoffray): Use type variables.
ngeoffray 2012/03/15 11:47:40 I believe you can remove this TODO now.
karlklose 2012/03/16 14:58:47 Done.
1318 return element.computeType(compiler);
1319 }
1247 } 1320 }
1248 return null; 1321 return null;
1249 } 1322 }
1250 1323
1251 Type visitSend(Send node) { 1324 Type visitSend(Send node) {
1252 Identifier prefix = node.receiver.asIdentifier(); 1325 Identifier prefix = node.receiver.asIdentifier();
1253 if (prefix === null) { 1326 if (prefix === null) {
1254 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); 1327 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]);
1255 return null; 1328 return null;
1256 } 1329 }
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
1605 1678
1606 class Scope { 1679 class Scope {
1607 final Element element; 1680 final Element element;
1608 final Scope parent; 1681 final Scope parent;
1609 1682
1610 Scope(this.parent, this.element); 1683 Scope(this.parent, this.element);
1611 abstract Element add(Element element); 1684 abstract Element add(Element element);
1612 abstract Element lookup(SourceString name); 1685 abstract Element lookup(SourceString name);
1613 } 1686 }
1614 1687
1688 class TypeVariableScope extends Scope {
1689 TypeVariableScope(parent, element) : super(parent, element);
1690 Element add(Element element) {
1691 throw "Cannot add element to TypeVariableScope";
1692 }
1693 Element lookup(SourceString name, [bool inStaticContext = false]) {
1694 if (!inStaticContext && name == element.name) {
ahe 2012/03/15 11:17:33 I don't believe this is correct. The scope should
karlklose 2012/03/16 14:58:47 Done, removed.
1695 return element;
1696 }
1697 if (parent !== null) return parent.lookup(name);
1698 }
1699 }
1700
1615 class MethodScope extends Scope { 1701 class MethodScope extends Scope {
1616 final Map<SourceString, Element> elements; 1702 final Map<SourceString, Element> elements;
1617 1703
1618 MethodScope(Scope parent, Element element) 1704 MethodScope(Scope parent, Element element)
1619 : super(parent, element), this.elements = new Map<SourceString, Element>(); 1705 : super(parent, element), this.elements = new Map<SourceString, Element>();
1620 1706
1621 Element lookup(SourceString name) { 1707 Element lookup(SourceString name, [bool inStaticContext = false]) {
1622 Element element = elements[name]; 1708 Element element = elements[name];
1623 if (element !== null) return element; 1709 if (element !== null) return element;
1624 return parent.lookup(name); 1710 return parent.lookup(name, inStaticContext);
1625 } 1711 }
1626 1712
1627 Element add(Element element) { 1713 Element add(Element element) {
1628 if (elements.containsKey(element.name)) return elements[element.name]; 1714 if (elements.containsKey(element.name)) return elements[element.name];
1629 elements[element.name] = element; 1715 elements[element.name] = element;
1630 return element; 1716 return element;
1631 } 1717 }
1632 } 1718 }
1633 1719
1634 class BlockScope extends MethodScope { 1720 class BlockScope extends MethodScope {
1635 BlockScope(Scope parent) : super(parent, parent.element); 1721 BlockScope(Scope parent) : super(parent, parent.element);
1636 } 1722 }
1637 1723
1638 class ClassScope extends Scope { 1724 class ClassScope extends Scope {
1639 ClassScope(ClassElement element, LibraryElement library) 1725 ClassScope(ClassElement element, LibraryElement library)
1640 : super(new TopScope(library), element); 1726 : super(new TopScope(library), element);
1641 1727
1642 Element lookup(SourceString name) { 1728 Element lookup(SourceString name, [bool inStaticContext = false]) {
1643 ClassElement cls = element; 1729 ClassElement cls = element;
1644 Element memberElement = cls.lookupLocalMember(name); 1730 Element result = cls.lookupLocalMember(name);
1645 if (memberElement != null) return memberElement; 1731 if (result !== null) return result;
1646 memberElement = parent.lookup(name); 1732 if (!inStaticContext) {
1647 if (memberElement != null) return memberElement; 1733 result = cls.lookupTypeParameter(name);
1734 }
1735 result = parent.lookup(name);
1736 if (result != null) return result;
1648 return cls.lookupSuperMember(name); 1737 return cls.lookupSuperMember(name);
1649 } 1738 }
1650 1739
1651 Element add(Element element) { 1740 Element add(Element element) {
1652 throw "Cannot add an element in a class scope"; 1741 throw "Cannot add an element in a class scope";
1653 } 1742 }
1654 } 1743 }
1655 1744
1656 class TopScope extends Scope { 1745 class TopScope extends Scope {
1657 LibraryElement get library() => element; 1746 LibraryElement get library() => element;
1658 1747
1659 TopScope(LibraryElement library) : super(null, library); 1748 TopScope(LibraryElement library) : super(null, library);
1660 Element lookup(SourceString name) => library.find(name); 1749 Element lookup(SourceString name, [bool inStaticContext = false]) {
1750 return library.find(name);
1751 }
1661 1752
1662 Element add(Element element) { 1753 Element add(Element element) {
1663 throw "Cannot add an element in the top scope"; 1754 throw "Cannot add an element in the top scope";
1664 } 1755 }
1665 } 1756 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698