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

Side by Side Diff: pkg/compiler/lib/src/typechecker.dart

Issue 1363993004: Report info messages together with their error, warning, or hint. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comment. Created 5 years, 2 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
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 library dart2js.typechecker; 5 library dart2js.typechecker;
6 6
7 import 'common/names.dart' show 7 import 'common/names.dart' show
8 Identifiers; 8 Identifiers;
9 import 'common/tasks.dart' show 9 import 'common/tasks.dart' show
10 CompilerTask; 10 CompilerTask;
11 import 'compiler.dart' show 11 import 'compiler.dart' show
12 Compiler; 12 Compiler;
13 import 'constants/expressions.dart'; 13 import 'constants/expressions.dart';
14 import 'constants/values.dart'; 14 import 'constants/values.dart';
15 import 'core_types.dart'; 15 import 'core_types.dart';
16 import 'dart_types.dart'; 16 import 'dart_types.dart';
17 import 'diagnostics/diagnostic_listener.dart' show
18 DiagnosticMessage;
17 import 'diagnostics/invariant.dart' show 19 import 'diagnostics/invariant.dart' show
18 invariant; 20 invariant;
19 import 'diagnostics/messages.dart'; 21 import 'diagnostics/messages.dart';
20 import 'diagnostics/spannable.dart' show 22 import 'diagnostics/spannable.dart' show
21 Spannable; 23 Spannable;
22 import 'elements/elements.dart' show 24 import 'elements/elements.dart' show
23 AbstractFieldElement, 25 AbstractFieldElement,
24 AstElement, 26 AstElement,
25 AsyncMarker, 27 AsyncMarker,
26 ClassElement, 28 ClassElement,
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 final List<TypePromotionMessage> messages = <TypePromotionMessage>[]; 264 final List<TypePromotionMessage> messages = <TypePromotionMessage>[];
263 265
264 TypePromotion(this.node, this.variable, this.type); 266 TypePromotion(this.node, this.variable, this.type);
265 267
266 bool get isValid => messages.isEmpty; 268 bool get isValid => messages.isEmpty;
267 269
268 TypePromotion copy() { 270 TypePromotion copy() {
269 return new TypePromotion(node, variable, type)..messages.addAll(messages); 271 return new TypePromotion(node, variable, type)..messages.addAll(messages);
270 } 272 }
271 273
272 void addHint(Spannable spannable, MessageKind kind, [Map arguments]) { 274 void addHint(DiagnosticMessage hint,
273 messages.add(new TypePromotionMessage(api.Diagnostic.HINT, 275 [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) {
274 spannable, kind, arguments)); 276 messages.add(new TypePromotionMessage(hint, infos));
275 }
276
277 void addInfo(Spannable spannable, MessageKind kind, [Map arguments]) {
278 messages.add(new TypePromotionMessage(api.Diagnostic.INFO,
279 spannable, kind, arguments));
280 } 277 }
281 278
282 String toString() { 279 String toString() {
283 return 'Promote ${variable} to ${type}${isValid ? '' : ' (invalid)'}'; 280 return 'Promote ${variable} to ${type}${isValid ? '' : ' (invalid)'}';
284 } 281 }
285 } 282 }
286 283
287 /// A hint or info message attached to a type promotion. 284 /// A hint or info message attached to a type promotion.
288 class TypePromotionMessage { 285 class TypePromotionMessage {
289 api.Diagnostic diagnostic; 286 DiagnosticMessage hint;
290 Spannable spannable; 287 List<DiagnosticMessage> infos;
291 MessageKind messageKind;
292 Map messageArguments;
293 288
294 TypePromotionMessage(this.diagnostic, this.spannable, this.messageKind, 289 TypePromotionMessage(this.hint, this.infos);
295 [this.messageArguments]);
296 } 290 }
297 291
298 class TypeCheckerVisitor extends Visitor<DartType> { 292 class TypeCheckerVisitor extends Visitor<DartType> {
299 final Compiler compiler; 293 final Compiler compiler;
300 final TreeElements elements; 294 final TreeElements elements;
301 final Types types; 295 final Types types;
302 296
303 Node lastSeenNode; 297 Node lastSeenNode;
304 DartType expectedReturnType; 298 DartType expectedReturnType;
305 AsyncMarker currentAsyncMarker = AsyncMarker.SYNC; 299 AsyncMarker currentAsyncMarker = AsyncMarker.SYNC;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 // If these are used, an error should have been reported by the resolver. 387 // If these are used, an error should have been reported by the resolver.
394 thisType = const DynamicType(); 388 thisType = const DynamicType();
395 superType = const DynamicType(); 389 superType = const DynamicType();
396 } 390 }
397 } 391 }
398 392
399 LibraryElement get currentLibrary => elements.analyzedElement.library; 393 LibraryElement get currentLibrary => elements.analyzedElement.library;
400 394
401 reportTypeWarning(Spannable spannable, MessageKind kind, 395 reportTypeWarning(Spannable spannable, MessageKind kind,
402 [Map arguments = const {}]) { 396 [Map arguments = const {}]) {
403 compiler.reportWarning(spannable, kind, arguments); 397 compiler.reportWarningMessage(spannable, kind, arguments);
404 } 398 }
405 399
406 reportMessage(Spannable spannable, MessageKind kind, 400 reportMessage(Spannable spannable, MessageKind kind,
407 Map arguments, 401 Map arguments,
408 {bool isHint: false}) { 402 {bool isHint: false}) {
409 if (isHint) { 403 if (isHint) {
410 compiler.reportHint(spannable, kind, arguments); 404 compiler.reportHintMessage(spannable, kind, arguments);
411 } else { 405 } else {
412 compiler.reportWarning(spannable, kind, arguments); 406 compiler.reportWarningMessage(spannable, kind, arguments);
413 } 407 }
414 } 408 }
415 409
416 reportTypeInfo(Spannable spannable, MessageKind kind,
417 [Map arguments = const {}]) {
418 compiler.reportInfo(spannable, kind, arguments);
419 }
420
421 reportTypePromotionHint(TypePromotion typePromotion) { 410 reportTypePromotionHint(TypePromotion typePromotion) {
422 if (!reportedTypePromotions.contains(typePromotion)) { 411 if (!reportedTypePromotions.contains(typePromotion)) {
423 reportedTypePromotions.add(typePromotion); 412 reportedTypePromotions.add(typePromotion);
424 for (TypePromotionMessage message in typePromotion.messages) { 413 for (TypePromotionMessage message in typePromotion.messages) {
425 switch (message.diagnostic) { 414 compiler.reportHint(message.hint, message.infos);
426 case api.Diagnostic.HINT:
427 compiler.reportHint(message.spannable,
428 message.messageKind,
429 message.messageArguments);
430 break;
431 case api.Diagnostic.INFO:
432 compiler.reportInfo(message.spannable,
433 message.messageKind,
434 message.messageArguments);
435 break;
436 }
437 } 415 }
438 } 416 }
439 } 417 }
440 418
441 // TODO(karlklose): remove these functions. 419 // TODO(karlklose): remove these functions.
442 DartType unhandledExpression() => const DynamicType(); 420 DartType unhandledExpression() => const DynamicType();
443 421
444 DartType analyzeNonVoid(Node node) { 422 DartType analyzeNonVoid(Node node) {
445 DartType type = analyze(node); 423 DartType type = analyze(node);
446 if (type.isVoid) { 424 if (type.isVoid) {
(...skipping 29 matching lines...) Expand all
476 return result; 454 return result;
477 } 455 }
478 456
479 void checkTypePromotion(Node node, TypePromotion typePromotion, 457 void checkTypePromotion(Node node, TypePromotion typePromotion,
480 {bool checkAccesses: false}) { 458 {bool checkAccesses: false}) {
481 VariableElement variable = typePromotion.variable; 459 VariableElement variable = typePromotion.variable;
482 String variableName = variable.name; 460 String variableName = variable.name;
483 List<Node> potentialMutationsIn = 461 List<Node> potentialMutationsIn =
484 elements.getPotentialMutationsIn(node, variable); 462 elements.getPotentialMutationsIn(node, variable);
485 if (!potentialMutationsIn.isEmpty) { 463 if (!potentialMutationsIn.isEmpty) {
486 typePromotion.addHint(typePromotion.node, 464 DiagnosticMessage hint = compiler.createMessage(
465 typePromotion.node,
487 MessageKind.POTENTIAL_MUTATION, 466 MessageKind.POTENTIAL_MUTATION,
488 {'variableName': variableName, 'shownType': typePromotion.type}); 467 {'variableName': variableName, 'shownType': typePromotion.type});
468 List<DiagnosticMessage> infos = <DiagnosticMessage>[];
489 for (Node mutation in potentialMutationsIn) { 469 for (Node mutation in potentialMutationsIn) {
490 typePromotion.addInfo(mutation, 470 infos.add(compiler.createMessage(mutation,
491 MessageKind.POTENTIAL_MUTATION_HERE, 471 MessageKind.POTENTIAL_MUTATION_HERE,
492 {'variableName': variableName}); 472 {'variableName': variableName}));
493 } 473 }
474 typePromotion.addHint(hint, infos);
494 } 475 }
495 List<Node> potentialMutationsInClosures = 476 List<Node> potentialMutationsInClosures =
496 elements.getPotentialMutationsInClosure(variable); 477 elements.getPotentialMutationsInClosure(variable);
497 if (!potentialMutationsInClosures.isEmpty) { 478 if (!potentialMutationsInClosures.isEmpty) {
498 typePromotion.addHint(typePromotion.node, 479 DiagnosticMessage hint = compiler.createMessage(
480 typePromotion.node,
499 MessageKind.POTENTIAL_MUTATION_IN_CLOSURE, 481 MessageKind.POTENTIAL_MUTATION_IN_CLOSURE,
500 {'variableName': variableName, 'shownType': typePromotion.type}); 482 {'variableName': variableName, 'shownType': typePromotion.type});
483 List<DiagnosticMessage> infos = <DiagnosticMessage>[];
501 for (Node mutation in potentialMutationsInClosures) { 484 for (Node mutation in potentialMutationsInClosures) {
502 typePromotion.addInfo(mutation, 485 infos.add(compiler.createMessage(
486 mutation,
503 MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE, 487 MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE,
504 {'variableName': variableName}); 488 {'variableName': variableName}));
505 } 489 }
490 typePromotion.addHint(hint, infos);
506 } 491 }
507 if (checkAccesses) { 492 if (checkAccesses) {
508 List<Node> accesses = elements.getAccessesByClosureIn(node, variable); 493 List<Node> accesses = elements.getAccessesByClosureIn(node, variable);
509 List<Node> mutations = elements.getPotentialMutations(variable); 494 List<Node> mutations = elements.getPotentialMutations(variable);
510 if (!accesses.isEmpty && !mutations.isEmpty) { 495 if (!accesses.isEmpty && !mutations.isEmpty) {
511 typePromotion.addHint(typePromotion.node, 496 DiagnosticMessage hint = compiler.createMessage(
497 typePromotion.node,
512 MessageKind.ACCESSED_IN_CLOSURE, 498 MessageKind.ACCESSED_IN_CLOSURE,
513 {'variableName': variableName, 'shownType': typePromotion.type}); 499 {'variableName': variableName, 'shownType': typePromotion.type});
500 List<DiagnosticMessage> infos = <DiagnosticMessage>[];
514 for (Node access in accesses) { 501 for (Node access in accesses) {
515 typePromotion.addInfo(access, 502 infos.add(compiler.createMessage(
503 access,
516 MessageKind.ACCESSED_IN_CLOSURE_HERE, 504 MessageKind.ACCESSED_IN_CLOSURE_HERE,
517 {'variableName': variableName}); 505 {'variableName': variableName}));
518 } 506 }
519 for (Node mutation in mutations) { 507 for (Node mutation in mutations) {
520 typePromotion.addInfo(mutation, 508 infos.add(compiler.createMessage(
509 mutation,
521 MessageKind.POTENTIAL_MUTATION_HERE, 510 MessageKind.POTENTIAL_MUTATION_HERE,
522 {'variableName': variableName}); 511 {'variableName': variableName}));
523 } 512 }
513 typePromotion.addHint(hint, infos);
524 } 514 }
525 } 515 }
526 } 516 }
527 517
528 /// Show type promotions from [left] and [right] in [node] given that the 518 /// Show type promotions from [left] and [right] in [node] given that the
529 /// promoted variables are not potentially mutated in [right]. 519 /// promoted variables are not potentially mutated in [right].
530 void reshowTypePromotions(Node node, Node left, Node right) { 520 void reshowTypePromotions(Node node, Node left, Node right) {
531 for (TypePromotion typePromotion in getShownTypePromotionsFor(left)) { 521 for (TypePromotion typePromotion in getShownTypePromotionsFor(left)) {
532 typePromotion = typePromotion.copy(); 522 typePromotion = typePromotion.copy();
533 checkTypePromotion(right, typePromotion); 523 checkTypePromotion(right, typePromotion);
(...skipping 29 matching lines...) Expand all
563 553
564 /** 554 /**
565 * Check if a value of type [from] can be assigned to a variable, parameter or 555 * Check if a value of type [from] can be assigned to a variable, parameter or
566 * return value of type [to]. If `isConst == true`, an error is emitted in 556 * return value of type [to]. If `isConst == true`, an error is emitted in
567 * checked mode, otherwise a warning is issued. 557 * checked mode, otherwise a warning is issued.
568 */ 558 */
569 bool checkAssignable(Spannable spannable, DartType from, DartType to, 559 bool checkAssignable(Spannable spannable, DartType from, DartType to,
570 {bool isConst: false}) { 560 {bool isConst: false}) {
571 if (!types.isAssignable(from, to)) { 561 if (!types.isAssignable(from, to)) {
572 if (compiler.enableTypeAssertions && isConst) { 562 if (compiler.enableTypeAssertions && isConst) {
573 compiler.reportError(spannable, MessageKind.NOT_ASSIGNABLE, 563 compiler.reportErrorMessage(
574 {'fromType': from, 'toType': to}); 564 spannable,
565 MessageKind.NOT_ASSIGNABLE,
566 {'fromType': from, 'toType': to});
575 } else { 567 } else {
576 reportTypeWarning(spannable, MessageKind.NOT_ASSIGNABLE, 568 compiler.reportWarningMessage(
577 {'fromType': from, 'toType': to}); 569 spannable,
570 MessageKind.NOT_ASSIGNABLE,
571 {'fromType': from, 'toType': to});
578 } 572 }
579 return false; 573 return false;
580 } 574 }
581 return true; 575 return true;
582 } 576 }
583 577
584 checkCondition(Expression condition) { 578 checkCondition(Expression condition) {
585 checkAssignable(condition, analyze(condition), boolType); 579 checkAssignable(condition, analyze(condition), boolType);
586 } 580 }
587 581
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 {bool isHint: false}) { 879 {bool isHint: false}) {
886 return lookupMember(node, type, name, memberKind, null, isHint: isHint) 880 return lookupMember(node, type, name, memberKind, null, isHint: isHint)
887 .computeType(compiler); 881 .computeType(compiler);
888 } 882 }
889 883
890 void analyzeArguments(Send send, Element element, DartType type, 884 void analyzeArguments(Send send, Element element, DartType type,
891 [LinkBuilder<DartType> argumentTypes]) { 885 [LinkBuilder<DartType> argumentTypes]) {
892 Link<Node> arguments = send.arguments; 886 Link<Node> arguments = send.arguments;
893 DartType unaliasedType = type.unalias(compiler); 887 DartType unaliasedType = type.unalias(compiler);
894 if (identical(unaliasedType.kind, TypeKind.FUNCTION)) { 888 if (identical(unaliasedType.kind, TypeKind.FUNCTION)) {
895 bool error = false; 889
890 /// Report [warning] including info(s) about the declaration of [element]
891 /// or [type].
892 void reportWarning(DiagnosticMessage warning) {
893 // TODO(johnniwinther): Support pointing to individual parameters on
894 // assignability warnings.
895 List<DiagnosticMessage> infos = <DiagnosticMessage>[];
896 Element declaration = element;
897 if (declaration == null) {
898 declaration = type.element;
899 } else if (type.isTypedef) {
900 infos.add(compiler.createMessage(
901 declaration,
902 MessageKind.THIS_IS_THE_DECLARATION,
903 {'name': element.name}));
904 declaration = type.element;
905 }
906 if (declaration != null) {
907 infos.add(compiler.createMessage(
908 declaration, MessageKind.THIS_IS_THE_METHOD));
909 }
910 compiler.reportWarning(warning, infos);
911 }
912
913 /// Report a warning on [node] if [argumentType] is not assignable to
914 /// [parameterType].
915 void checkAssignable(Spannable node,
916 DartType argumentType,
917 DartType parameterType) {
918 if (!types.isAssignable(argumentType, parameterType)) {
919 reportWarning(compiler.createMessage(
920 node,
921 MessageKind.NOT_ASSIGNABLE,
922 {'fromType': argumentType, 'toType': parameterType}));
923 }
924 }
925
896 FunctionType funType = unaliasedType; 926 FunctionType funType = unaliasedType;
897 Iterator<DartType> parameterTypes = funType.parameterTypes.iterator; 927 Iterator<DartType> parameterTypes = funType.parameterTypes.iterator;
898 Iterator<DartType> optionalParameterTypes = 928 Iterator<DartType> optionalParameterTypes =
899 funType.optionalParameterTypes.iterator; 929 funType.optionalParameterTypes.iterator;
900 while (!arguments.isEmpty) { 930 while (!arguments.isEmpty) {
901 Node argument = arguments.head; 931 Node argument = arguments.head;
902 NamedArgument namedArgument = argument.asNamedArgument(); 932 NamedArgument namedArgument = argument.asNamedArgument();
903 if (namedArgument != null) { 933 if (namedArgument != null) {
904 argument = namedArgument.expression; 934 argument = namedArgument.expression;
905 String argumentName = namedArgument.name.source; 935 String argumentName = namedArgument.name.source;
906 DartType namedParameterType = 936 DartType namedParameterType =
907 funType.getNamedParameterType(argumentName); 937 funType.getNamedParameterType(argumentName);
908 if (namedParameterType == null) { 938 if (namedParameterType == null) {
909 error = true;
910 // TODO(johnniwinther): Provide better information on the called 939 // TODO(johnniwinther): Provide better information on the called
911 // function. 940 // function.
912 reportTypeWarning(argument, MessageKind.NAMED_ARGUMENT_NOT_FOUND, 941 reportWarning(compiler.createMessage(
913 {'argumentName': argumentName}); 942 argument,
943 MessageKind.NAMED_ARGUMENT_NOT_FOUND,
944 {'argumentName': argumentName}));
914 945
915 DartType argumentType = analyze(argument); 946 DartType argumentType = analyze(argument);
916 if (argumentTypes != null) argumentTypes.addLast(argumentType); 947 if (argumentTypes != null) argumentTypes.addLast(argumentType);
917 } else { 948 } else {
918 DartType argumentType = analyze(argument); 949 DartType argumentType = analyze(argument);
919 if (argumentTypes != null) argumentTypes.addLast(argumentType); 950 if (argumentTypes != null) argumentTypes.addLast(argumentType);
920 if (!checkAssignable(argument, argumentType, namedParameterType)) { 951 checkAssignable(argument, argumentType, namedParameterType);
921 error = true;
922 }
923 } 952 }
924 } else { 953 } else {
925 if (!parameterTypes.moveNext()) { 954 if (!parameterTypes.moveNext()) {
926 if (!optionalParameterTypes.moveNext()) { 955 if (!optionalParameterTypes.moveNext()) {
927 error = true; 956
928 // TODO(johnniwinther): Provide better information on the 957 // TODO(johnniwinther): Provide better information on the
929 // called function. 958 // called function.
930 reportTypeWarning(argument, MessageKind.ADDITIONAL_ARGUMENT); 959 reportWarning(compiler.createMessage(
960 argument, MessageKind.ADDITIONAL_ARGUMENT));
931 961
932 DartType argumentType = analyze(argument); 962 DartType argumentType = analyze(argument);
933 if (argumentTypes != null) argumentTypes.addLast(argumentType); 963 if (argumentTypes != null) argumentTypes.addLast(argumentType);
934 } else { 964 } else {
935 DartType argumentType = analyze(argument); 965 DartType argumentType = analyze(argument);
936 if (argumentTypes != null) argumentTypes.addLast(argumentType); 966 if (argumentTypes != null) argumentTypes.addLast(argumentType);
937 if (!checkAssignable(argument, 967 checkAssignable(
938 argumentType, 968 argument, argumentType, optionalParameterTypes.current);
939 optionalParameterTypes.current)) {
940 error = true;
941 }
942 } 969 }
943 } else { 970 } else {
944 DartType argumentType = analyze(argument); 971 DartType argumentType = analyze(argument);
945 if (argumentTypes != null) argumentTypes.addLast(argumentType); 972 if (argumentTypes != null) argumentTypes.addLast(argumentType);
946 if (!checkAssignable(argument, argumentType, 973 checkAssignable(argument, argumentType, parameterTypes.current);
947 parameterTypes.current)) {
948 error = true;
949 }
950 } 974 }
951 } 975 }
952 arguments = arguments.tail; 976 arguments = arguments.tail;
953 } 977 }
954 if (parameterTypes.moveNext()) { 978 if (parameterTypes.moveNext()) {
955 error = true;
956 // TODO(johnniwinther): Provide better information on the called 979 // TODO(johnniwinther): Provide better information on the called
957 // function. 980 // function.
958 reportTypeWarning(send, MessageKind.MISSING_ARGUMENT, 981 reportWarning(compiler.createMessage(
959 {'argumentType': parameterTypes.current}); 982 send, MessageKind.MISSING_ARGUMENT,
960 } 983 {'argumentType': parameterTypes.current}));
961 if (error) {
962 // TODO(johnniwinther): Improve access to declaring element and handle
963 // synthesized member signatures. Currently function typed instance
964 // members provide no access to their own name.
965 if (element == null) {
966 element = type.element;
967 } else if (type.isTypedef) {
968 reportTypeInfo(element,
969 MessageKind.THIS_IS_THE_DECLARATION,
970 {'name': element.name});
971 element = type.element;
972 }
973 if (element != null) {
974 reportTypeInfo(element, MessageKind.THIS_IS_THE_METHOD);
975 }
976 } 984 }
977 } else { 985 } else {
978 while(!arguments.isEmpty) { 986 while(!arguments.isEmpty) {
979 DartType argumentType = analyze(arguments.head); 987 DartType argumentType = analyze(arguments.head);
980 if (argumentTypes != null) argumentTypes.addLast(argumentType); 988 if (argumentTypes != null) argumentTypes.addLast(argumentType);
981 arguments = arguments.tail; 989 arguments = arguments.tail;
982 } 990 }
983 } 991 }
984 } 992 }
985 993
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 if (variable != null && 1214 if (variable != null &&
1207 (variable.isVariable || variable.isParameter)) { 1215 (variable.isVariable || variable.isParameter)) {
1208 DartType knownType = getKnownType(variable); 1216 DartType knownType = getKnownType(variable);
1209 if (!knownType.isDynamic) { 1217 if (!knownType.isDynamic) {
1210 DartType shownType = elements.getType(node.arguments.head); 1218 DartType shownType = elements.getType(node.arguments.head);
1211 TypePromotion typePromotion = 1219 TypePromotion typePromotion =
1212 new TypePromotion(node, variable, shownType); 1220 new TypePromotion(node, variable, shownType);
1213 if (!types.isMoreSpecific(shownType, knownType)) { 1221 if (!types.isMoreSpecific(shownType, knownType)) {
1214 String variableName = variable.name; 1222 String variableName = variable.name;
1215 if (!types.isSubtype(shownType, knownType)) { 1223 if (!types.isSubtype(shownType, knownType)) {
1216 typePromotion.addHint(node, 1224 typePromotion.addHint(compiler.createMessage(
1225 node,
1217 MessageKind.NOT_MORE_SPECIFIC_SUBTYPE, 1226 MessageKind.NOT_MORE_SPECIFIC_SUBTYPE,
1218 {'variableName': variableName, 1227 {'variableName': variableName,
1219 'shownType': shownType, 1228 'shownType': shownType,
1220 'knownType': knownType}); 1229 'knownType': knownType}));
1221 } else { 1230 } else {
1222 DartType shownTypeSuggestion = 1231 DartType shownTypeSuggestion =
1223 computeMoreSpecificType(shownType, knownType); 1232 computeMoreSpecificType(shownType, knownType);
1224 if (shownTypeSuggestion != null) { 1233 if (shownTypeSuggestion != null) {
1225 typePromotion.addHint(node, 1234 typePromotion.addHint(compiler.createMessage(
1235 node,
1226 MessageKind.NOT_MORE_SPECIFIC_SUGGESTION, 1236 MessageKind.NOT_MORE_SPECIFIC_SUGGESTION,
1227 {'variableName': variableName, 1237 {'variableName': variableName,
1228 'shownType': shownType, 1238 'shownType': shownType,
1229 'shownTypeSuggestion': shownTypeSuggestion, 1239 'shownTypeSuggestion': shownTypeSuggestion,
1230 'knownType': knownType}); 1240 'knownType': knownType}));
1231 } else { 1241 } else {
1232 typePromotion.addHint(node, 1242 typePromotion.addHint(compiler.createMessage(
1243 node,
1233 MessageKind.NOT_MORE_SPECIFIC, 1244 MessageKind.NOT_MORE_SPECIFIC,
1234 {'variableName': variableName, 1245 {'variableName': variableName,
1235 'shownType': shownType, 1246 'shownType': shownType,
1236 'knownType': knownType}); 1247 'knownType': knownType}));
1237 } 1248 }
1238 } 1249 }
1239 } 1250 }
1240 showTypePromotion(node, typePromotion); 1251 showTypePromotion(node, typePromotion);
1241 } 1252 }
1242 } 1253 }
1243 } 1254 }
1244 return boolType; 1255 return boolType;
1245 } if (node.isOperator && identical(name, 'as')) { 1256 } if (node.isOperator && identical(name, 'as')) {
1246 analyze(node.receiver); 1257 analyze(node.receiver);
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after
1918 ConstantExpression caseConstant = 1929 ConstantExpression caseConstant =
1919 compiler.resolver.constantCompiler.compileNode( 1930 compiler.resolver.constantCompiler.compileNode(
1920 caseMatch.expression, elements); 1931 caseMatch.expression, elements);
1921 enumValues.remove( 1932 enumValues.remove(
1922 compiler.constants.getConstantValue(caseConstant)); 1933 compiler.constants.getConstantValue(caseConstant));
1923 } 1934 }
1924 } 1935 }
1925 } 1936 }
1926 unreferencedFields.addAll(enumValues.values); 1937 unreferencedFields.addAll(enumValues.values);
1927 if (!unreferencedFields.isEmpty) { 1938 if (!unreferencedFields.isEmpty) {
1928 compiler.reportWarning(node, MessageKind.MISSING_ENUM_CASES, 1939 compiler.reportWarningMessage(
1940 node, MessageKind.MISSING_ENUM_CASES,
1929 {'enumType': expressionType, 1941 {'enumType': expressionType,
1930 'enumValues': unreferencedFields.map((e) => e.name).join(', ')}); 1942 'enumValues': unreferencedFields.map(
1943 (e) => e.name).join(', ')});
1931 } 1944 }
1932 }); 1945 });
1933 } 1946 }
1934 1947
1935 return const StatementType(); 1948 return const StatementType();
1936 } 1949 }
1937 1950
1938 visitSwitchCase(SwitchCase node) { 1951 visitSwitchCase(SwitchCase node) {
1939 return analyze(node.statements); 1952 return analyze(node.statements);
1940 } 1953 }
(...skipping 16 matching lines...) Expand all
1957 1970
1958 visitTypedef(Typedef node) { 1971 visitTypedef(Typedef node) {
1959 // Do not typecheck [Typedef] nodes. 1972 // Do not typecheck [Typedef] nodes.
1960 } 1973 }
1961 1974
1962 visitNode(Node node) { 1975 visitNode(Node node) {
1963 compiler.internalError(node, 1976 compiler.internalError(node,
1964 'Unexpected node ${node.getObjectDescription()} in the type checker.'); 1977 'Unexpected node ${node.getObjectDescription()} in the type checker.');
1965 } 1978 }
1966 } 1979 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/string_validator.dart ('k') | tests/compiler/dart2js/analyze_unused_dart2js_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698