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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/resolution/members.dart

Issue 12210010: Give correct warnings/errors on type expressions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased Created 7 years, 10 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
« no previous file with comments | « no previous file | tests/co19/co19-dart2js.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 part of resolution; 5 part of resolution;
6 6
7 abstract class TreeElements { 7 abstract class TreeElements {
8 Element operator[](Node node); 8 Element operator[](Node node);
9 Selector getSelector(Send send); 9 Selector getSelector(Send send);
10 DartType getType(Node node); 10 DartType getType(Node node);
(...skipping 1288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1299 nestingLevel++; 1299 nestingLevel++;
1300 } 1300 }
1301 1301
1302 void exitSwitch() { 1302 void exitSwitch() {
1303 nestingLevel--; 1303 nestingLevel--;
1304 breakTargetStack = breakTargetStack.tail; 1304 breakTargetStack = breakTargetStack.tail;
1305 labels = labels.outer; 1305 labels = labels.outer;
1306 } 1306 }
1307 } 1307 }
1308 1308
1309 /**
1310 * Interface for the predicates and methods needed by the [TypeResolver].
1311 */
1312 abstract class TypeResolverContext {
1313 Scope get scope;
1314 Element get enclosingElement;
1315
1316 void error(Node node, MessageKind kind, [Map arguments = const {}]);
1317 void warning(Node node, MessageKind kind, [Map arguments = const {}]);
1318 void useType(Node node, DartType type);
1319 }
1320
1309 class TypeResolver { 1321 class TypeResolver {
1310 final Compiler compiler; 1322 final Compiler compiler;
1323 TypeResolverContext context;
1324 bool isTypeExpression;
1311 1325
1312 TypeResolver(this.compiler); 1326 TypeResolver(this.compiler);
1313 1327
1328 Scope get scope => context.scope;
1329 Element get enclosingElement => context.enclosingElement;
1330
1331 void error(Node node, MessageKind kind, [Map arguments = const {}]) {
1332 context.error(node, kind, arguments);
1333 }
1334
1335 void warning(Node node, MessageKind kind, [Map arguments = const {}]) {
1336 context.warning(node, kind, arguments);
1337 }
1338
1339 void reportFailure(bool failureIsError,
1340 Node node, MessageKind kind, [Map arguments = const {}]) {
1341 if (failureIsError) {
1342 error(node, kind, arguments);
1343 } else {
1344 warning(node, kind, arguments);
1345 }
1346 }
1347
1348 void whenResolved(Node node, DartType type) {
1349 context.useType(node, type);
1350 }
1351
1314 Element resolveTypeName(Scope scope, 1352 Element resolveTypeName(Scope scope,
1315 SourceString prefixName, 1353 SourceString prefixName,
1316 Identifier typeName) { 1354 Identifier typeName) {
1317 if (prefixName != null) { 1355 if (prefixName != null) {
1318 Element e = scope.lookup(prefixName); 1356 Element e = scope.lookup(prefixName);
1319 if (e != null) { 1357 if (e != null) {
1320 if (identical(e.kind, ElementKind.PREFIX)) { 1358 if (identical(e.kind, ElementKind.PREFIX)) {
1321 // The receiver is a prefix. Lookup in the imported members. 1359 // The receiver is a prefix. Lookup in the imported members.
1322 PrefixElement prefix = e; 1360 PrefixElement prefix = e;
1323 return prefix.lookupLocalMember(typeName.source); 1361 return prefix.lookupLocalMember(typeName.source);
(...skipping 15 matching lines...) Expand all
1339 compiler.onDeprecatedFeature(typeName, 'Dynamic'); 1377 compiler.onDeprecatedFeature(typeName, 'Dynamic');
1340 return compiler.dynamicClass; 1378 return compiler.dynamicClass;
1341 } else if (identical(stringValue, 'dynamic')) { 1379 } else if (identical(stringValue, 'dynamic')) {
1342 return compiler.dynamicClass; 1380 return compiler.dynamicClass;
1343 } else { 1381 } else {
1344 return scope.lookup(typeName.source); 1382 return scope.lookup(typeName.source);
1345 } 1383 }
1346 } 1384 }
1347 } 1385 }
1348 1386
1349 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean 1387 DartType resolveTypeExpression(TypeAnnotation node) {
1350 // flags instead of closures. 1388 this.isTypeExpression = true;
1351 DartType resolveTypeAnnotation( 1389 return resolveTypeAnnotationInternal(node);
1352 TypeAnnotation node,
1353 Scope scope,
1354 Element enclosingElement,
1355 {onFailure(Node node, MessageKind kind, [Map arguments]),
1356 whenResolved(Node node, DartType type)}) {
1357 if (onFailure == null) {
1358 onFailure = (n, k, [arguments]) {};
1359 }
1360 if (whenResolved == null) {
1361 whenResolved = (n, t) {};
1362 }
1363 if (scope == null) {
1364 compiler.internalError('resolveTypeAnnotation: no scope specified');
1365 }
1366 return resolveTypeAnnotationInContext(scope, node, enclosingElement,
1367 onFailure, whenResolved);
1368 } 1390 }
1369 1391
1370 DartType resolveTypeAnnotationInContext(Scope scope, TypeAnnotation node, 1392 DartType resolveTypeAnnotation(TypeAnnotation node) {
1371 Element enclosingElement, 1393 this.isTypeExpression = false;
1372 onFailure, whenResolved) { 1394 return resolveTypeAnnotationInternal(node);
1395 }
1396
1397 DartType resolveTypeAnnotationInternal(TypeAnnotation node) {
1373 Identifier typeName; 1398 Identifier typeName;
1374 SourceString prefixName; 1399 SourceString prefixName;
1375 Send send = node.typeName.asSend(); 1400 Send send = node.typeName.asSend();
1376 if (send != null) { 1401 if (send != null) {
1377 // The type name is of the form [: prefix . identifier :]. 1402 // The type name is of the form [: prefix . identifier :].
1378 prefixName = send.receiver.asIdentifier().source; 1403 prefixName = send.receiver.asIdentifier().source;
1379 typeName = send.selector.asIdentifier(); 1404 typeName = send.selector.asIdentifier();
1380 } else { 1405 } else {
1381 typeName = node.typeName.asIdentifier(); 1406 typeName = node.typeName.asIdentifier();
1382 } 1407 }
1383 1408
1384 Element element = resolveTypeName(scope, prefixName, typeName); 1409 Element element = resolveTypeName(scope, prefixName, typeName);
1385 DartType type; 1410 DartType type;
1386 1411
1387 DartType reportFailureAndCreateType(MessageKind messageKind, 1412 DartType reportFailureAndCreateType(bool failureIsError,
1413 MessageKind messageKind,
1388 Map messageArguments) { 1414 Map messageArguments) {
1389 onFailure(node, messageKind, messageArguments); 1415 reportFailure(failureIsError, node, messageKind, messageArguments);
1390 var erroneousElement = new ErroneousElementX( 1416 var erroneousElement = new ErroneousElementX(
1391 messageKind, messageArguments, typeName.source, enclosingElement); 1417 messageKind, messageArguments, typeName.source, enclosingElement);
1392 var arguments = new LinkBuilder<DartType>(); 1418 var arguments = new LinkBuilder<DartType>();
1393 resolveTypeArguments( 1419 resolveTypeArguments(node, null, arguments);
1394 node, null, enclosingElement,
1395 scope, onFailure, whenResolved, arguments);
1396 return new MalformedType(erroneousElement, null, arguments.toLink()); 1420 return new MalformedType(erroneousElement, null, arguments.toLink());
1397 } 1421 }
1398 1422
1399 DartType checkNoTypeArguments(DartType type) { 1423 DartType checkNoTypeArguments(DartType type) {
1400 var arguments = new LinkBuilder<DartType>(); 1424 var arguments = new LinkBuilder<DartType>();
1401 bool hashTypeArgumentMismatch = resolveTypeArguments( 1425 bool hasTypeArgumentMismatch = resolveTypeArguments(
1402 node, const Link<DartType>(), enclosingElement, 1426 node, const Link<DartType>(), arguments);
1403 scope, onFailure, whenResolved, arguments); 1427 if (hasTypeArgumentMismatch) {
1404 if (hashTypeArgumentMismatch) {
1405 type = new MalformedType( 1428 type = new MalformedType(
1406 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, 1429 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
1407 {'type': node}, typeName.source, enclosingElement), 1430 {'type': node}, typeName.source, enclosingElement),
1408 type, arguments.toLink()); 1431 type, arguments.toLink());
1409 } 1432 }
1410 return type; 1433 return type;
1411 } 1434 }
1412 1435
1413 if (element == null) { 1436 if (element == null) {
1414 type = reportFailureAndCreateType( 1437 type = reportFailureAndCreateType(false,
1415 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); 1438 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName});
1416 } else if (element.isAmbiguous()) { 1439 } else if (element.isAmbiguous()) {
1417 AmbiguousElement ambiguous = element; 1440 AmbiguousElement ambiguous = element;
1418 type = reportFailureAndCreateType( 1441 type = reportFailureAndCreateType(isTypeExpression,
1419 ambiguous.messageKind, ambiguous.messageArguments); 1442 ambiguous.messageKind, ambiguous.messageArguments);
1420 } else if (!element.impliesType()) { 1443 } else if (!element.impliesType()) {
1421 type = reportFailureAndCreateType( 1444 type = reportFailureAndCreateType(false,
1422 MessageKind.NOT_A_TYPE, {'node': node.typeName}); 1445 MessageKind.NOT_A_TYPE, {'node': node.typeName});
1423 } else { 1446 } else {
1424 if (identical(element, compiler.types.voidType.element) || 1447 if (identical(element, compiler.types.voidType.element) ||
1425 identical(element, compiler.types.dynamicType.element)) { 1448 identical(element, compiler.types.dynamicType.element)) {
1426 type = checkNoTypeArguments(element.computeType(compiler)); 1449 type = checkNoTypeArguments(element.computeType(compiler));
1427 } else if (element.isClass()) { 1450 } else if (element.isClass()) {
1428 ClassElement cls = element; 1451 ClassElement cls = element;
1429 compiler.resolver._ensureClassWillBeResolved(cls); 1452 compiler.resolver._ensureClassWillBeResolved(cls);
1430 element.computeType(compiler); 1453 element.computeType(compiler);
1431 var arguments = new LinkBuilder<DartType>(); 1454 var arguments = new LinkBuilder<DartType>();
1432 bool hashTypeArgumentMismatch = resolveTypeArguments( 1455 bool hasTypeArgumentMismatch = resolveTypeArguments(
1433 node, cls.typeVariables, enclosingElement, 1456 node, cls.typeVariables, arguments);
1434 scope, onFailure, whenResolved, arguments); 1457 if (hasTypeArgumentMismatch) {
1435 if (hashTypeArgumentMismatch) {
1436 type = new MalformedType( 1458 type = new MalformedType(
1437 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, 1459 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
1438 {'type': node}, typeName.source, enclosingElement), 1460 {'type': node}, typeName.source, enclosingElement),
1439 new InterfaceType(cls.declaration, arguments.toLink())); 1461 new InterfaceType(cls.declaration, arguments.toLink()));
1440 } else { 1462 } else {
1441 if (arguments.isEmpty) { 1463 if (arguments.isEmpty) {
1442 type = cls.rawType; 1464 type = cls.rawType;
1443 } else { 1465 } else {
1444 type = new InterfaceType(cls.declaration, arguments.toLink()); 1466 type = new InterfaceType(cls.declaration, arguments.toLink());
1445 } 1467 }
1446 } 1468 }
1447 } else if (element.isTypedef()) { 1469 } else if (element.isTypedef()) {
1448 TypedefElement typdef = element; 1470 TypedefElement typdef = element;
1449 // TODO(ahe): Should be [ensureResolved]. 1471 // TODO(ahe): Should be [ensureResolved].
1450 compiler.resolveTypedef(typdef); 1472 compiler.resolveTypedef(typdef);
1451 var arguments = new LinkBuilder<DartType>(); 1473 var arguments = new LinkBuilder<DartType>();
1452 bool hashTypeArgumentMismatch = resolveTypeArguments( 1474 bool hashTypeArgumentMismatch = resolveTypeArguments(
1453 node, typdef.typeVariables, enclosingElement, 1475 node, typdef.typeVariables, arguments);
1454 scope, onFailure, whenResolved, arguments);
1455 if (hashTypeArgumentMismatch) { 1476 if (hashTypeArgumentMismatch) {
1456 type = new MalformedType( 1477 type = new MalformedType(
1457 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, 1478 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
1458 {'type': node}, typeName.source, enclosingElement), 1479 {'type': node}, typeName.source, enclosingElement),
1459 new TypedefType(typdef, arguments.toLink())); 1480 new TypedefType(typdef, arguments.toLink()));
1460 } else { 1481 } else {
1461 if (arguments.isEmpty) { 1482 if (arguments.isEmpty) {
1462 type = typdef.rawType; 1483 type = typdef.rawType;
1463 } else { 1484 } else {
1464 type = new TypedefType(typdef, arguments.toLink()); 1485 type = new TypedefType(typdef, arguments.toLink());
(...skipping 23 matching lines...) Expand all
1488 whenResolved(node, type); 1509 whenResolved(node, type);
1489 return type; 1510 return type;
1490 } 1511 }
1491 1512
1492 /** 1513 /**
1493 * Resolves the type arguments of [node] and adds these to [arguments]. 1514 * Resolves the type arguments of [node] and adds these to [arguments].
1494 * 1515 *
1495 * Returns [: true :] if the number of type arguments did not match the 1516 * Returns [: true :] if the number of type arguments did not match the
1496 * number of type variables. 1517 * number of type variables.
1497 */ 1518 */
1498 bool resolveTypeArguments( 1519 bool resolveTypeArguments(TypeAnnotation node,
1499 TypeAnnotation node, 1520 Link<DartType> typeVariables,
1500 Link<DartType> typeVariables, 1521 LinkBuilder<DartType> arguments) {
1501 Element enclosingElement,
1502 Scope scope,
1503 onFailure, whenResolved,
1504 LinkBuilder<DartType> arguments) {
1505 if (node.typeArguments == null) { 1522 if (node.typeArguments == null) {
1506 return false; 1523 return false;
1507 } 1524 }
1508 bool typeArgumentCountMismatch = false; 1525 bool typeArgumentCountMismatch = false;
1509 for (Link<Node> typeArguments = node.typeArguments.nodes; 1526 for (Node typeArgument in node.typeArguments.nodes) {
1510 !typeArguments.isEmpty;
1511 typeArguments = typeArguments.tail) {
1512 if (typeVariables != null && typeVariables.isEmpty) { 1527 if (typeVariables != null && typeVariables.isEmpty) {
1513 onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); 1528 reportFailure(isTypeExpression,
1529 typeArgument, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
1514 typeArgumentCountMismatch = true; 1530 typeArgumentCountMismatch = true;
1515 } 1531 }
1516 DartType argType = resolveTypeAnnotationInContext(scope, 1532 DartType argType = resolveTypeAnnotationInternal(typeArgument);
1517 typeArguments.head,
1518 enclosingElement,
1519 onFailure,
1520 whenResolved);
1521 arguments.addLast(argType); 1533 arguments.addLast(argType);
1522 if (typeVariables != null && !typeVariables.isEmpty) { 1534 if (typeVariables != null && !typeVariables.isEmpty) {
1523 typeVariables = typeVariables.tail; 1535 typeVariables = typeVariables.tail;
1524 } 1536 }
1525 } 1537 }
1526 if (typeVariables != null && !typeVariables.isEmpty) { 1538 if (typeVariables != null && !typeVariables.isEmpty) {
1527 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); 1539 reportFailure(isTypeExpression,
1540 node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT);
1528 typeArgumentCountMismatch = true; 1541 typeArgumentCountMismatch = true;
1529 } 1542 }
1530 return typeArgumentCountMismatch; 1543 return typeArgumentCountMismatch;
1531 } 1544 }
1532 } 1545 }
1533 1546
1534 /** 1547 /**
1535 * Core implementation of resolution. 1548 * Core implementation of resolution.
1536 * 1549 *
1537 * Do not subclass or instantiate this class outside this library 1550 * Do not subclass or instantiate this class outside this library
1538 * except for testing. 1551 * except for testing.
1539 */ 1552 */
1540 class ResolverVisitor extends CommonResolverVisitor<Element> { 1553 class ResolverVisitor extends CommonResolverVisitor<Element>
1554 implements TypeResolverContext {
1541 final TreeElementMapping mapping; 1555 final TreeElementMapping mapping;
1542 Element enclosingElement; 1556 Element enclosingElement;
1543 final TypeResolver typeResolver; 1557 final TypeResolver typeResolver;
1544 bool inInstanceContext; 1558 bool inInstanceContext;
1545 bool inCheckContext; 1559 bool inCheckContext;
1546 bool inCatchBlock; 1560 bool inCatchBlock;
1547 Scope scope; 1561 Scope scope;
1548 ClassElement currentClass; 1562 ClassElement currentClass;
1549 ExpressionStatement currentExpressionStatement; 1563 ExpressionStatement currentExpressionStatement;
1550 bool typeRequired = false; 1564 bool typeRequired = false;
1551 StatementScope statementScope; 1565 StatementScope statementScope;
1552 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION 1566 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION
1553 | ElementCategory.IMPLIES_TYPE; 1567 | ElementCategory.IMPLIES_TYPE;
1554 1568
1555 ResolverVisitor(Compiler compiler, Element element, this.mapping) 1569 ResolverVisitor(Compiler compiler, Element element, this.mapping)
1556 : this.enclosingElement = element, 1570 : this.enclosingElement = element,
1557 // When the element is a field, we are actually resolving its 1571 // When the element is a field, we are actually resolving its
1558 // initial value, which should not have access to instance 1572 // initial value, which should not have access to instance
1559 // fields. 1573 // fields.
1560 inInstanceContext = (element.isInstanceMember() && !element.isField()) 1574 inInstanceContext = (element.isInstanceMember() && !element.isField())
1561 || element.isGenerativeConstructor(), 1575 || element.isGenerativeConstructor(),
1562 this.currentClass = element.isMember() ? element.getEnclosingClass() 1576 this.currentClass = element.isMember() ? element.getEnclosingClass()
1563 : null, 1577 : null,
1564 this.statementScope = new StatementScope(), 1578 this.statementScope = new StatementScope(),
1565 typeResolver = new TypeResolver(compiler), 1579 typeResolver = new TypeResolver(compiler),
1566 scope = element.buildScope(), 1580 scope = element.buildScope(),
1567 inCheckContext = compiler.enableTypeAssertions, 1581 inCheckContext = compiler.enableTypeAssertions,
1568 inCatchBlock = false, 1582 inCatchBlock = false,
1569 super(compiler); 1583 super(compiler) {
1584 typeResolver.context = this;
1585 }
1570 1586
1571 ResolutionEnqueuer get world => compiler.enqueuer.resolution; 1587 ResolutionEnqueuer get world => compiler.enqueuer.resolution;
1572 1588
1573 Element lookup(Node node, SourceString name) { 1589 Element lookup(Node node, SourceString name) {
1574 Element result = scope.lookup(name); 1590 Element result = scope.lookup(name);
1575 if (!Elements.isUnresolved(result)) { 1591 if (!Elements.isUnresolved(result)) {
1576 if (!inInstanceContext && result.isInstanceMember()) { 1592 if (!inInstanceContext && result.isInstanceMember()) {
1577 compiler.reportErrorCode( 1593 compiler.reportErrorCode(
1578 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); 1594 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name});
1579 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, 1595 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE,
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after
2457 argument.element.enclosingElement); 2473 argument.element.enclosingElement);
2458 } else if (argument is InterfaceType) { 2474 } else if (argument is InterfaceType) {
2459 InterfaceType type = argument; 2475 InterfaceType type = argument;
2460 type.typeArguments.forEach((DartType argument) { 2476 type.typeArguments.forEach((DartType argument) {
2461 analyzeTypeArgument(type, argument); 2477 analyzeTypeArgument(type, argument);
2462 }); 2478 });
2463 } 2479 }
2464 } 2480 }
2465 2481
2466 DartType resolveTypeAnnotation(TypeAnnotation node) { 2482 DartType resolveTypeAnnotation(TypeAnnotation node) {
2467 Function report = typeRequired ? error : warning; 2483 DartType type = typeRequired ?
2468 DartType type = typeResolver.resolveTypeAnnotation( 2484 typeResolver.resolveTypeExpression(node) :
2469 node, scope, enclosingElement, 2485 typeResolver.resolveTypeAnnotation(node);
2470 onFailure: report, whenResolved: useType);
2471 if (type == null) return null; 2486 if (type == null) return null;
2472 if (inCheckContext) { 2487 if (inCheckContext) {
2473 compiler.enqueuer.resolution.registerIsCheck(type); 2488 compiler.enqueuer.resolution.registerIsCheck(type);
2474 } 2489 }
2475 if (typeRequired || inCheckContext) { 2490 if (typeRequired || inCheckContext) {
2476 if (type is InterfaceType) { 2491 if (type is InterfaceType) {
2477 InterfaceType itf = type; 2492 InterfaceType itf = type;
2478 itf.typeArguments.forEach((DartType argument) { 2493 itf.typeArguments.forEach((DartType argument) {
2479 analyzeTypeArgument(type, argument); 2494 analyzeTypeArgument(type, argument);
2480 }); 2495 });
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
2811 inCatchBlock = true; 2826 inCatchBlock = true;
2812 visitIn(node.block, blockScope); 2827 visitIn(node.block, blockScope);
2813 inCatchBlock = oldInCatchBlock; 2828 inCatchBlock = oldInCatchBlock;
2814 } 2829 }
2815 2830
2816 visitTypedef(Typedef node) { 2831 visitTypedef(Typedef node) {
2817 unimplemented(node, 'typedef'); 2832 unimplemented(node, 'typedef');
2818 } 2833 }
2819 } 2834 }
2820 2835
2821 class TypeDefinitionVisitor extends CommonResolverVisitor<DartType> { 2836 class TypeDefinitionVisitor extends CommonResolverVisitor<DartType>
2837 implements TypeResolverContext {
2822 Scope scope; 2838 Scope scope;
2823 TypeDeclarationElement element; 2839 final TypeDeclarationElement element;
2824 TypeResolver typeResolver; 2840 TypeResolver typeResolver;
2841 Element get enclosingElement => element;
2825 2842
2826 TypeDefinitionVisitor(Compiler compiler, TypeDeclarationElement element) 2843 TypeDefinitionVisitor(Compiler compiler, TypeDeclarationElement element)
2827 : this.element = element, 2844 : this.element = element,
2828 scope = Scope.buildEnclosingScope(element), 2845 scope = Scope.buildEnclosingScope(element),
2829 typeResolver = new TypeResolver(compiler), 2846 typeResolver = new TypeResolver(compiler),
2830 super(compiler); 2847 super(compiler) {
2848 typeResolver.context = this;
2849 }
2850
2851 void useType(Node node, DartType type) {
2852 // Do not register used types.
2853 }
2831 2854
2832 void resolveTypeVariableBounds(NodeList node) { 2855 void resolveTypeVariableBounds(NodeList node) {
2833 if (node == null) return; 2856 if (node == null) return;
2834 2857
2835 var nameSet = new Set<SourceString>(); 2858 var nameSet = new Set<SourceString>();
2836 // Resolve the bounds of type variables. 2859 // Resolve the bounds of type variables.
2837 Link<DartType> typeLink = element.typeVariables; 2860 Link<DartType> typeLink = element.typeVariables;
2838 Link<Node> nodeLink = node.nodes; 2861 Link<Node> nodeLink = node.nodes;
2839 while (!nodeLink.isEmpty) { 2862 while (!nodeLink.isEmpty) {
2840 TypeVariableType typeVariable = typeLink.head; 2863 TypeVariableType typeVariable = typeLink.head;
2841 SourceString typeName = typeVariable.name; 2864 SourceString typeName = typeVariable.name;
2842 TypeVariable typeNode = nodeLink.head; 2865 TypeVariable typeNode = nodeLink.head;
2843 if (nameSet.contains(typeName)) { 2866 if (nameSet.contains(typeName)) {
2844 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, 2867 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME,
2845 {'typeVariableName': typeName}); 2868 {'typeVariableName': typeName});
2846 } 2869 }
2847 nameSet.add(typeName); 2870 nameSet.add(typeName);
2848 2871
2849 TypeVariableElement variableElement = typeVariable.element; 2872 TypeVariableElement variableElement = typeVariable.element;
2850 if (typeNode.bound != null) { 2873 if (typeNode.bound != null) {
2851 DartType boundType = typeResolver.resolveTypeAnnotation( 2874 DartType boundType = typeResolver.resolveTypeAnnotation(typeNode.bound);
2852 typeNode.bound, scope, element, onFailure: warning);
2853 if (boundType != null && boundType.element == variableElement) { 2875 if (boundType != null && boundType.element == variableElement) {
2854 // TODO(johnniwinther): Check for more general cycles, like 2876 // TODO(johnniwinther): Check for more general cycles, like
2855 // [: <A extends B, B extends C, C extends B> :]. 2877 // [: <A extends B, B extends C, C extends B> :].
2856 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, 2878 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE,
2857 {'typeVariableName': variableElement.name}); 2879 {'typeVariableName': variableElement.name});
2858 } else if (boundType != null) { 2880 } else if (boundType != null) {
2859 variableElement.bound = boundType; 2881 variableElement.bound = boundType;
2860 } else { 2882 } else {
2861 // TODO(johnniwinther): Should be an erroneous type. 2883 // TODO(johnniwinther): Should be an erroneous type.
2862 variableElement.bound = compiler.objectClass.computeType(compiler); 2884 variableElement.bound = compiler.objectClass.computeType(compiler);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2919 // TODO(ahe): It is not safe to call resolveTypeVariableBounds yet. 2941 // TODO(ahe): It is not safe to call resolveTypeVariableBounds yet.
2920 // As a side-effect, this may get us back here trying to 2942 // As a side-effect, this may get us back here trying to
2921 // resolve this class again. 2943 // resolve this class again.
2922 resolveTypeVariableBounds(node.typeParameters); 2944 resolveTypeVariableBounds(node.typeParameters);
2923 2945
2924 // Setup the supertype for the element. 2946 // Setup the supertype for the element.
2925 assert(element.supertype == null); 2947 assert(element.supertype == null);
2926 if (node.superclass != null) { 2948 if (node.superclass != null) {
2927 MixinApplication superMixin = node.superclass.asMixinApplication(); 2949 MixinApplication superMixin = node.superclass.asMixinApplication();
2928 if (superMixin != null) { 2950 if (superMixin != null) {
2929 DartType supertype = resolveSupertype(element, superMixin.superclass); 2951 DartType supertype = resolveSupertype(superMixin.superclass);
2930 Link<Node> link = superMixin.mixins.nodes; 2952 Link<Node> link = superMixin.mixins.nodes;
2931 while (!link.isEmpty) { 2953 while (!link.isEmpty) {
2932 supertype = applyMixin(supertype, visit(link.head)); 2954 supertype = applyMixin(supertype, visit(link.head));
2933 link = link.tail; 2955 link = link.tail;
2934 } 2956 }
2935 element.supertype = supertype; 2957 element.supertype = supertype;
2936 } else { 2958 } else {
2937 element.supertype = resolveSupertype(element, node.superclass); 2959 element.supertype = resolveSupertype(node.superclass);
2938 } 2960 }
2939 } 2961 }
2940 2962
2941 // If the super type isn't specified, we make it Object. 2963 // If the super type isn't specified, we make it Object.
2942 final objectElement = compiler.objectClass; 2964 final objectElement = compiler.objectClass;
2943 if (!identical(element, objectElement) && element.supertype == null) { 2965 if (!identical(element, objectElement) && element.supertype == null) {
2944 if (objectElement == null) { 2966 if (objectElement == null) {
2945 compiler.internalError("Internal error: cannot resolve Object", 2967 compiler.internalError("Internal error: cannot resolve Object",
2946 node: node); 2968 node: node);
2947 } else { 2969 } else {
(...skipping 16 matching lines...) Expand all
2964 DartType visitNamedMixinApplication(NamedMixinApplication node) { 2986 DartType visitNamedMixinApplication(NamedMixinApplication node) {
2965 compiler.ensure(element != null); 2987 compiler.ensure(element != null);
2966 compiler.ensure(element.resolutionState == STATE_STARTED); 2988 compiler.ensure(element.resolutionState == STATE_STARTED);
2967 2989
2968 InterfaceType type = element.computeType(compiler); 2990 InterfaceType type = element.computeType(compiler);
2969 scope = new TypeDeclarationScope(scope, element); 2991 scope = new TypeDeclarationScope(scope, element);
2970 resolveTypeVariableBounds(node.typeParameters); 2992 resolveTypeVariableBounds(node.typeParameters);
2971 2993
2972 // Generate anonymous mixin application elements for the 2994 // Generate anonymous mixin application elements for the
2973 // intermediate mixin applications (excluding the last). 2995 // intermediate mixin applications (excluding the last).
2974 DartType supertype = resolveSupertype(element, node.superclass); 2996 DartType supertype = resolveSupertype(node.superclass);
2975 Link<Node> link = node.mixins.nodes; 2997 Link<Node> link = node.mixins.nodes;
2976 while (!link.tail.isEmpty) { 2998 while (!link.tail.isEmpty) {
2977 supertype = applyMixin(supertype, visit(link.head)); 2999 supertype = applyMixin(supertype, visit(link.head));
2978 link = link.tail; 3000 link = link.tail;
2979 } 3001 }
2980 doApplyMixinTo(element, supertype, visit(link.head)); 3002 doApplyMixinTo(element, supertype, visit(link.head));
2981 return element.computeType(compiler); 3003 return element.computeType(compiler);
2982 } 3004 }
2983 3005
2984 DartType applyMixin(DartType supertype, DartType mixinType) { 3006 DartType applyMixin(DartType supertype, DartType mixinType) {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
3093 Identifier selector = node.selector.asIdentifier(); 3115 Identifier selector = node.selector.asIdentifier();
3094 var e = prefixElement.lookupLocalMember(selector.source); 3116 var e = prefixElement.lookupLocalMember(selector.source);
3095 if (e == null || !e.impliesType()) { 3117 if (e == null || !e.impliesType()) {
3096 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, 3118 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE,
3097 {'typeName': node.selector}); 3119 {'typeName': node.selector});
3098 return null; 3120 return null;
3099 } 3121 }
3100 return e.computeType(compiler); 3122 return e.computeType(compiler);
3101 } 3123 }
3102 3124
3103 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { 3125 DartType resolveSupertype(TypeAnnotation superclass) {
3104 DartType supertype = typeResolver.resolveTypeAnnotation( 3126 DartType supertype = typeResolver.resolveTypeExpression(superclass);
3105 superclass, scope, cls, onFailure: error);
3106 if (supertype != null) { 3127 if (supertype != null) {
3107 if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) { 3128 if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) {
3108 // Error has already been reported. 3129 // Error has already been reported.
3109 return null; 3130 return null;
3110 } else if (!identical(supertype.kind, TypeKind.INTERFACE)) { 3131 } else if (!identical(supertype.kind, TypeKind.INTERFACE)) {
3111 // TODO(johnniwinther): Handle dynamic. 3132 // TODO(johnniwinther): Handle dynamic.
3112 error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED); 3133 error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED);
3113 return null; 3134 return null;
3114 } else if (isBlackListed(supertype)) { 3135 } else if (isBlackListed(supertype)) {
3115 error(superclass, MessageKind.CANNOT_EXTEND, {'type': supertype}); 3136 error(superclass, MessageKind.CANNOT_EXTEND, {'type': supertype});
3116 return null; 3137 return null;
3117 } 3138 }
3118 } 3139 }
3119 return supertype; 3140 return supertype;
3120 } 3141 }
3121 3142
3122 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { 3143 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) {
3123 Link<DartType> result = const Link<DartType>(); 3144 Link<DartType> result = const Link<DartType>();
3124 if (interfaces == null) return result; 3145 if (interfaces == null) return result;
3125 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { 3146 for (TypeAnnotation interface in interfaces.nodes){
3126 DartType interfaceType = typeResolver.resolveTypeAnnotation( 3147 DartType interfaceType = typeResolver.resolveTypeExpression(interface);
3127 link.head, scope, element, onFailure: error);
3128 if (interfaceType != null) { 3148 if (interfaceType != null) {
3129 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) { 3149 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) {
3130 // Error has already been reported. 3150 // Error has already been reported.
3131 } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) { 3151 } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) {
3132 // TODO(johnniwinther): Handle dynamic. 3152 // TODO(johnniwinther): Handle dynamic.
3133 TypeAnnotation typeAnnotation = link.head; 3153 error(interface.typeName, MessageKind.CLASS_NAME_EXPECTED);
3134 error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED);
3135 } else { 3154 } else {
3136 if (interfaceType == element.supertype) { 3155 if (interfaceType == element.supertype) {
3137 compiler.reportErrorCode( 3156 compiler.reportErrorCode(
3138 superclass, 3157 superclass,
3139 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, 3158 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
3140 {'type': interfaceType}); 3159 {'type': interfaceType});
3141 compiler.reportErrorCode( 3160 compiler.reportErrorCode(
3142 link.head, 3161 interface,
3143 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, 3162 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
3144 {'type': interfaceType}); 3163 {'type': interfaceType});
3145 } 3164 }
3146 if (result.contains(interfaceType)) { 3165 if (result.contains(interfaceType)) {
3147 compiler.reportErrorCode( 3166 compiler.reportErrorCode(
3148 link.head, 3167 interface,
3149 MessageKind.DUPLICATE_IMPLEMENTS, 3168 MessageKind.DUPLICATE_IMPLEMENTS,
3150 {'type': interfaceType}); 3169 {'type': interfaceType});
3151 } 3170 }
3152 result = result.prepend(interfaceType); 3171 result = result.prepend(interfaceType);
3153 if (isBlackListed(interfaceType)) { 3172 if (isBlackListed(interfaceType)) {
3154 error(link.head, MessageKind.CANNOT_IMPLEMENT, 3173 error(interface, MessageKind.CANNOT_IMPLEMENT,
3155 {'type': interfaceType}); 3174 {'type': interfaceType});
3156 } 3175 }
3157 } 3176 }
3158 } 3177 }
3159 } 3178 }
3160 return result; 3179 return result;
3161 } 3180 }
3162 3181
3163 void calculateAllSupertypes(ClassElement cls) { 3182 void calculateAllSupertypes(ClassElement cls) {
3164 // TODO(karlklose): Check if type arguments match, if a class 3183 // TODO(karlklose): Check if type arguments match, if a class
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
3700 return e; 3719 return e;
3701 } 3720 }
3702 3721
3703 /// Assumed to be called by [resolveRedirectingFactory]. 3722 /// Assumed to be called by [resolveRedirectingFactory].
3704 Element visitReturn(Return node) { 3723 Element visitReturn(Return node) {
3705 Node expression = node.expression; 3724 Node expression = node.expression;
3706 return finishConstructorReference(visit(expression), 3725 return finishConstructorReference(visit(expression),
3707 expression, expression); 3726 expression, expression);
3708 } 3727 }
3709 } 3728 }
OLDNEW
« no previous file with comments | « no previous file | tests/co19/co19-dart2js.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698