| 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 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |