Support multiple files in messages test.

Change-Id: Ia39deb29c5255dbcfe973fbdbad35d08ed181bd1
Reviewed-on: https://dart-review.googlesource.com/60242
Commit-Queue: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index d308900..8c56c40 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -116,7 +116,6 @@
 DuplicatedExportInType/analyzerCode: Fail
 DuplicatedExportInType/example: Fail
 DuplicatedImportInType/analyzerCode: Fail
-DuplicatedImportInType/example: Fail
 DuplicatedModifier/script1: Fail
 DuplicatedName/analyzerCode: Fail
 DuplicatedName/example: Fail
@@ -249,7 +248,6 @@
 MissingMain/analyzerCode: Fail
 MissingMain/example: Fail
 MissingPartOf/analyzerCode: Fail
-MissingPartOf/example: Fail
 MissingPrefixInDeferredImport/example: Fail
 MixinInferenceNoMatchingClass/analyzerCode: Fail
 MixinInferenceNoMatchingClass/example: Fail
@@ -299,15 +297,12 @@
 PartOfLibraryNameMismatch/analyzerCode: Fail
 PartOfLibraryNameMismatch/example: Fail
 PartOfSelf/analyzerCode: Fail
-PartOfSelf/example: Fail
 PartOfTwoLibraries/analyzerCode: Fail # Issue 33227
-PartOfTwoLibraries/example: Fail # Needs multiple files
 PartOfUriMismatch/analyzerCode: Fail
 PartOfUriMismatch/example: Fail
 PartOfUseUri/analyzerCode: Fail
 PartOfUseUri/example: Fail
 PartTwice/analyzerCode: Fail
-PartTwice/example: Fail
 PatchClassTypeVariablesMismatch/analyzerCode: Fail
 PatchClassTypeVariablesMismatch/example: Fail
 PatchDeclarationMismatch/analyzerCode: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index af33dd73..534bfdf 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1410,6 +1410,10 @@
 DuplicatedImportInType:
   template: "'#name' is imported from both '#uri' and '#uri2'."
   severity: ERROR_LEGACY_WARNING
+  script:
+    lib1.dart: "class A {}"
+    lib2.dart: "class A {}"
+    main.dart: "import 'lib1.dart'; import 'lib2.dart'; A a;"
 
 CyclicClassHierarchy:
   template: "'#name' is a supertype of itself via '#string'."
@@ -1579,6 +1583,8 @@
 
 PartOfSelf:
   template: "A file can't be a part of itself."
+  script:
+    main.dart: "part 'main.dart';"
 
 TypeVariableDuplicatedName:
   template: "A type variable can't have the same name as another."
@@ -1703,11 +1709,18 @@
 
 PartTwice:
   template: "Can't use '#uri' as a part more than once."
+  script:
+    part.dart: "part of 'main.dart';"
+    main.dart: "part 'part.dart'; part 'part.dart';"
 
 PartOfTwoLibraries:
   template: "A file can't be part of more than one library."
   tip: "Try moving the shared declarations into the libraries, or into a new library."
   severity: ERROR
+  script:
+    main.dart: "library lib; import 'lib.dart'; part 'part.dart';"
+    lib.dart: "library lib; part 'part.dart';"
+    part.dart: "part of lib;"
 
 PartOfTwoLibrariesContext:
   template: "Used as a part in this library."
@@ -1765,6 +1778,9 @@
 
 MissingPartOf:
   template: "Can't use '#uri' as a part, because it has no 'part of' declaration."
+  script:
+    part.dart: ""
+    main.dart: "part 'part.dart';"
 
 SupertypeIsFunction:
   template: "Can't use a function type as supertype."
diff --git a/pkg/front_end/test/fasta/messages_test.dart b/pkg/front_end/test/fasta/messages_test.dart
index e1a706c..d5d759d 100644
--- a/pkg/front_end/test/fasta/messages_test.dart
+++ b/pkg/front_end/test/fasta/messages_test.dart
@@ -157,10 +157,11 @@
             if (node is YamlList) {
               int i = 0;
               for (YamlNode script in node.nodes) {
-                examples.add(new ScriptExample("script${++i}", name, script));
+                examples
+                    .add(new ScriptExample("script${++i}", name, script, this));
               }
             } else {
-              examples.add(new ScriptExample("script", name, node));
+              examples.add(new ScriptExample("script", name, node, this));
             }
             break;
 
@@ -301,6 +302,10 @@
   YamlNode get node;
 
   Uint8List get bytes;
+
+  Map<String, Uint8List> get scripts {
+    return {"main.dart": bytes};
+  }
 }
 
 class BytesExample extends Example {
@@ -380,15 +385,33 @@
   @override
   final YamlNode node;
 
-  final String script;
+  final Object script;
 
-  ScriptExample(String name, String code, this.node)
+  ScriptExample(String name, String code, this.node, MessageTestSuite suite)
       : script = node.value,
-        super(name, code);
+        super(name, code) {
+    if (script is! String && script is! Map) {
+      throw suite.formatProblems(
+          "A script must be either a String or a Map in $code:",
+          this, <List>[]);
+    }
+  }
 
   @override
-  Uint8List get bytes {
-    return new Uint8List.fromList(utf8.encode(script));
+  Uint8List get bytes => throw "Unsupported: ScriptExample.bytes";
+
+  @override
+  Map<String, Uint8List> get scripts {
+    Object script = this.script;
+    if (script is Map) {
+      var scriptFiles = <String, Uint8List>{};
+      script.forEach((fileName, value) {
+        scriptFiles[fileName] = new Uint8List.fromList(utf8.encode(value));
+      });
+      return scriptFiles;
+    } else {
+      return {"main.dart": new Uint8List.fromList(utf8.encode(script))};
+    }
   }
 }
 
@@ -414,12 +437,16 @@
 
   Future<Result<Null>> run(Example example, MessageTestSuite suite) async {
     if (example == null) return pass(null);
-    String name = "${example.expectedCode}/${example.name}";
-    Uri uri = suite.fileSystem.currentDirectory.resolve("${name}.dart");
-    suite.fileSystem.entityForUri(uri).writeAsBytesSync(example.bytes);
-    Uri output = uri.resolve("${uri.path}.dill");
+    String dir = "${example.expectedCode}/${example.name}";
+    example.scripts.forEach((String fileName, Uint8List bytes) {
+      Uri uri = suite.fileSystem.currentDirectory.resolve("$dir/$fileName");
+      suite.fileSystem.entityForUri(uri).writeAsBytesSync(bytes);
+    });
+    Uri main = suite.fileSystem.currentDirectory.resolve("$dir/main.dart");
+    Uri output =
+        suite.fileSystem.currentDirectory.resolve("$dir/main.dart.dill");
 
-    print("Compiling $uri");
+    print("Compiling $main");
     List<List> problems = <List>[];
 
     await suite.compiler.batchCompile(
@@ -432,7 +459,7 @@
             problems.add([problem, severity]);
           }
           ..strongMode = true,
-        uri,
+        main,
         output);
 
     List<List> unexpectedProblems = <List>[];