Chromium Code Reviews| 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 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1261 nestingLevel++; | 1261 nestingLevel++; |
| 1262 } | 1262 } |
| 1263 | 1263 |
| 1264 void exitSwitch() { | 1264 void exitSwitch() { |
| 1265 nestingLevel--; | 1265 nestingLevel--; |
| 1266 breakTargetStack = breakTargetStack.tail; | 1266 breakTargetStack = breakTargetStack.tail; |
| 1267 labels = labels.outer; | 1267 labels = labels.outer; |
| 1268 } | 1268 } |
| 1269 } | 1269 } |
| 1270 | 1270 |
| 1271 /** | |
| 1272 * Interface for the predicates and methods needed by the [TypeResolver]. | |
| 1273 */ | |
| 1274 abstract class TypeResolverContext { | |
| 1275 Scope get scope; | |
| 1276 Element get enclosingElement; | |
| 1277 | |
| 1278 void error(Node node, MessageKind kind, [Map arguments = const {}]); | |
| 1279 void warning(Node node, MessageKind kind, [Map arguments = const {}]); | |
| 1280 void useType(Node node, DartType type); | |
| 1281 } | |
| 1282 | |
| 1271 class TypeResolver { | 1283 class TypeResolver { |
| 1272 final Compiler compiler; | 1284 final Compiler compiler; |
| 1285 TypeResolverContext context; | |
| 1286 bool isTypeExpression; | |
| 1273 | 1287 |
| 1274 TypeResolver(this.compiler); | 1288 TypeResolver(this.compiler); |
| 1275 | 1289 |
| 1290 Scope get scope => context.scope; | |
| 1291 Element get enclosingElement => context.enclosingElement; | |
| 1292 | |
| 1293 void error(Node node, MessageKind kind, [Map arguments = const {}]) { | |
| 1294 context.error(node, kind, arguments); | |
| 1295 } | |
| 1296 | |
| 1297 void warning(Node node, MessageKind kind, [Map arguments = const {}]) { | |
| 1298 context.warning(node, kind, arguments); | |
| 1299 } | |
| 1300 | |
| 1301 void reportFailure(bool failureIsError, | |
| 1302 Node node, MessageKind kind, [Map arguments = const {}]) { | |
| 1303 if (failureIsError) { | |
| 1304 error(node, kind, arguments); | |
| 1305 } else { | |
| 1306 warning(node, kind, arguments); | |
| 1307 } | |
| 1308 } | |
| 1309 | |
| 1310 void whenResolved(Node node, DartType type) { | |
| 1311 context.useType(node, type); | |
| 1312 } | |
| 1313 | |
| 1276 Element resolveTypeName(Scope scope, | 1314 Element resolveTypeName(Scope scope, |
| 1277 SourceString prefixName, | 1315 SourceString prefixName, |
| 1278 Identifier typeName) { | 1316 Identifier typeName) { |
| 1279 if (prefixName != null) { | 1317 if (prefixName != null) { |
| 1280 Element e = scope.lookup(prefixName); | 1318 Element e = scope.lookup(prefixName); |
| 1281 if (e != null) { | 1319 if (e != null) { |
| 1282 if (identical(e.kind, ElementKind.PREFIX)) { | 1320 if (identical(e.kind, ElementKind.PREFIX)) { |
| 1283 // The receiver is a prefix. Lookup in the imported members. | 1321 // The receiver is a prefix. Lookup in the imported members. |
| 1284 PrefixElement prefix = e; | 1322 PrefixElement prefix = e; |
| 1285 return prefix.lookupLocalMember(typeName.source); | 1323 return prefix.lookupLocalMember(typeName.source); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1301 compiler.onDeprecatedFeature(typeName, 'Dynamic'); | 1339 compiler.onDeprecatedFeature(typeName, 'Dynamic'); |
| 1302 return compiler.dynamicClass; | 1340 return compiler.dynamicClass; |
| 1303 } else if (identical(stringValue, 'dynamic')) { | 1341 } else if (identical(stringValue, 'dynamic')) { |
| 1304 return compiler.dynamicClass; | 1342 return compiler.dynamicClass; |
| 1305 } else { | 1343 } else { |
| 1306 return scope.lookup(typeName.source); | 1344 return scope.lookup(typeName.source); |
| 1307 } | 1345 } |
| 1308 } | 1346 } |
| 1309 } | 1347 } |
| 1310 | 1348 |
| 1311 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean | 1349 DartType resolveTypeExpression(TypeAnnotation node) { |
| 1312 // flags instead of closures. | 1350 this.isTypeExpression = true; |
|
ahe
2013/02/05 11:26:29
I don't think it is safe to call resolveTypeExpres
| |
| 1313 DartType resolveTypeAnnotation( | 1351 return resolveTypeAnnotationInternal(node); |
| 1314 TypeAnnotation node, | |
| 1315 Scope scope, | |
| 1316 Element enclosingElement, | |
| 1317 {onFailure(Node node, MessageKind kind, [Map arguments]), | |
| 1318 whenResolved(Node node, DartType type)}) { | |
| 1319 if (onFailure == null) { | |
| 1320 onFailure = (n, k, [arguments]) {}; | |
| 1321 } | |
| 1322 if (whenResolved == null) { | |
| 1323 whenResolved = (n, t) {}; | |
| 1324 } | |
| 1325 if (scope == null) { | |
| 1326 compiler.internalError('resolveTypeAnnotation: no scope specified'); | |
| 1327 } | |
| 1328 return resolveTypeAnnotationInContext(scope, node, enclosingElement, | |
| 1329 onFailure, whenResolved); | |
| 1330 } | 1352 } |
| 1331 | 1353 |
| 1332 DartType resolveTypeAnnotationInContext(Scope scope, TypeAnnotation node, | 1354 DartType resolveTypeAnnotation(TypeAnnotation node) { |
| 1333 Element enclosingElement, | 1355 this.isTypeExpression = false; |
| 1334 onFailure, whenResolved) { | 1356 return resolveTypeAnnotationInternal(node); |
| 1357 } | |
| 1358 | |
| 1359 DartType resolveTypeAnnotationInternal(TypeAnnotation node) { | |
| 1335 Identifier typeName; | 1360 Identifier typeName; |
| 1336 SourceString prefixName; | 1361 SourceString prefixName; |
| 1337 Send send = node.typeName.asSend(); | 1362 Send send = node.typeName.asSend(); |
| 1338 if (send != null) { | 1363 if (send != null) { |
| 1339 // The type name is of the form [: prefix . identifier :]. | 1364 // The type name is of the form [: prefix . identifier :]. |
| 1340 prefixName = send.receiver.asIdentifier().source; | 1365 prefixName = send.receiver.asIdentifier().source; |
| 1341 typeName = send.selector.asIdentifier(); | 1366 typeName = send.selector.asIdentifier(); |
| 1342 } else { | 1367 } else { |
| 1343 typeName = node.typeName.asIdentifier(); | 1368 typeName = node.typeName.asIdentifier(); |
| 1344 } | 1369 } |
| 1345 | 1370 |
| 1346 Element element = resolveTypeName(scope, prefixName, typeName); | 1371 Element element = resolveTypeName(scope, prefixName, typeName); |
| 1347 DartType type; | 1372 DartType type; |
| 1348 | 1373 |
| 1349 DartType reportFailureAndCreateType(MessageKind messageKind, | 1374 DartType reportFailureAndCreateType(bool failureIsError, |
| 1375 MessageKind messageKind, | |
| 1350 Map messageArguments) { | 1376 Map messageArguments) { |
| 1351 onFailure(node, messageKind, messageArguments); | 1377 reportFailure(failureIsError, node, messageKind, messageArguments); |
| 1352 var erroneousElement = new ErroneousElementX( | 1378 var erroneousElement = new ErroneousElementX( |
| 1353 messageKind, messageArguments, typeName.source, enclosingElement); | 1379 messageKind, messageArguments, typeName.source, enclosingElement); |
| 1354 var arguments = new LinkBuilder<DartType>(); | 1380 var arguments = new LinkBuilder<DartType>(); |
| 1355 resolveTypeArguments( | 1381 resolveTypeArguments(node, null, arguments); |
| 1356 node, null, enclosingElement, | |
| 1357 scope, onFailure, whenResolved, arguments); | |
| 1358 return new MalformedType(erroneousElement, null, arguments.toLink()); | 1382 return new MalformedType(erroneousElement, null, arguments.toLink()); |
| 1359 } | 1383 } |
| 1360 | 1384 |
| 1361 DartType checkNoTypeArguments(DartType type) { | 1385 DartType checkNoTypeArguments(DartType type) { |
| 1362 var arguments = new LinkBuilder<DartType>(); | 1386 var arguments = new LinkBuilder<DartType>(); |
| 1363 bool hashTypeArgumentMismatch = resolveTypeArguments( | 1387 bool hasTypeArgumentMismatch = resolveTypeArguments( |
|
ahe
2013/02/05 11:26:29
The old name was funnier ;-)
| |
| 1364 node, const Link<DartType>(), enclosingElement, | 1388 node, const Link<DartType>(), arguments); |
| 1365 scope, onFailure, whenResolved, arguments); | 1389 if (hasTypeArgumentMismatch) { |
| 1366 if (hashTypeArgumentMismatch) { | |
| 1367 type = new MalformedType( | 1390 type = new MalformedType( |
| 1368 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, | 1391 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, |
| 1369 {'type': node}, typeName.source, enclosingElement), | 1392 {'type': node}, typeName.source, enclosingElement), |
| 1370 type, arguments.toLink()); | 1393 type, arguments.toLink()); |
| 1371 } | 1394 } |
| 1372 return type; | 1395 return type; |
| 1373 } | 1396 } |
| 1374 | 1397 |
| 1375 if (element == null) { | 1398 if (element == null) { |
| 1376 type = reportFailureAndCreateType( | 1399 type = reportFailureAndCreateType(false, |
| 1377 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); | 1400 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); |
| 1378 } else if (element.isAmbiguous()) { | 1401 } else if (element.isAmbiguous()) { |
| 1379 AmbiguousElement ambiguous = element; | 1402 AmbiguousElement ambiguous = element; |
| 1380 type = reportFailureAndCreateType( | 1403 type = reportFailureAndCreateType(isTypeExpression, |
| 1381 ambiguous.messageKind, ambiguous.messageArguments); | 1404 ambiguous.messageKind, ambiguous.messageArguments); |
| 1382 } else if (!element.impliesType()) { | 1405 } else if (!element.impliesType()) { |
| 1383 type = reportFailureAndCreateType( | 1406 type = reportFailureAndCreateType(false, |
| 1384 MessageKind.NOT_A_TYPE, {'node': node.typeName}); | 1407 MessageKind.NOT_A_TYPE, {'node': node.typeName}); |
| 1385 } else { | 1408 } else { |
| 1386 if (identical(element, compiler.types.voidType.element) || | 1409 if (identical(element, compiler.types.voidType.element) || |
| 1387 identical(element, compiler.types.dynamicType.element)) { | 1410 identical(element, compiler.types.dynamicType.element)) { |
| 1388 type = checkNoTypeArguments(element.computeType(compiler)); | 1411 type = checkNoTypeArguments(element.computeType(compiler)); |
| 1389 } else if (element.isClass()) { | 1412 } else if (element.isClass()) { |
| 1390 ClassElement cls = element; | 1413 ClassElement cls = element; |
| 1391 compiler.resolver._ensureClassWillBeResolved(cls); | 1414 compiler.resolver._ensureClassWillBeResolved(cls); |
| 1392 element.computeType(compiler); | 1415 element.computeType(compiler); |
| 1393 var arguments = new LinkBuilder<DartType>(); | 1416 var arguments = new LinkBuilder<DartType>(); |
| 1394 bool hashTypeArgumentMismatch = resolveTypeArguments( | 1417 bool hasTypeArgumentMismatch = resolveTypeArguments( |
| 1395 node, cls.typeVariables, enclosingElement, | 1418 node, cls.typeVariables, arguments); |
| 1396 scope, onFailure, whenResolved, arguments); | 1419 if (hasTypeArgumentMismatch) { |
| 1397 if (hashTypeArgumentMismatch) { | |
| 1398 type = new MalformedType( | 1420 type = new MalformedType( |
| 1399 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, | 1421 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, |
| 1400 {'type': node}, typeName.source, enclosingElement), | 1422 {'type': node}, typeName.source, enclosingElement), |
| 1401 new InterfaceType(cls.declaration, arguments.toLink())); | 1423 new InterfaceType(cls.declaration, arguments.toLink())); |
| 1402 } else { | 1424 } else { |
| 1403 if (arguments.isEmpty) { | 1425 if (arguments.isEmpty) { |
| 1404 type = cls.rawType; | 1426 type = cls.rawType; |
| 1405 } else { | 1427 } else { |
| 1406 type = new InterfaceType(cls.declaration, arguments.toLink()); | 1428 type = new InterfaceType(cls.declaration, arguments.toLink()); |
| 1407 } | 1429 } |
| 1408 } | 1430 } |
| 1409 } else if (element.isTypedef()) { | 1431 } else if (element.isTypedef()) { |
| 1410 TypedefElement typdef = element; | 1432 TypedefElement typdef = element; |
| 1411 // TODO(ahe): Should be [ensureResolved]. | 1433 // TODO(ahe): Should be [ensureResolved]. |
| 1412 compiler.resolveTypedef(typdef); | 1434 compiler.resolveTypedef(typdef); |
| 1413 var arguments = new LinkBuilder<DartType>(); | 1435 var arguments = new LinkBuilder<DartType>(); |
| 1414 bool hashTypeArgumentMismatch = resolveTypeArguments( | 1436 bool hashTypeArgumentMismatch = resolveTypeArguments( |
| 1415 node, typdef.typeVariables, enclosingElement, | 1437 node, typdef.typeVariables, arguments); |
| 1416 scope, onFailure, whenResolved, arguments); | |
| 1417 if (hashTypeArgumentMismatch) { | 1438 if (hashTypeArgumentMismatch) { |
| 1418 type = new MalformedType( | 1439 type = new MalformedType( |
| 1419 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, | 1440 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, |
| 1420 {'type': node}, typeName.source, enclosingElement), | 1441 {'type': node}, typeName.source, enclosingElement), |
| 1421 new TypedefType(typdef, arguments.toLink())); | 1442 new TypedefType(typdef, arguments.toLink())); |
| 1422 } else { | 1443 } else { |
| 1423 if (arguments.isEmpty) { | 1444 if (arguments.isEmpty) { |
| 1424 type = typdef.rawType; | 1445 type = typdef.rawType; |
| 1425 } else { | 1446 } else { |
| 1426 type = new TypedefType(typdef, arguments.toLink()); | 1447 type = new TypedefType(typdef, arguments.toLink()); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1449 whenResolved(node, type); | 1470 whenResolved(node, type); |
| 1450 return type; | 1471 return type; |
| 1451 } | 1472 } |
| 1452 | 1473 |
| 1453 /** | 1474 /** |
| 1454 * Resolves the type arguments of [node] and adds these to [arguments]. | 1475 * Resolves the type arguments of [node] and adds these to [arguments]. |
| 1455 * | 1476 * |
| 1456 * Returns [: true :] if the number of type arguments did not match the | 1477 * Returns [: true :] if the number of type arguments did not match the |
| 1457 * number of type variables. | 1478 * number of type variables. |
| 1458 */ | 1479 */ |
| 1459 bool resolveTypeArguments( | 1480 bool resolveTypeArguments(TypeAnnotation node, |
| 1460 TypeAnnotation node, | 1481 Link<DartType> typeVariables, |
| 1461 Link<DartType> typeVariables, | 1482 LinkBuilder<DartType> arguments) { |
| 1462 Element enclosingElement, | |
| 1463 Scope scope, | |
| 1464 onFailure, whenResolved, | |
| 1465 LinkBuilder<DartType> arguments) { | |
| 1466 if (node.typeArguments == null) { | 1483 if (node.typeArguments == null) { |
| 1467 return false; | 1484 return false; |
| 1468 } | 1485 } |
| 1469 bool typeArgumentCountMismatch = false; | 1486 bool typeArgumentCountMismatch = false; |
| 1470 for (Link<Node> typeArguments = node.typeArguments.nodes; | 1487 for (Node typeArgument in node.typeArguments.nodes) { |
|
ahe
2013/02/05 11:26:29
Please avoid for-in.
| |
| 1471 !typeArguments.isEmpty; | |
| 1472 typeArguments = typeArguments.tail) { | |
| 1473 if (typeVariables != null && typeVariables.isEmpty) { | 1488 if (typeVariables != null && typeVariables.isEmpty) { |
| 1474 onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 1489 reportFailure(isTypeExpression, |
| 1490 typeArgument, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | |
| 1475 typeArgumentCountMismatch = true; | 1491 typeArgumentCountMismatch = true; |
| 1476 } | 1492 } |
| 1477 DartType argType = resolveTypeAnnotationInContext(scope, | 1493 DartType argType = resolveTypeAnnotationInternal(typeArgument); |
| 1478 typeArguments.head, | |
| 1479 enclosingElement, | |
| 1480 onFailure, | |
| 1481 whenResolved); | |
| 1482 arguments.addLast(argType); | 1494 arguments.addLast(argType); |
| 1483 if (typeVariables != null && !typeVariables.isEmpty) { | 1495 if (typeVariables != null && !typeVariables.isEmpty) { |
| 1484 typeVariables = typeVariables.tail; | 1496 typeVariables = typeVariables.tail; |
| 1485 } | 1497 } |
| 1486 } | 1498 } |
| 1487 if (typeVariables != null && !typeVariables.isEmpty) { | 1499 if (typeVariables != null && !typeVariables.isEmpty) { |
| 1488 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); | 1500 reportFailure(isTypeExpression, |
| 1501 node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); | |
| 1489 typeArgumentCountMismatch = true; | 1502 typeArgumentCountMismatch = true; |
| 1490 } | 1503 } |
| 1491 return typeArgumentCountMismatch; | 1504 return typeArgumentCountMismatch; |
| 1492 } | 1505 } |
| 1493 } | 1506 } |
| 1494 | 1507 |
| 1495 /** | 1508 /** |
| 1496 * Core implementation of resolution. | 1509 * Core implementation of resolution. |
| 1497 * | 1510 * |
| 1498 * Do not subclass or instantiate this class outside this library | 1511 * Do not subclass or instantiate this class outside this library |
| 1499 * except for testing. | 1512 * except for testing. |
| 1500 */ | 1513 */ |
| 1501 class ResolverVisitor extends CommonResolverVisitor<Element> { | 1514 class ResolverVisitor extends CommonResolverVisitor<Element> |
| 1515 implements TypeResolverContext { | |
| 1502 final TreeElementMapping mapping; | 1516 final TreeElementMapping mapping; |
| 1503 Element enclosingElement; | 1517 Element enclosingElement; |
| 1504 final TypeResolver typeResolver; | 1518 final TypeResolver typeResolver; |
| 1505 bool inInstanceContext; | 1519 bool inInstanceContext; |
| 1506 bool inCheckContext; | 1520 bool inCheckContext; |
| 1507 bool inCatchBlock; | 1521 bool inCatchBlock; |
| 1508 Scope scope; | 1522 Scope scope; |
| 1509 ClassElement currentClass; | 1523 ClassElement currentClass; |
| 1510 ExpressionStatement currentExpressionStatement; | 1524 ExpressionStatement currentExpressionStatement; |
| 1511 bool typeRequired = false; | 1525 bool typeRequired = false; |
| 1512 StatementScope statementScope; | 1526 StatementScope statementScope; |
| 1513 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION | 1527 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION |
| 1514 | ElementCategory.IMPLIES_TYPE; | 1528 | ElementCategory.IMPLIES_TYPE; |
| 1515 | 1529 |
| 1516 ResolverVisitor(Compiler compiler, Element element, this.mapping) | 1530 ResolverVisitor(Compiler compiler, Element element, this.mapping) |
| 1517 : this.enclosingElement = element, | 1531 : this.enclosingElement = element, |
| 1518 // When the element is a field, we are actually resolving its | 1532 // When the element is a field, we are actually resolving its |
| 1519 // initial value, which should not have access to instance | 1533 // initial value, which should not have access to instance |
| 1520 // fields. | 1534 // fields. |
| 1521 inInstanceContext = (element.isInstanceMember() && !element.isField()) | 1535 inInstanceContext = (element.isInstanceMember() && !element.isField()) |
| 1522 || element.isGenerativeConstructor(), | 1536 || element.isGenerativeConstructor(), |
| 1523 this.currentClass = element.isMember() ? element.getEnclosingClass() | 1537 this.currentClass = element.isMember() ? element.getEnclosingClass() |
| 1524 : null, | 1538 : null, |
| 1525 this.statementScope = new StatementScope(), | 1539 this.statementScope = new StatementScope(), |
| 1526 typeResolver = new TypeResolver(compiler), | 1540 typeResolver = new TypeResolver(compiler), |
| 1527 scope = element.buildScope(), | 1541 scope = element.buildScope(), |
| 1528 inCheckContext = compiler.enableTypeAssertions, | 1542 inCheckContext = compiler.enableTypeAssertions, |
| 1529 inCatchBlock = false, | 1543 inCatchBlock = false, |
| 1530 super(compiler); | 1544 super(compiler) { |
| 1545 typeResolver.context = this; | |
| 1546 } | |
| 1531 | 1547 |
| 1532 ResolutionEnqueuer get world => compiler.enqueuer.resolution; | 1548 ResolutionEnqueuer get world => compiler.enqueuer.resolution; |
| 1533 | 1549 |
| 1534 Element lookup(Node node, SourceString name) { | 1550 Element lookup(Node node, SourceString name) { |
| 1535 Element result = scope.lookup(name); | 1551 Element result = scope.lookup(name); |
| 1536 if (!Elements.isUnresolved(result)) { | 1552 if (!Elements.isUnresolved(result)) { |
| 1537 if (!inInstanceContext && result.isInstanceMember()) { | 1553 if (!inInstanceContext && result.isInstanceMember()) { |
| 1538 compiler.reportErrorCode( | 1554 compiler.reportErrorCode( |
| 1539 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); | 1555 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); |
| 1540 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, | 1556 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, |
| (...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2396 argument.element.enclosingElement); | 2412 argument.element.enclosingElement); |
| 2397 } else if (argument is InterfaceType) { | 2413 } else if (argument is InterfaceType) { |
| 2398 InterfaceType type = argument; | 2414 InterfaceType type = argument; |
| 2399 type.typeArguments.forEach((DartType argument) { | 2415 type.typeArguments.forEach((DartType argument) { |
| 2400 analyzeTypeArgument(type, argument); | 2416 analyzeTypeArgument(type, argument); |
| 2401 }); | 2417 }); |
| 2402 } | 2418 } |
| 2403 } | 2419 } |
| 2404 | 2420 |
| 2405 DartType resolveTypeAnnotation(TypeAnnotation node) { | 2421 DartType resolveTypeAnnotation(TypeAnnotation node) { |
| 2406 Function report = typeRequired ? error : warning; | 2422 DartType type = typeRequired ? |
| 2407 DartType type = typeResolver.resolveTypeAnnotation( | 2423 typeResolver.resolveTypeExpression(node) : |
| 2408 node, scope, enclosingElement, | 2424 typeResolver.resolveTypeAnnotation(node); |
| 2409 onFailure: report, whenResolved: useType); | |
| 2410 if (type == null) return null; | 2425 if (type == null) return null; |
| 2411 if (inCheckContext) { | 2426 if (inCheckContext) { |
| 2412 compiler.enqueuer.resolution.registerIsCheck(type); | 2427 compiler.enqueuer.resolution.registerIsCheck(type); |
| 2413 } | 2428 } |
| 2414 if (typeRequired || inCheckContext) { | 2429 if (typeRequired || inCheckContext) { |
| 2415 if (type is InterfaceType) { | 2430 if (type is InterfaceType) { |
| 2416 InterfaceType itf = type; | 2431 InterfaceType itf = type; |
| 2417 itf.typeArguments.forEach((DartType argument) { | 2432 itf.typeArguments.forEach((DartType argument) { |
| 2418 analyzeTypeArgument(type, argument); | 2433 analyzeTypeArgument(type, argument); |
| 2419 }); | 2434 }); |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2739 inCatchBlock = true; | 2754 inCatchBlock = true; |
| 2740 visitIn(node.block, blockScope); | 2755 visitIn(node.block, blockScope); |
| 2741 inCatchBlock = oldInCatchBlock; | 2756 inCatchBlock = oldInCatchBlock; |
| 2742 } | 2757 } |
| 2743 | 2758 |
| 2744 visitTypedef(Typedef node) { | 2759 visitTypedef(Typedef node) { |
| 2745 unimplemented(node, 'typedef'); | 2760 unimplemented(node, 'typedef'); |
| 2746 } | 2761 } |
| 2747 } | 2762 } |
| 2748 | 2763 |
| 2749 class TypeDefinitionVisitor extends CommonResolverVisitor<DartType> { | 2764 class TypeDefinitionVisitor extends CommonResolverVisitor<DartType> |
| 2765 implements TypeResolverContext { | |
| 2750 Scope scope; | 2766 Scope scope; |
| 2751 TypeDeclarationElement element; | 2767 final TypeDeclarationElement element; |
| 2752 TypeResolver typeResolver; | 2768 TypeResolver typeResolver; |
| 2769 Element get enclosingElement => element; | |
| 2753 | 2770 |
| 2754 TypeDefinitionVisitor(Compiler compiler, TypeDeclarationElement element) | 2771 TypeDefinitionVisitor(Compiler compiler, TypeDeclarationElement element) |
| 2755 : this.element = element, | 2772 : this.element = element, |
| 2756 scope = Scope.buildEnclosingScope(element), | 2773 scope = Scope.buildEnclosingScope(element), |
| 2757 typeResolver = new TypeResolver(compiler), | 2774 typeResolver = new TypeResolver(compiler), |
| 2758 super(compiler); | 2775 super(compiler) { |
| 2776 typeResolver.context = this; | |
| 2777 } | |
| 2778 | |
| 2779 void useType(Node node, DartType type) { | |
| 2780 // Do not register used types. | |
| 2781 } | |
| 2759 | 2782 |
| 2760 void resolveTypeVariableBounds(NodeList node) { | 2783 void resolveTypeVariableBounds(NodeList node) { |
| 2761 if (node == null) return; | 2784 if (node == null) return; |
| 2762 | 2785 |
| 2763 var nameSet = new Set<SourceString>(); | 2786 var nameSet = new Set<SourceString>(); |
| 2764 // Resolve the bounds of type variables. | 2787 // Resolve the bounds of type variables. |
| 2765 Link<DartType> typeLink = element.typeVariables; | 2788 Link<DartType> typeLink = element.typeVariables; |
| 2766 Link<Node> nodeLink = node.nodes; | 2789 Link<Node> nodeLink = node.nodes; |
| 2767 while (!nodeLink.isEmpty) { | 2790 while (!nodeLink.isEmpty) { |
| 2768 TypeVariableType typeVariable = typeLink.head; | 2791 TypeVariableType typeVariable = typeLink.head; |
| 2769 SourceString typeName = typeVariable.name; | 2792 SourceString typeName = typeVariable.name; |
| 2770 TypeVariable typeNode = nodeLink.head; | 2793 TypeVariable typeNode = nodeLink.head; |
| 2771 if (nameSet.contains(typeName)) { | 2794 if (nameSet.contains(typeName)) { |
| 2772 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, | 2795 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, |
| 2773 {'typeVariableName': typeName}); | 2796 {'typeVariableName': typeName}); |
| 2774 } | 2797 } |
| 2775 nameSet.add(typeName); | 2798 nameSet.add(typeName); |
| 2776 | 2799 |
| 2777 TypeVariableElement variableElement = typeVariable.element; | 2800 TypeVariableElement variableElement = typeVariable.element; |
| 2778 if (typeNode.bound != null) { | 2801 if (typeNode.bound != null) { |
| 2779 DartType boundType = typeResolver.resolveTypeAnnotation( | 2802 DartType boundType = typeResolver.resolveTypeAnnotation(typeNode.bound); |
| 2780 typeNode.bound, scope, element, onFailure: warning); | |
| 2781 if (boundType != null && boundType.element == variableElement) { | 2803 if (boundType != null && boundType.element == variableElement) { |
| 2782 // TODO(johnniwinther): Check for more general cycles, like | 2804 // TODO(johnniwinther): Check for more general cycles, like |
| 2783 // [: <A extends B, B extends C, C extends B> :]. | 2805 // [: <A extends B, B extends C, C extends B> :]. |
| 2784 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, | 2806 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, |
| 2785 {'typeVariableName': variableElement.name}); | 2807 {'typeVariableName': variableElement.name}); |
| 2786 } else if (boundType != null) { | 2808 } else if (boundType != null) { |
| 2787 variableElement.bound = boundType; | 2809 variableElement.bound = boundType; |
| 2788 } else { | 2810 } else { |
| 2789 // TODO(johnniwinther): Should be an erroneous type. | 2811 // TODO(johnniwinther): Should be an erroneous type. |
| 2790 variableElement.bound = compiler.objectClass.computeType(compiler); | 2812 variableElement.bound = compiler.objectClass.computeType(compiler); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2847 // TODO(ahe): It is not safe to call resolveTypeVariableBounds yet. | 2869 // TODO(ahe): It is not safe to call resolveTypeVariableBounds yet. |
| 2848 // As a side-effect, this may get us back here trying to | 2870 // As a side-effect, this may get us back here trying to |
| 2849 // resolve this class again. | 2871 // resolve this class again. |
| 2850 resolveTypeVariableBounds(node.typeParameters); | 2872 resolveTypeVariableBounds(node.typeParameters); |
| 2851 | 2873 |
| 2852 // Setup the supertype for the element. | 2874 // Setup the supertype for the element. |
| 2853 assert(element.supertype == null); | 2875 assert(element.supertype == null); |
| 2854 if (node.superclass != null) { | 2876 if (node.superclass != null) { |
| 2855 MixinApplication superMixin = node.superclass.asMixinApplication(); | 2877 MixinApplication superMixin = node.superclass.asMixinApplication(); |
| 2856 if (superMixin != null) { | 2878 if (superMixin != null) { |
| 2857 DartType supertype = resolveSupertype(element, superMixin.superclass); | 2879 DartType supertype = resolveSupertype(superMixin.superclass); |
| 2858 Link<Node> link = superMixin.mixins.nodes; | 2880 Link<Node> link = superMixin.mixins.nodes; |
| 2859 while (!link.isEmpty) { | 2881 while (!link.isEmpty) { |
| 2860 supertype = applyMixin(supertype, visit(link.head)); | 2882 supertype = applyMixin(supertype, visit(link.head)); |
| 2861 link = link.tail; | 2883 link = link.tail; |
| 2862 } | 2884 } |
| 2863 element.supertype = supertype; | 2885 element.supertype = supertype; |
| 2864 } else { | 2886 } else { |
| 2865 element.supertype = resolveSupertype(element, node.superclass); | 2887 element.supertype = resolveSupertype(node.superclass); |
| 2866 } | 2888 } |
| 2867 } | 2889 } |
| 2868 | 2890 |
| 2869 // If the super type isn't specified, we make it Object. | 2891 // If the super type isn't specified, we make it Object. |
| 2870 final objectElement = compiler.objectClass; | 2892 final objectElement = compiler.objectClass; |
| 2871 if (!identical(element, objectElement) && element.supertype == null) { | 2893 if (!identical(element, objectElement) && element.supertype == null) { |
| 2872 if (objectElement == null) { | 2894 if (objectElement == null) { |
| 2873 compiler.internalError("Internal error: cannot resolve Object", | 2895 compiler.internalError("Internal error: cannot resolve Object", |
| 2874 node: node); | 2896 node: node); |
| 2875 } else { | 2897 } else { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 2892 DartType visitNamedMixinApplication(NamedMixinApplication node) { | 2914 DartType visitNamedMixinApplication(NamedMixinApplication node) { |
| 2893 compiler.ensure(element != null); | 2915 compiler.ensure(element != null); |
| 2894 compiler.ensure(element.resolutionState == STATE_STARTED); | 2916 compiler.ensure(element.resolutionState == STATE_STARTED); |
| 2895 | 2917 |
| 2896 InterfaceType type = element.computeType(compiler); | 2918 InterfaceType type = element.computeType(compiler); |
| 2897 scope = new TypeDeclarationScope(scope, element); | 2919 scope = new TypeDeclarationScope(scope, element); |
| 2898 resolveTypeVariableBounds(node.typeParameters); | 2920 resolveTypeVariableBounds(node.typeParameters); |
| 2899 | 2921 |
| 2900 // Generate anonymous mixin application elements for the | 2922 // Generate anonymous mixin application elements for the |
| 2901 // intermediate mixin applications (excluding the last). | 2923 // intermediate mixin applications (excluding the last). |
| 2902 DartType supertype = resolveSupertype(element, node.superclass); | 2924 DartType supertype = resolveSupertype(node.superclass); |
| 2903 Link<Node> link = node.mixins.nodes; | 2925 Link<Node> link = node.mixins.nodes; |
| 2904 while (!link.tail.isEmpty) { | 2926 while (!link.tail.isEmpty) { |
| 2905 supertype = applyMixin(supertype, visit(link.head)); | 2927 supertype = applyMixin(supertype, visit(link.head)); |
| 2906 link = link.tail; | 2928 link = link.tail; |
| 2907 } | 2929 } |
| 2908 doApplyMixinTo(element, supertype, visit(link.head)); | 2930 doApplyMixinTo(element, supertype, visit(link.head)); |
| 2909 return element.computeType(compiler); | 2931 return element.computeType(compiler); |
| 2910 } | 2932 } |
| 2911 | 2933 |
| 2912 DartType applyMixin(DartType supertype, DartType mixinType) { | 2934 DartType applyMixin(DartType supertype, DartType mixinType) { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3021 Identifier selector = node.selector.asIdentifier(); | 3043 Identifier selector = node.selector.asIdentifier(); |
| 3022 var e = prefixElement.lookupLocalMember(selector.source); | 3044 var e = prefixElement.lookupLocalMember(selector.source); |
| 3023 if (e == null || !e.impliesType()) { | 3045 if (e == null || !e.impliesType()) { |
| 3024 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, | 3046 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, |
| 3025 {'typeName': node.selector}); | 3047 {'typeName': node.selector}); |
| 3026 return null; | 3048 return null; |
| 3027 } | 3049 } |
| 3028 return e.computeType(compiler); | 3050 return e.computeType(compiler); |
| 3029 } | 3051 } |
| 3030 | 3052 |
| 3031 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { | 3053 DartType resolveSupertype(TypeAnnotation superclass) { |
| 3032 DartType supertype = typeResolver.resolveTypeAnnotation( | 3054 DartType supertype = typeResolver.resolveTypeExpression(superclass); |
| 3033 superclass, scope, cls, onFailure: error); | |
| 3034 if (supertype != null) { | 3055 if (supertype != null) { |
| 3035 if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) { | 3056 if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) { |
| 3036 // Error has already been reported. | 3057 // Error has already been reported. |
| 3037 return null; | 3058 return null; |
| 3038 } else if (!identical(supertype.kind, TypeKind.INTERFACE)) { | 3059 } else if (!identical(supertype.kind, TypeKind.INTERFACE)) { |
| 3039 // TODO(johnniwinther): Handle dynamic. | 3060 // TODO(johnniwinther): Handle dynamic. |
| 3040 error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED); | 3061 error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED); |
| 3041 return null; | 3062 return null; |
| 3042 } else if (isBlackListed(supertype)) { | 3063 } else if (isBlackListed(supertype)) { |
| 3043 error(superclass, MessageKind.CANNOT_EXTEND, {'type': supertype}); | 3064 error(superclass, MessageKind.CANNOT_EXTEND, {'type': supertype}); |
| 3044 return null; | 3065 return null; |
| 3045 } | 3066 } |
| 3046 } | 3067 } |
| 3047 return supertype; | 3068 return supertype; |
| 3048 } | 3069 } |
| 3049 | 3070 |
| 3050 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { | 3071 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { |
| 3051 Link<DartType> result = const Link<DartType>(); | 3072 Link<DartType> result = const Link<DartType>(); |
| 3052 if (interfaces == null) return result; | 3073 if (interfaces == null) return result; |
| 3053 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { | 3074 for (TypeAnnotation interface in interfaces.nodes){ |
|
ahe
2013/02/05 11:26:29
Please avoid for-in.
| |
| 3054 DartType interfaceType = typeResolver.resolveTypeAnnotation( | 3075 DartType interfaceType = typeResolver.resolveTypeExpression(interface); |
| 3055 link.head, scope, element, onFailure: error); | |
| 3056 if (interfaceType != null) { | 3076 if (interfaceType != null) { |
| 3057 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) { | 3077 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) { |
| 3058 // Error has already been reported. | 3078 // Error has already been reported. |
| 3059 } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) { | 3079 } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) { |
| 3060 // TODO(johnniwinther): Handle dynamic. | 3080 // TODO(johnniwinther): Handle dynamic. |
| 3061 TypeAnnotation typeAnnotation = link.head; | 3081 error(interface.typeName, MessageKind.CLASS_NAME_EXPECTED); |
| 3062 error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); | |
| 3063 } else { | 3082 } else { |
| 3064 if (interfaceType == element.supertype) { | 3083 if (interfaceType == element.supertype) { |
| 3065 compiler.reportErrorCode( | 3084 compiler.reportErrorCode( |
| 3066 superclass, | 3085 superclass, |
| 3067 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, | 3086 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, |
| 3068 {'type': interfaceType}); | 3087 {'type': interfaceType}); |
| 3069 compiler.reportErrorCode( | 3088 compiler.reportErrorCode( |
| 3070 link.head, | 3089 interface, |
| 3071 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, | 3090 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, |
| 3072 {'type': interfaceType}); | 3091 {'type': interfaceType}); |
| 3073 } | 3092 } |
| 3074 if (result.contains(interfaceType)) { | 3093 if (result.contains(interfaceType)) { |
| 3075 compiler.reportErrorCode( | 3094 compiler.reportErrorCode( |
| 3076 link.head, | 3095 interface, |
| 3077 MessageKind.DUPLICATE_IMPLEMENTS, | 3096 MessageKind.DUPLICATE_IMPLEMENTS, |
| 3078 {'type': interfaceType}); | 3097 {'type': interfaceType}); |
| 3079 } | 3098 } |
| 3080 result = result.prepend(interfaceType); | 3099 result = result.prepend(interfaceType); |
| 3081 if (isBlackListed(interfaceType)) { | 3100 if (isBlackListed(interfaceType)) { |
| 3082 error(link.head, MessageKind.CANNOT_IMPLEMENT, | 3101 error(interface, MessageKind.CANNOT_IMPLEMENT, |
| 3083 {'type': interfaceType}); | 3102 {'type': interfaceType}); |
| 3084 } | 3103 } |
| 3085 } | 3104 } |
| 3086 } | 3105 } |
| 3087 } | 3106 } |
| 3088 return result; | 3107 return result; |
| 3089 } | 3108 } |
| 3090 | 3109 |
| 3091 void calculateAllSupertypes(ClassElement cls) { | 3110 void calculateAllSupertypes(ClassElement cls) { |
| 3092 // TODO(karlklose): Check if type arguments match, if a class | 3111 // TODO(karlklose): Check if type arguments match, if a class |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3623 return e; | 3642 return e; |
| 3624 } | 3643 } |
| 3625 | 3644 |
| 3626 /// Assumed to be called by [resolveRedirectingFactory]. | 3645 /// Assumed to be called by [resolveRedirectingFactory]. |
| 3627 Element visitReturn(Return node) { | 3646 Element visitReturn(Return node) { |
| 3628 Node expression = node.expression; | 3647 Node expression = node.expression; |
| 3629 return finishConstructorReference(visit(expression), | 3648 return finishConstructorReference(visit(expression), |
| 3630 expression, expression); | 3649 expression, expression); |
| 3631 } | 3650 } |
| 3632 } | 3651 } |
| OLD | NEW |