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

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: 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') | tests/co19/co19-dart2js.status » ('J')
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 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | tests/co19/co19-dart2js.status » ('j') | tests/co19/co19-dart2js.status » ('J')

Powered by Google App Engine
This is Rietveld 408576698