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

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

Issue 21242002: Retain elements a finer granularity than library. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address review comments Created 7 years, 4 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
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 dart2js; 5 part of dart2js;
6 6
7 /** 7 /**
8 * The messages in this file should meet the following guide lines: 8 * The messages in this file should meet the following guide lines:
9 * 9 *
10 * 1. The message should start with exactly one of "Error", "Internal error", 10 * 1. The message should start with exactly one of "Error", "Internal error",
11 * "Warning", "Info", or "Hint" followed by a colon. It is crucial to users to 11 * "Warning", "Info", or "Hint" followed by a colon. It is crucial to users to
12 * be able to locate errors in the midst of warnings, but we are operating 12 * be able to locate errors in the midst of warnings.
13 * under the assumption that these messages will eventually be translated to 13 * TODO(ahe): Remove these prefixes from the error message.
14 * other languages than English, and that it is therefor not possible to
15 * automatically apply these prefixes.
16 * 14 *
17 * 2. After the colon, one space and a complete sentence starting with an 15 * 2. After the colon, one space and a complete sentence starting with an
18 * uppercase letter, and ending with a period. 16 * uppercase letter, and ending with a period.
19 * 17 *
20 * 3. Reserved words and embedded identifiers should be in quotes (double 18 * 3. Reserved words and embedded identifiers should be in single quotes, so
21 * quotes), so prefer single quotes for the complete message. For example, 19 * prefer double quotes for the complete message. For example, "Error: The
22 * 'Error: The class "#{className}" cannot use "super".' Notice that the word 20 * class '#{className}' can't use 'super'." Notice that the word 'class' in the
23 * "class" in the preceding message is not quoted as it refers to the concept 21 * preceding message is not quoted as it refers to the concept 'class', not the
24 * "class", not the reserved word. On the other hand, "super" refers to the 22 * reserved word. On the other hand, 'super' refers to the reserved word. Do
25 * reserved word. Do not quote "null" and numeric literals. 23 * not quote 'null' and numeric literals.
26 * 24 *
27 * 4. Do not try to compose messages, as it can make translating them hard. 25 * 4. Do not try to compose messages, as it can make translating them hard.
28 * 26 *
29 * 5. Try to keep the error messages short, but informative. 27 * 5. Try to keep the error messages short, but informative.
30 * 28 *
31 * 6. Use simple words and terminology, assume the reader of the message does 29 * 6. Use simple words and terminology, assume the reader of the message
32 * not have an advanced degree in math, and that English is not the reader's 30 * doesn't have an advanced degree in math, and that English is not the
33 * native language. Do not assume any formal computer science training. For 31 * reader's native language. Do not assume any formal computer science
34 * example, do not use Latin abbreviations (prefer "that is" over "i.e.", and 32 * training. For example, do not use Latin abbreviations (prefer "that is" over
35 * "for example" over "e.g."). Also avoid phrases such as "if and only if" and 33 * "i.e.", and "for example" over "e.g."). Also avoid phrases such as "if and
36 * "iff", that level of precision is unnecessary. 34 * only if" and "iff", that level of precision is unnecessary.
37 * 35 *
38 * 7. Do not use contractions, for example, prefer "cannot" over "can't". This 36 * 7. Prefer contractions when they are in common use, for example, prefer
39 * is again to benefit readers to whom English is not their first language. 37 * "can't" over "cannot". Using "cannot", "must not", "shall not", etc. is
38 * off-putting to people new to programming.
40 * 39 *
41 * 8. Use common terminology, preferably from the Dart Language 40 * 8. Use common terminology, preferably from the Dart Language
42 * Specification. This increases the user's chance of finding a good 41 * Specification. This increases the user's chance of finding a good
43 * explanation on the web. 42 * explanation on the web.
44 * 43 *
45 * 9. Do not try to be cute or funny. It is extremely frustrating to work on a 44 * 9. Do not try to be cute or funny. It is extremely frustrating to work on a
46 * product that crashes with a "tongue-in-cheek" message, especially if you did 45 * product that crashes with a "tongue-in-cheek" message, especially if you did
47 * not want to use this product to begin with with. 46 * not want to use this product to begin with with.
48 * 47 *
49 * 10. Do not lie, that is, do not write error messages containing phrases like 48 * 10. Do not lie, that is, do not write error messages containing phrases like
50 * "cannot happen". If the user ever saw this message, it would be a 49 * "can't happen". If the user ever saw this message, it would be a
51 * lie. Prefer messages like: 'Internal error: This function should not be 50 * lie. Prefer messages like: "Internal error: This function should not be
52 * called when "x" is null.'. 51 * called when 'x' is null.".
52 *
53 * 11. Prefer to not use imperative tone. That is, the message should not sound
54 * accusing or like it is ordering the user around. The computer should
55 * describe the problem, not criticize for violating the specification.
56 *
57 * Other things to keep in mind:
58 *
59 * An INFO message should always be preceded by a non-INFO message, and the
60 * INFO messages are additional details about the preceding non-INFO
61 * message. For example, consider duplicated elements. First report a WARNING
62 * or ERROR about the duplicated element, and then report an INFO about the
63 * location of the existing element.
64 *
65 * Generally, we want to provide messages that consists of three sentences:
66 * 1. what is wrong, 2. why is it wrong, 3. how do I fix it. However, we
67 * combine the first two in [template] and the last in [howToFix].
53 */ 68 */
54 class MessageKind { 69 class MessageKind {
70 /// Should describe what is wrong and why.
55 final String template; 71 final String template;
56 const MessageKind(this.template); 72
73 /// Should describe how to fix the problem. Elided when using --terse option.
74 final String howToFix;
75
76 /// Examples will be checked by
77 /// tests/compiler/dart2js/message_kind_test.dart.
78 final List<String> examples;
79
80 const MessageKind(this.template, {this.howToFix, this.examples});
57 81
58 /// Do not use this. It is here for legacy and debugging. It violates item 4 82 /// Do not use this. It is here for legacy and debugging. It violates item 4
59 /// above. 83 /// above.
60 static const MessageKind GENERIC = const MessageKind('#{text}'); 84 static const MessageKind GENERIC = const MessageKind('#{text}');
61 85
62 static const DualKind NOT_ASSIGNABLE = const DualKind( 86 static const DualKind NOT_ASSIGNABLE = const DualKind(
63 error: const MessageKind( 87 error: const MessageKind(
64 'Error: "#{fromType}" is not assignable to "#{toType}".'), 88 'Error: "#{fromType}" is not assignable to "#{toType}".'),
65 warning: const MessageKind( 89 warning: const MessageKind(
66 'Warning: "#{fromType}" is not assignable to "#{toType}".')); 90 'Warning: "#{fromType}" is not assignable to "#{toType}".'));
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 'Did you mean "#{lhs} == #{rhs}" or "identical(#{lhs}, #{rhs})"?'); 636 'Did you mean "#{lhs} == #{rhs}" or "identical(#{lhs}, #{rhs})"?');
613 637
614 static const MessageKind UNSUPPORTED_BANG_EQ_EQ = const MessageKind( 638 static const MessageKind UNSUPPORTED_BANG_EQ_EQ = const MessageKind(
615 'Error: "!==" is not an operator. ' 639 'Error: "!==" is not an operator. '
616 'Did you mean "#{lhs} != #{rhs}" or "!identical(#{lhs}, #{rhs})"?'); 640 'Did you mean "#{lhs} != #{rhs}" or "!identical(#{lhs}, #{rhs})"?');
617 641
618 static const MessageKind UNSUPPORTED_THROW_WITHOUT_EXP = const MessageKind( 642 static const MessageKind UNSUPPORTED_THROW_WITHOUT_EXP = const MessageKind(
619 'Error: No expression after "throw". ' 643 'Error: No expression after "throw". '
620 'Did you mean "rethrow"?'); 644 'Did you mean "rethrow"?');
621 645
646 static const MessageKind MIRRORS_EXPECTED_STRING = const MessageKind(
647 "Hint: Can't use '#{name}' here because it's an instance of '#{type}' "
648 "and a 'String' value is expected.",
649 howToFix: "Did you forget to add quotes?",
650 examples: const [
651 """
652 // 'main' is a method, not a class.
653 @MirrorsUsed(symbols: const [Foo])
654 import 'dart:mirrors';
655
656 class Foo {}
657
658 main() {}
659 """]);
660
661 static const MessageKind MIRRORS_EXPECTED_STRING_OR_TYPE = const MessageKind(
662 "Hint: Can't use '#{name}' here because it's an instance of '#{type}' "
663 "and a 'String' or 'Type' value is expected.",
664 howToFix: "Did you forget to add quotes?",
665 examples: const [
666 """
667 // 'main' is a method, not a class.
668 @MirrorsUsed(targets: const [main])
669 import 'dart:mirrors';
670
671 main() {}
672 """]);
673
674 static const MessageKind MIRRORS_EXPECTED_STRING_OR_LIST = const MessageKind(
675 "Hint: Can't use '#{name}' here because it's an instance of '#{type}' "
676 "and a 'String' or 'List' value is expected.",
677 howToFix: "Did you forget to add quotes?",
678 examples: const [
679 """
680 // 'Foo' is not a string.
681 @MirrorsUsed(symbols: Foo)
682 import 'dart:mirrors';
683
684 class Foo {}
685
686 main() {}
687 """]);
688
689 static const MessageKind MIRRORS_EXPECTED_STRING_TYPE_OR_LIST =
690 const MessageKind(
691 "Hint: Can't use '#{name}' here because it's an instance of '#{type}' "
692 "but a 'String', 'Type', or 'List' value is expected.",
693 howToFix: "Did you forget to add quotes?",
694 examples: const [
695 """
696 // '1' is not a string.
697 @MirrorsUsed(targets: 1)
698 import 'dart:mirrors';
699
700 main() {}
701 """]);
702
703 static const MessageKind MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY =
704 const MessageKind(
705 "Hint: Can't find '#{name}' in the current library.",
706 // TODO(ahe): The closest identifiers in edit distance would be nice.
707 howToFix: "Did you forget to add an import?",
708 examples: const [
709 """
710 // 'window' is not in scope because dart:html isn't imported.
711 @MirrorsUsed(targets: 'window')
712 import 'dart:mirrors';
713
714 main() {}
715 """]);
716
717 static const MessageKind MIRRORS_CANNOT_RESOLVE_IN_LIBRARY =
718 const MessageKind(
719 "Hint: Can't find '#{name}' in the library '#{library}'.",
720 // TODO(ahe): The closest identifiers in edit distance would be nice.
721 howToFix: "Is '#{name}' spelled right?",
722 examples: const [
723 """
724 // 'List' is misspelled.
725 @MirrorsUsed(targets: 'dart.core.Lsit')
726 import 'dart:mirrors';
727
728 main() {}
729 """]);
730
731 static const MessageKind MIRRORS_CANNOT_FIND_IN_ELEMENT =
732 const MessageKind(
733 "Hint: Can't find '#{name}' in '#{element}'.",
734 // TODO(ahe): The closest identifiers in edit distance would be nice.
735 howToFix: "Is '#{name}' spelled right?",
736 examples: const [
737 """
738 // 'addAll' is misspelled.
739 @MirrorsUsed(targets: 'dart.core.List.addAl')
740 import 'dart:mirrors';
741
742 main() {}
743 """]);
744
622 static const MessageKind COMPILER_CRASHED = const MessageKind( 745 static const MessageKind COMPILER_CRASHED = const MessageKind(
623 'Error: The compiler crashed when compiling this element.'); 746 'Error: The compiler crashed when compiling this element.');
624 747
625 static const MessageKind PLEASE_REPORT_THE_CRASH = const MessageKind(''' 748 static const MessageKind PLEASE_REPORT_THE_CRASH = const MessageKind('''
626 The compiler is broken. 749 The compiler is broken.
627 750
628 When compiling the above element, the compiler crashed. It is not 751 When compiling the above element, the compiler crashed. It is not
629 possible to tell if this is caused by a problem in your program or 752 possible to tell if this is caused by a problem in your program or
630 not. Regardless, the compiler should not crash. 753 not. Regardless, the compiler should not crash.
631 754
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 static const MessageKind PATCH_NON_FUNCTION = const MessageKind( 852 static const MessageKind PATCH_NON_FUNCTION = const MessageKind(
730 'Error: Cannot patch non-function with function patch ' 853 'Error: Cannot patch non-function with function patch '
731 '"#{functionName}".'); 854 '"#{functionName}".');
732 855
733 ////////////////////////////////////////////////////////////////////////////// 856 //////////////////////////////////////////////////////////////////////////////
734 // Patch errors end. 857 // Patch errors end.
735 ////////////////////////////////////////////////////////////////////////////// 858 //////////////////////////////////////////////////////////////////////////////
736 859
737 toString() => template; 860 toString() => template;
738 861
739 Message message([Map arguments = const {}]) { 862 Message message([Map arguments = const {}, bool terse = false]) {
740 return new Message(this, arguments); 863 return new Message(this, arguments, terse);
741 } 864 }
742 865
743 CompilationError error([Map arguments = const {}]) { 866 CompilationError error([Map arguments = const {}, bool terse = false]) {
744 return new CompilationError(this, arguments); 867 return new CompilationError(this, arguments, terse);
745 } 868 }
746 } 869 }
747 870
748 class DualKind { 871 class DualKind {
749 final MessageKind error; 872 final MessageKind error;
750 final MessageKind warning; 873 final MessageKind warning;
751 874
752 const DualKind({this.error, this.warning}); 875 const DualKind({this.error, this.warning});
753 } 876 }
754 877
755 class Message { 878 class Message {
756 final kind; 879 final MessageKind kind;
757 final Map arguments; 880 final Map arguments;
881 final bool terse;
758 String message; 882 String message;
759 883
760 Message(this.kind, this.arguments) { 884 Message(this.kind, this.arguments, this.terse) {
761 assert(() { computeMessage(); return true; }); 885 assert(() { computeMessage(); return true; });
762 } 886 }
763 887
764 String computeMessage() { 888 String computeMessage() {
765 if (message == null) { 889 if (message == null) {
766 message = kind.template; 890 message = kind.template;
767 arguments.forEach((key, value) { 891 arguments.forEach((key, value) {
768 String string = slowToString(value); 892 String string = slowToString(value);
769 message = message.replaceAll('#{${key}}', string); 893 message = message.replaceAll('#{${key}}', string);
770 }); 894 });
771 assert(invariant( 895 assert(invariant(
772 CURRENT_ELEMENT_SPANNABLE, 896 CURRENT_ELEMENT_SPANNABLE,
773 !message.contains(new RegExp(r'#\{.+\}')), 897 !message.contains(new RegExp(r'#\{.+\}')),
774 message: 'Missing arguments in error message: "$message"')); 898 message: 'Missing arguments in error message: "$message"'));
899 if (!terse && kind.howToFix != null) {
900 String howToFix = kind.howToFix;
901 arguments.forEach((key, value) {
902 String string = slowToString(value);
903 howToFix = howToFix.replaceAll('#{${key}}', string);
904 });
905 message = '$message\n$howToFix';
906 }
775 } 907 }
776 return message; 908 return message;
777 } 909 }
778 910
779 String toString() { 911 String toString() {
780 return computeMessage(); 912 return computeMessage();
781 } 913 }
782 914
783 bool operator==(other) { 915 bool operator==(other) {
784 if (other is !Message) return false; 916 if (other is !Message) return false;
785 return (kind == other.kind) && (toString() == other.toString()); 917 return (kind == other.kind) && (toString() == other.toString());
786 } 918 }
787 919
788 int get hashCode => throw new UnsupportedError('Message.hashCode'); 920 int get hashCode => throw new UnsupportedError('Message.hashCode');
789 921
790 String slowToString(object) { 922 String slowToString(object) {
791 if (object is SourceString) { 923 if (object is SourceString) {
792 return object.slowToString(); 924 return object.slowToString();
793 } else { 925 } else {
794 return object.toString(); 926 return object.toString();
795 } 927 }
796 } 928 }
797 } 929 }
798 930
799 class Diagnostic { 931 class Diagnostic {
800 final Message message; 932 final Message message;
801 Diagnostic(MessageKind kind, [Map arguments = const {}]) 933 Diagnostic(MessageKind kind, Map arguments, bool terse)
802 : message = new Message(kind, arguments); 934 : message = new Message(kind, arguments, terse);
803 String toString() => message.toString(); 935 String toString() => message.toString();
804 } 936 }
805 937
806 class TypeWarning extends Diagnostic { 938 class TypeWarning extends Diagnostic {
807 TypeWarning(MessageKind kind, [Map arguments = const {}]) 939 TypeWarning(MessageKind kind, Map arguments, bool terse)
808 : super(kind, arguments); 940 : super(kind, arguments, terse);
809 } 941 }
810 942
811 class ResolutionWarning extends Diagnostic { 943 class ResolutionWarning extends Diagnostic {
812 ResolutionWarning(MessageKind kind, [Map arguments = const {}]) 944 ResolutionWarning(MessageKind kind, Map arguments, bool terse)
813 : super(kind, arguments); 945 : super(kind, arguments, terse);
814 } 946 }
815 947
816 class CompileTimeConstantError extends Diagnostic { 948 class CompileTimeConstantError extends Diagnostic {
817 CompileTimeConstantError(MessageKind kind, [Map arguments = const {}]) 949 CompileTimeConstantError(MessageKind kind, Map arguments, bool terse)
818 : super(kind, arguments); 950 : super(kind, arguments, terse);
819 } 951 }
820 952
821 class CompilationError extends Diagnostic { 953 class CompilationError extends Diagnostic {
822 CompilationError(MessageKind kind, [Map arguments = const {}]) 954 CompilationError(MessageKind kind, Map arguments, bool terse)
823 : super(kind, arguments); 955 : super(kind, arguments, terse);
824 } 956 }
OLDNEW
« no previous file with comments | « dart/sdk/lib/_internal/compiler/implementation/typechecker.dart ('k') | dart/tests/compiler/dart2js/memory_compiler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698