Add frontendInternal key and external example to messages tests

This CL adds two keys to the messages.yaml file:

 * `frontendInternal` which indicates that we do not require a
    dart2jsCode nor a analyzerCode: there is no corresponding
    error in other tools

 * `external` which can be used instead of an example. The external
   file is not actually run to verify the example, but the file is
   checked for existance. This can for instance be used to test an
   internal frontend error code.

Change-Id: I2426c6ba2a2abe5baaab09c8e0947b4b876df083
Reviewed-on: https://dart-review.googlesource.com/54387
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 696070c..a4feebd 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -10,7 +10,9 @@
 # 2. A suggestion for how to correct the problem (tip).
 #
 # 3. Examples that produce the message (one of expression, statement,
-#    declaration, member, script, or bytes).
+#    declaration, member, script, bytes or external). Note that 'external'
+#    should be the path to an external test. The external test will not be run,
+#    but the existance of the file will be verified.
 #
 # A message shouldn't indicate which kind of diagnostic it is, for example,
 # warning or error. Tools are expected to prepend "Warning: ", or "Error: ",
@@ -43,6 +45,9 @@
 # Long term, the analyzer and front-end need to share the same error codes. So
 # eventually all error codes should have an `analyzerCode` field.
 #
+# In some cases a mesage is internal to the frontend, and no meaningful dart2js
+# nor analyzer code can be provided. In such cases set `frontendInternal: true`.
+#
 # ## Parameter Substitution in Template and Tip
 #
 # The fields `template` and `tip` are subject to parameter substitution. When
diff --git a/pkg/front_end/test/fasta/messages_test.dart b/pkg/front_end/test/fasta/messages_test.dart
index 16f96a5..334a62f 100644
--- a/pkg/front_end/test/fasta/messages_test.dart
+++ b/pkg/front_end/test/fasta/messages_test.dart
@@ -83,6 +83,8 @@
 
       List<String> unknownKeys = <String>[];
       List<Example> examples = <Example>[];
+      String externalTest;
+      bool frontendInternal = false;
       String analyzerCode;
       String dart2jsCode;
       Severity severity;
@@ -103,6 +105,10 @@
             }
             break;
 
+          case "frontendInternal":
+            frontendInternal = value;
+            break;
+
           case "analyzerCode":
             analyzerCode = value;
             break;
@@ -170,6 +176,10 @@
             }
             break;
 
+          case "external":
+            externalTest = node.value;
+            break;
+
           default:
             unknownKeys.add(key);
         }
@@ -213,16 +223,29 @@
           severity != Severity.internalProblem);
 
       yield createDescription(
+          "externalexample",
+          null,
+          exampleAndAnalyzerCodeRequired &&
+                  externalTest != null &&
+                  !(new File(externalTest).existsSync())
+              ? "Given external example for $name points to a nonexisting file."
+              : null);
+
+      yield createDescription(
           "example",
           null,
-          exampleAndAnalyzerCodeRequired && examples.isEmpty
+          exampleAndAnalyzerCodeRequired &&
+                  examples.isEmpty &&
+                  externalTest == null
               ? "No example for $name, please add at least one example."
               : null);
 
       yield createDescription(
           "analyzerCode",
           null,
-          exampleAndAnalyzerCodeRequired && analyzerCode == null
+          exampleAndAnalyzerCodeRequired &&
+                  !frontendInternal &&
+                  analyzerCode == null
               ? "No analyzer code for $name."
                   "\nTry running"
                   " <BUILDDIR>/dart-sdk/bin/dartanalyzer --format=machine"
@@ -234,6 +257,7 @@
           "dart2jsCode",
           null,
           exampleAndAnalyzerCodeRequired &&
+                  !frontendInternal &&
                   analyzerCode != null &&
                   dart2jsCode == null
               ? "No dart2js code for $name."