| OLD | NEW |
| 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 mock_compiler; | 5 library mock_compiler; |
| 6 | 6 |
| 7 import "package:expect/expect.dart"; | 7 import "package:expect/expect.dart"; |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'dart:collection'; | 9 import 'dart:collection'; |
| 10 | 10 |
| 11 import 'package:compiler/compiler.dart' as api; | 11 import 'package:compiler/compiler.dart' as api; |
| 12 import 'package:compiler/src/common/names.dart' show | 12 import 'package:compiler/src/common/names.dart' show |
| 13 Uris; | 13 Uris; |
| 14 import 'package:compiler/src/constants/expressions.dart'; | 14 import 'package:compiler/src/constants/expressions.dart'; |
| 15 import 'package:compiler/src/diagnostics/diagnostic_listener.dart'; | 15 import 'package:compiler/src/diagnostics/diagnostic_listener.dart'; |
| 16 import 'package:compiler/src/diagnostics/messages.dart'; | |
| 17 import 'package:compiler/src/diagnostics/source_span.dart'; | 16 import 'package:compiler/src/diagnostics/source_span.dart'; |
| 18 import 'package:compiler/src/diagnostics/spannable.dart'; | 17 import 'package:compiler/src/diagnostics/spannable.dart'; |
| 19 import 'package:compiler/src/elements/elements.dart'; | 18 import 'package:compiler/src/elements/elements.dart'; |
| 20 import 'package:compiler/src/js_backend/backend_helpers.dart' | 19 import 'package:compiler/src/js_backend/backend_helpers.dart' |
| 21 show BackendHelpers; | 20 show BackendHelpers; |
| 22 import 'package:compiler/src/js_backend/lookup_map_analysis.dart' | 21 import 'package:compiler/src/js_backend/lookup_map_analysis.dart' |
| 23 show LookupMapAnalysis; | 22 show LookupMapAnalysis; |
| 24 import 'package:compiler/src/io/source_file.dart'; | 23 import 'package:compiler/src/io/source_file.dart'; |
| 25 import 'package:compiler/src/resolution/members.dart'; | 24 import 'package:compiler/src/resolution/members.dart'; |
| 26 import 'package:compiler/src/resolution/registry.dart'; | 25 import 'package:compiler/src/resolution/registry.dart'; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 37 ErroneousElementX, | 36 ErroneousElementX, |
| 38 FunctionElementX; | 37 FunctionElementX; |
| 39 | 38 |
| 40 import 'package:compiler/src/compiler.dart'; | 39 import 'package:compiler/src/compiler.dart'; |
| 41 | 40 |
| 42 import 'package:compiler/src/deferred_load.dart' | 41 import 'package:compiler/src/deferred_load.dart' |
| 43 show DeferredLoadTask, | 42 show DeferredLoadTask, |
| 44 OutputUnit; | 43 OutputUnit; |
| 45 | 44 |
| 46 import 'mock_libraries.dart'; | 45 import 'mock_libraries.dart'; |
| 46 import 'diagnostic_helper.dart'; |
| 47 | 47 |
| 48 class WarningMessage { | 48 export 'diagnostic_helper.dart'; |
| 49 Spannable node; | |
| 50 Message message; | |
| 51 WarningMessage(this.node, this.message); | |
| 52 | |
| 53 toString() => message.kind.toString(); | |
| 54 } | |
| 55 | 49 |
| 56 final Uri PATCH_CORE = new Uri(scheme: 'patch', path: 'core'); | 50 final Uri PATCH_CORE = new Uri(scheme: 'patch', path: 'core'); |
| 57 | 51 |
| 58 typedef String LibrarySourceProvider(Uri uri); | 52 typedef String LibrarySourceProvider(Uri uri); |
| 59 | 53 |
| 60 class MockCompiler extends Compiler { | 54 class MockCompiler extends Compiler { |
| 61 api.DiagnosticHandler diagnosticHandler; | 55 api.DiagnosticHandler diagnosticHandler; |
| 62 List<WarningMessage> warnings; | |
| 63 List<WarningMessage> errors; | |
| 64 List<WarningMessage> hints; | |
| 65 List<WarningMessage> infos; | |
| 66 List<WarningMessage> crashes; | |
| 67 /// Expected number of warnings. If `null`, the number of warnings is | 56 /// Expected number of warnings. If `null`, the number of warnings is |
| 68 /// not checked. | 57 /// not checked. |
| 69 final int expectedWarnings; | 58 final int expectedWarnings; |
| 70 /// Expected number of errors. If `null`, the number of errors is not checked. | 59 /// Expected number of errors. If `null`, the number of errors is not checked. |
| 71 final int expectedErrors; | 60 final int expectedErrors; |
| 72 final Map<String, SourceFile> sourceFiles; | 61 final Map<String, SourceFile> sourceFiles; |
| 73 Node parsedTree; | 62 Node parsedTree; |
| 74 final String testedPatchVersion; | 63 final String testedPatchVersion; |
| 75 final LibrarySourceProvider librariesOverride; | 64 final LibrarySourceProvider librariesOverride; |
| 65 final DiagnosticCollector diagnosticCollector = new DiagnosticCollector(); |
| 76 | 66 |
| 77 MockCompiler.internal( | 67 MockCompiler.internal( |
| 78 {Map<String, String> coreSource, | 68 {Map<String, String> coreSource, |
| 79 bool enableTypeAssertions: false, | 69 bool enableTypeAssertions: false, |
| 80 bool enableUserAssertions: false, | 70 bool enableUserAssertions: false, |
| 81 bool enableMinification: false, | 71 bool enableMinification: false, |
| 82 int maxConcreteTypeSize: 5, | 72 int maxConcreteTypeSize: 5, |
| 83 bool disableTypeInference: false, | 73 bool disableTypeInference: false, |
| 84 bool analyzeAll: false, | 74 bool analyzeAll: false, |
| 85 bool analyzeOnly: false, | 75 bool analyzeOnly: false, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 108 emitJavaScript: emitJavaScript, | 98 emitJavaScript: emitJavaScript, |
| 109 preserveComments: preserveComments, | 99 preserveComments: preserveComments, |
| 110 trustTypeAnnotations: trustTypeAnnotations, | 100 trustTypeAnnotations: trustTypeAnnotations, |
| 111 diagnosticOptions: | 101 diagnosticOptions: |
| 112 new DiagnosticOptions(showPackageWarnings: true), | 102 new DiagnosticOptions(showPackageWarnings: true), |
| 113 outputProvider: new LegacyCompilerOutput(outputProvider)) { | 103 outputProvider: new LegacyCompilerOutput(outputProvider)) { |
| 114 this.disableInlining = disableInlining; | 104 this.disableInlining = disableInlining; |
| 115 | 105 |
| 116 deferredLoadTask = new MockDeferredLoadTask(this); | 106 deferredLoadTask = new MockDeferredLoadTask(this); |
| 117 | 107 |
| 118 clearMessages(); | |
| 119 | |
| 120 registerSource(Uris.dart_core, | 108 registerSource(Uris.dart_core, |
| 121 buildLibrarySource(DEFAULT_CORE_LIBRARY, coreSource)); | 109 buildLibrarySource(DEFAULT_CORE_LIBRARY, coreSource)); |
| 122 registerSource(PATCH_CORE, DEFAULT_PATCH_CORE_SOURCE); | 110 registerSource(PATCH_CORE, DEFAULT_PATCH_CORE_SOURCE); |
| 123 | 111 |
| 124 registerSource(BackendHelpers.DART_JS_HELPER, | 112 registerSource(BackendHelpers.DART_JS_HELPER, |
| 125 buildLibrarySource(DEFAULT_JS_HELPER_LIBRARY)); | 113 buildLibrarySource(DEFAULT_JS_HELPER_LIBRARY)); |
| 126 registerSource(BackendHelpers.DART_FOREIGN_HELPER, | 114 registerSource(BackendHelpers.DART_FOREIGN_HELPER, |
| 127 buildLibrarySource(DEFAULT_FOREIGN_HELPER_LIBRARY)); | 115 buildLibrarySource(DEFAULT_FOREIGN_HELPER_LIBRARY)); |
| 128 registerSource(BackendHelpers.DART_INTERCEPTORS, | 116 registerSource(BackendHelpers.DART_INTERCEPTORS, |
| 129 buildLibrarySource(DEFAULT_INTERCEPTORS_LIBRARY)); | 117 buildLibrarySource(DEFAULT_INTERCEPTORS_LIBRARY)); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 // wasn't resolved. | 149 // wasn't resolved. |
| 162 coreClasses.objectClass.ensureResolved(resolution); | 150 coreClasses.objectClass.ensureResolved(resolution); |
| 163 }).then((_) => uri); | 151 }).then((_) => uri); |
| 164 } | 152 } |
| 165 | 153 |
| 166 Future run(Uri uri, [String mainSource = ""]) { | 154 Future run(Uri uri, [String mainSource = ""]) { |
| 167 return init(mainSource).then((Uri mainUri) { | 155 return init(mainSource).then((Uri mainUri) { |
| 168 return super.run(uri == null ? mainUri : uri); | 156 return super.run(uri == null ? mainUri : uri); |
| 169 }).then((result) { | 157 }).then((result) { |
| 170 if (expectedErrors != null && | 158 if (expectedErrors != null && |
| 171 expectedErrors != errors.length) { | 159 expectedErrors != diagnosticCollector.errors.length) { |
| 172 throw "unexpected error during compilation ${errors}"; | 160 throw "unexpected error during compilation " |
| 161 "${diagnosticCollector.errors}"; |
| 173 } else if (expectedWarnings != null && | 162 } else if (expectedWarnings != null && |
| 174 expectedWarnings != warnings.length) { | 163 expectedWarnings != diagnosticCollector.warnings.length) { |
| 175 throw "unexpected warnings during compilation ${warnings}"; | 164 throw "unexpected warnings during compilation " |
| 165 "${diagnosticCollector.warnings}"; |
| 176 } else { | 166 } else { |
| 177 return result; | 167 return result; |
| 178 } | 168 } |
| 179 }); | 169 }); |
| 180 } | 170 } |
| 181 | 171 |
| 182 /** | 172 /** |
| 183 * Registers the [source] with [uri] making it possible load [source] as a | 173 * Registers the [source] with [uri] making it possible load [source] as a |
| 184 * library. If an override has been provided in [librariesOverride], that | 174 * library. If an override has been provided in [librariesOverride], that |
| 185 * is used instead. | 175 * is used instead. |
| 186 */ | 176 */ |
| 187 void registerSource(Uri uri, String source) { | 177 void registerSource(Uri uri, String source) { |
| 188 if (librariesOverride != null) { | 178 if (librariesOverride != null) { |
| 189 String override = librariesOverride(uri); | 179 String override = librariesOverride(uri); |
| 190 if (override != null) { | 180 if (override != null) { |
| 191 source = override; | 181 source = override; |
| 192 } | 182 } |
| 193 } | 183 } |
| 194 sourceFiles[uri.toString()] = new MockFile(source); | 184 sourceFiles[uri.toString()] = new MockFile(source); |
| 195 } | 185 } |
| 196 | 186 |
| 197 // TODO(johnniwinther): Remove this when we don't filter certain type checker | |
| 198 // warnings. | |
| 199 void reportWarning( | |
| 200 DiagnosticMessage message, | |
| 201 [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) { | |
| 202 reportDiagnostic(message, infos, api.Diagnostic.WARNING); | |
| 203 } | |
| 204 | |
| 205 void reportDiagnostic(DiagnosticMessage message, | 187 void reportDiagnostic(DiagnosticMessage message, |
| 206 List<DiagnosticMessage> infoMessages, | 188 List<DiagnosticMessage> infoMessages, |
| 207 api.Diagnostic kind) { | 189 api.Diagnostic kind) { |
| 208 | 190 |
| 209 void processMessage(DiagnosticMessage message, api.Diagnostic kind) { | 191 void processMessage(DiagnosticMessage message, api.Diagnostic kind) { |
| 210 var diagnostic = new WarningMessage(message.spannable, message.message); | 192 SourceSpan span = message.sourceSpan; |
| 211 if (kind == api.Diagnostic.CRASH) { | 193 Uri uri; |
| 212 crashes.add(diagnostic); | 194 int begin; |
| 213 } else if (kind == api.Diagnostic.ERROR) { | 195 int end; |
| 214 errors.add(diagnostic); | 196 String text = '${message.message}'; |
| 215 } else if (kind == api.Diagnostic.WARNING) { | 197 if (span != null) { |
| 216 warnings.add(diagnostic); | 198 uri = span.uri; |
| 217 } else if (kind == api.Diagnostic.INFO) { | 199 begin = span.begin; |
| 218 infos.add(diagnostic); | 200 end = span.end; |
| 219 } else if (kind == api.Diagnostic.HINT) { | |
| 220 hints.add(diagnostic); | |
| 221 } | 201 } |
| 202 diagnosticCollector.report(message.message, uri, begin, end, text, kind); |
| 222 if (diagnosticHandler != null) { | 203 if (diagnosticHandler != null) { |
| 223 SourceSpan span = message.sourceSpan; | 204 diagnosticHandler(uri, begin, end, text, kind); |
| 224 if (span != null) { | |
| 225 diagnosticHandler( | |
| 226 span.uri, span.begin, span.end, '${message.message}', kind); | |
| 227 } else { | |
| 228 diagnosticHandler(null, null, null, '${message.message}', kind); | |
| 229 } | |
| 230 } | 205 } |
| 231 } | 206 } |
| 232 | 207 |
| 233 processMessage(message, kind); | 208 processMessage(message, kind); |
| 234 infoMessages.forEach((i) => processMessage(i, api.Diagnostic.INFO)); | 209 infoMessages.forEach((i) => processMessage(i, api.Diagnostic.INFO)); |
| 235 } | 210 } |
| 236 | 211 |
| 237 bool get compilationFailed => !crashes.isEmpty || !errors.isEmpty; | |
| 238 | |
| 239 void clearMessages() { | |
| 240 warnings = []; | |
| 241 errors = []; | |
| 242 hints = []; | |
| 243 infos = []; | |
| 244 crashes = []; | |
| 245 } | |
| 246 | |
| 247 CollectingTreeElements resolveStatement(String text) { | 212 CollectingTreeElements resolveStatement(String text) { |
| 248 parsedTree = parseStatement(text); | 213 parsedTree = parseStatement(text); |
| 249 return resolveNodeStatement(parsedTree, new MockElement(mainApp)); | 214 return resolveNodeStatement(parsedTree, new MockElement(mainApp)); |
| 250 } | 215 } |
| 251 | 216 |
| 252 TreeElementMapping resolveNodeStatement(Node tree, | 217 TreeElementMapping resolveNodeStatement(Node tree, |
| 253 ExecutableElement element) { | 218 ExecutableElement element) { |
| 254 ResolverVisitor visitor = | 219 ResolverVisitor visitor = |
| 255 new ResolverVisitor(this, element, | 220 new ResolverVisitor(this, element, |
| 256 new ResolutionRegistry(this, | 221 new ResolutionRegistry(this, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 : new ErroneousElementX(null, null, name, container); | 277 : new ErroneousElementX(null, null, name, container); |
| 313 } | 278 } |
| 314 | 279 |
| 315 /// Create a new [MockCompiler] and apply it asynchronously to [f]. | 280 /// Create a new [MockCompiler] and apply it asynchronously to [f]. |
| 316 static Future create(f(MockCompiler compiler)) { | 281 static Future create(f(MockCompiler compiler)) { |
| 317 MockCompiler compiler = new MockCompiler.internal(); | 282 MockCompiler compiler = new MockCompiler.internal(); |
| 318 return compiler.init().then((_) => f(compiler)); | 283 return compiler.init().then((_) => f(compiler)); |
| 319 } | 284 } |
| 320 } | 285 } |
| 321 | 286 |
| 322 /// A function the checks [message]. If the check fails or if [message] is | |
| 323 /// `null`, an error string is returned. Otherwise `null` is returned. | |
| 324 typedef String CheckMessage(Message message); | |
| 325 | |
| 326 CheckMessage checkMessage(MessageKind kind, Map arguments) { | |
| 327 return (Message message) { | |
| 328 if (message == null) return '$kind'; | |
| 329 if (message.kind != kind) return 'Expected message $kind, found $message.'; | |
| 330 for (var key in arguments.keys) { | |
| 331 if (!message.arguments.containsKey(key)) { | |
| 332 return 'Expected argument $key not found in $message.kind.'; | |
| 333 } | |
| 334 String expectedValue = '${arguments[key]}'; | |
| 335 String foundValue = '${message.arguments[key]}'; | |
| 336 if (expectedValue != foundValue) { | |
| 337 return 'Expected argument $key with value $expectedValue, ' | |
| 338 'found $foundValue.'; | |
| 339 } | |
| 340 } | |
| 341 return null; | |
| 342 }; | |
| 343 } | |
| 344 | |
| 345 void compareWarningKinds(String text, | |
| 346 List expectedWarnings, | |
| 347 List<WarningMessage> foundWarnings) { | |
| 348 compareMessageKinds(text, expectedWarnings, foundWarnings, 'warning'); | |
| 349 } | |
| 350 | |
| 351 /// [expectedMessages] must be a list of either [MessageKind] or [CheckMessage]. | |
| 352 void compareMessageKinds(String text, | |
| 353 List expectedMessages, | |
| 354 List<WarningMessage> foundMessages, | |
| 355 String kind) { | |
| 356 var fail = (message) => Expect.fail('$text: $message'); | |
| 357 HasNextIterator expectedIterator = | |
| 358 new HasNextIterator(expectedMessages.iterator); | |
| 359 HasNextIterator<WarningMessage> foundIterator = | |
| 360 new HasNextIterator(foundMessages.iterator); | |
| 361 while (expectedIterator.hasNext && foundIterator.hasNext) { | |
| 362 var expected = expectedIterator.next(); | |
| 363 var found = foundIterator.next(); | |
| 364 if (expected is MessageKind) { | |
| 365 Expect.equals(expected, found.message.kind); | |
| 366 } else if (expected is CheckMessage) { | |
| 367 String error = expected(found.message); | |
| 368 Expect.isNull(error, error); | |
| 369 } else { | |
| 370 Expect.fail("Unexpected $kind value: $expected."); | |
| 371 } | |
| 372 } | |
| 373 if (expectedIterator.hasNext) { | |
| 374 do { | |
| 375 var expected = expectedIterator.next(); | |
| 376 if (expected is CheckMessage) expected = expected(null); | |
| 377 print('Expected $kind "${expected}" did not occur'); | |
| 378 } while (expectedIterator.hasNext); | |
| 379 fail('Too few ${kind}s'); | |
| 380 } | |
| 381 if (foundIterator.hasNext) { | |
| 382 do { | |
| 383 WarningMessage message = foundIterator.next(); | |
| 384 print('Additional $kind "${message}: ${message.message}"'); | |
| 385 } while (foundIterator.hasNext); | |
| 386 fail('Too many ${kind}s'); | |
| 387 } | |
| 388 } | |
| 389 | |
| 390 class CollectingTreeElements extends TreeElementMapping { | 287 class CollectingTreeElements extends TreeElementMapping { |
| 391 final Map<Node, Element> map = new LinkedHashMap<Node, Element>(); | 288 final Map<Node, Element> map = new LinkedHashMap<Node, Element>(); |
| 392 | 289 |
| 393 CollectingTreeElements(Element currentElement) : super(currentElement); | 290 CollectingTreeElements(Element currentElement) : super(currentElement); |
| 394 | 291 |
| 395 operator []=(Node node, Element element) { | 292 operator []=(Node node, Element element) { |
| 396 map[node] = element; | 293 map[node] = element; |
| 397 } | 294 } |
| 398 | 295 |
| 399 operator [](Node node) => map[node]; | 296 operator [](Node node) => map[node]; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 trustTypeAnnotations: trustTypeAnnotations, | 367 trustTypeAnnotations: trustTypeAnnotations, |
| 471 enableTypeAssertions: enableTypeAssertions, | 368 enableTypeAssertions: enableTypeAssertions, |
| 472 enableUserAssertions: enableUserAssertions, | 369 enableUserAssertions: enableUserAssertions, |
| 473 expectedErrors: expectedErrors, | 370 expectedErrors: expectedErrors, |
| 474 expectedWarnings: expectedWarnings, | 371 expectedWarnings: expectedWarnings, |
| 475 outputProvider: outputProvider); | 372 outputProvider: outputProvider); |
| 476 compiler.registerSource(uri, code); | 373 compiler.registerSource(uri, code); |
| 477 compiler.diagnosticHandler = createHandler(compiler, code); | 374 compiler.diagnosticHandler = createHandler(compiler, code); |
| 478 return compiler; | 375 return compiler; |
| 479 } | 376 } |
| OLD | NEW |