| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 /// Command line tool to run the checker on a Dart program. | 5 /// Command line tool to run the checker on a Dart program. |
| 6 library dev_compiler.src.compiler; | 6 library dev_compiler.src.compiler; |
| 7 | 7 |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'dart:collection'; | 9 import 'dart:collection'; |
| 10 import 'dart:math' as math; | 10 import 'dart:math' as math; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 /// messages. | 41 /// messages. |
| 42 StreamSubscription setupLogger(Level level, printFn) { | 42 StreamSubscription setupLogger(Level level, printFn) { |
| 43 Logger.root.level = level; | 43 Logger.root.level = level; |
| 44 return Logger.root.onRecord.listen((LogRecord rec) { | 44 return Logger.root.onRecord.listen((LogRecord rec) { |
| 45 printFn('${rec.level.name.toLowerCase()}: ${rec.message}'); | 45 printFn('${rec.level.name.toLowerCase()}: ${rec.message}'); |
| 46 }); | 46 }); |
| 47 } | 47 } |
| 48 | 48 |
| 49 class BatchCompiler extends AbstractCompiler { | 49 class BatchCompiler extends AbstractCompiler { |
| 50 JSGenerator _jsGen; | 50 JSGenerator _jsGen; |
| 51 LibraryElement _dartCore; |
| 52 String _runtimeOutputDir; |
| 51 | 53 |
| 52 /// Already compiled sources, so we don't compile them again. | 54 /// Already compiled sources, so we don't compile them again. |
| 53 final _compiled = new HashSet<LibraryElement>(); | 55 final _compiled = new HashSet<LibraryElement>(); |
| 54 | 56 |
| 55 bool _failure = false; | 57 bool _failure = false; |
| 56 bool get failure => _failure; | 58 bool get failure => _failure; |
| 57 | 59 |
| 58 BatchCompiler(AnalysisContext context, CompilerOptions options, | 60 BatchCompiler(AnalysisContext context, CompilerOptions options, |
| 59 {AnalysisErrorListener reporter}) | 61 {AnalysisErrorListener reporter}) |
| 60 : super(context, options, reporter) { | 62 : super(context, options, reporter) { |
| 63 _inputBaseDir = options.inputBaseDir; |
| 61 if (outputDir != null) { | 64 if (outputDir != null) { |
| 62 _jsGen = new JSGenerator(this); | 65 _jsGen = new JSGenerator(this); |
| 66 _runtimeOutputDir = path.join(outputDir, 'dev_compiler', 'runtime'); |
| 63 } | 67 } |
| 68 _dartCore = context.typeProvider.objectType.element.library; |
| 64 } | 69 } |
| 65 | 70 |
| 66 void reset() { | 71 void reset() { |
| 67 _compiled.clear(); | 72 _compiled.clear(); |
| 68 } | 73 } |
| 69 | 74 |
| 70 /// Compiles every file in [options.inputs]. | 75 /// Compiles every file in [options.inputs]. |
| 71 /// Returns true on successful compile. | 76 /// Returns true on successful compile. |
| 72 bool run() { | 77 bool run() { |
| 73 var clock = new Stopwatch()..start(); | 78 var clock = new Stopwatch()..start(); |
| 74 options.inputs.forEach(compileFromUriString); | 79 options.inputs.forEach(compileFromUriString); |
| 75 clock.stop(); | 80 clock.stop(); |
| 76 var time = (clock.elapsedMilliseconds / 1000).toStringAsFixed(2); | 81 var time = (clock.elapsedMilliseconds / 1000).toStringAsFixed(2); |
| 77 _log.fine('Compiled ${_compiled.length} libraries in ${time} s\n'); | 82 _log.fine('Compiled ${_compiled.length} libraries in ${time} s\n'); |
| 78 | 83 |
| 79 return !_failure; | 84 return !_failure; |
| 80 } | 85 } |
| 81 | 86 |
| 82 void compileFromUriString(String uriString) { | 87 void compileFromUriString(String uriString) { |
| 83 compileFromUri(stringToUri(uriString)); | 88 _compileFromUri(stringToUri(uriString)); |
| 84 } | 89 } |
| 85 | 90 |
| 86 void compileFromUri(Uri uri) { | 91 void _compileFromUri(Uri uri) { |
| 92 if (!uri.isAbsolute) { |
| 93 throw new ArgumentError.value('$uri', 'uri', 'must be absolute'); |
| 94 } |
| 87 var source = context.sourceFactory.forUri(Uri.encodeFull('$uri')); | 95 var source = context.sourceFactory.forUri(Uri.encodeFull('$uri')); |
| 88 if (source == null) throw new ArgumentError.value( | 96 if (source == null) { |
| 89 uri.toString(), 'uri', 'could not find source for'); | 97 throw new ArgumentError.value('$uri', 'uri', 'could not find source for'); |
| 98 } |
| 90 compileSource(source); | 99 compileSource(source); |
| 91 } | 100 } |
| 92 | 101 |
| 93 void compileSource(Source source) { | 102 void compileSource(Source source) { |
| 94 if (AnalysisEngine.isHtmlFileName(source.uri.path)) { | 103 if (AnalysisEngine.isHtmlFileName(source.uri.path)) { |
| 95 compileHtml(source); | 104 _compileHtml(source); |
| 96 return; | 105 return; |
| 97 } | 106 } |
| 98 | |
| 99 compileLibrary(context.computeLibraryElement(source)); | 107 compileLibrary(context.computeLibraryElement(source)); |
| 100 } | 108 } |
| 101 | 109 |
| 102 void compileLibrary(LibraryElement library) { | 110 void compileLibrary(LibraryElement library) { |
| 103 if (!_compiled.add(library)) return; | 111 if (!_compiled.add(library)) return; |
| 104 if (!options.checkSdk && library.source.uri.scheme == 'dart') return; | 112 |
| 113 if (!options.checkSdk && library.source.uri.scheme == 'dart') { |
| 114 if (_jsGen != null) _copyDartRuntime(); |
| 115 return; |
| 116 } |
| 105 | 117 |
| 106 // TODO(jmesserly): in incremental mode, we can skip the transitive | 118 // TODO(jmesserly): in incremental mode, we can skip the transitive |
| 107 // compile of imports/exports. | 119 // compile of imports/exports. |
| 120 compileLibrary(_dartCore); // implicit dart:core dependency |
| 108 library.importedLibraries.forEach(compileLibrary); | 121 library.importedLibraries.forEach(compileLibrary); |
| 109 library.exportedLibraries.forEach(compileLibrary); | 122 library.exportedLibraries.forEach(compileLibrary); |
| 110 | 123 |
| 111 var unitElements = [library.definingCompilationUnit]..addAll(library.parts); | 124 var unitElements = [library.definingCompilationUnit]..addAll(library.parts); |
| 112 var units = <CompilationUnit>[]; | 125 var units = <CompilationUnit>[]; |
| 113 | 126 |
| 114 bool failureInLib = false; | 127 bool failureInLib = false; |
| 115 for (var element in unitElements) { | 128 for (var element in unitElements) { |
| 116 var unit = context.resolveCompilationUnit(element.source, library); | 129 var unit = context.resolveCompilationUnit(element.source, library); |
| 117 units.add(unit); | 130 units.add(unit); |
| 118 failureInLib = logErrors(element.source) || failureInLib; | 131 failureInLib = logErrors(element.source) || failureInLib; |
| 119 checker.visitCompilationUnit(unit); | 132 checker.visitCompilationUnit(unit); |
| 120 if (checker.failure) failureInLib = true; | 133 if (checker.failure) failureInLib = true; |
| 121 } | 134 } |
| 122 | 135 |
| 123 if (failureInLib) { | 136 if (failureInLib) { |
| 124 _failure = true; | 137 _failure = true; |
| 125 if (!options.codegenOptions.forceCompile) return; | 138 if (!options.codegenOptions.forceCompile) return; |
| 126 } | 139 } |
| 127 | 140 |
| 128 if (_jsGen != null) { | 141 if (_jsGen != null) { |
| 129 var unit = units.first; | 142 var unit = units.first; |
| 130 var parts = units.skip(1).toList(); | 143 var parts = units.skip(1).toList(); |
| 131 _jsGen.generateLibrary(new LibraryUnit(unit, parts)); | 144 _jsGen.generateLibrary(new LibraryUnit(unit, parts)); |
| 132 } | 145 } |
| 133 } | 146 } |
| 134 | 147 |
| 135 void compileHtml(Source source) { | 148 void _copyDartRuntime() { |
| 149 for (var file in defaultRuntimeFiles) { |
| 150 var input = path.join(options.runtimeDir, file); |
| 151 var output = path.join(_runtimeOutputDir, file); |
| 152 new Directory(path.dirname(output)).createSync(recursive: true); |
| 153 new File(input).copySync(output); |
| 154 } |
| 155 } |
| 156 |
| 157 void _compileHtml(Source source) { |
| 136 // TODO(jmesserly): reuse DartScriptsTask instead of copy/paste. | 158 // TODO(jmesserly): reuse DartScriptsTask instead of copy/paste. |
| 137 var contents = context.getContents(source); | 159 var contents = context.getContents(source); |
| 138 var document = html.parse(contents.data, generateSpans: true); | 160 var document = html.parse(contents.data, generateSpans: true); |
| 139 var scripts = document.querySelectorAll('script[type="application/dart"]'); | 161 var scripts = document.querySelectorAll('script[type="application/dart"]'); |
| 140 | 162 |
| 141 var loadedLibs = new LinkedHashSet<Uri>(); | 163 var loadedLibs = new LinkedHashSet<Uri>(); |
| 142 | 164 |
| 165 var htmlOutDir = path.dirname(getOutputPath(source.uri)); |
| 143 for (var script in scripts) { | 166 for (var script in scripts) { |
| 144 Source scriptSource = null; | 167 Source scriptSource = null; |
| 145 var srcAttr = script.attributes['src']; | 168 var srcAttr = script.attributes['src']; |
| 146 if (srcAttr == null) { | 169 if (srcAttr == null) { |
| 147 if (script.hasContent()) { | 170 if (script.hasContent()) { |
| 148 var fragments = <ScriptFragment>[]; | 171 var fragments = <ScriptFragment>[]; |
| 149 for (var node in script.nodes) { | 172 for (var node in script.nodes) { |
| 150 if (node is html.Text) { | 173 if (node is html.Text) { |
| 151 var start = node.sourceSpan.start; | 174 var start = node.sourceSpan.start; |
| 152 fragments.add(new ScriptFragment( | 175 fragments.add(new ScriptFragment( |
| 153 start.offset, start.line, start.column, node.data)); | 176 start.offset, start.line, start.column, node.data)); |
| 154 } | 177 } |
| 155 } | 178 } |
| 156 scriptSource = new DartScript(source, fragments); | 179 scriptSource = new DartScript(source, fragments); |
| 157 } | 180 } |
| 158 } else if (AnalysisEngine.isDartFileName(srcAttr)) { | 181 } else if (AnalysisEngine.isDartFileName(srcAttr)) { |
| 159 scriptSource = context.sourceFactory.resolveUri(source, srcAttr); | 182 scriptSource = context.sourceFactory.resolveUri(source, srcAttr); |
| 160 } | 183 } |
| 161 | 184 |
| 162 if (scriptSource != null) { | 185 if (scriptSource != null) { |
| 163 var lib = context.computeLibraryElement(scriptSource); | 186 var lib = context.computeLibraryElement(scriptSource); |
| 164 compileLibrary(lib); | 187 compileLibrary(lib); |
| 165 script.replaceWith(_linkLibraries(lib, loadedLibs)); | 188 script.replaceWith(_linkLibraries(lib, loadedLibs, from: htmlOutDir)); |
| 166 } | 189 } |
| 167 } | 190 } |
| 168 | 191 |
| 169 // TODO(jmesserly): we need to clean this up so we aren't treating these | |
| 170 // as a special case. | |
| 171 for (var file in defaultRuntimeFiles) { | |
| 172 var input = path.join(options.runtimeDir, file); | |
| 173 var output = path.join(outputDir, runtimeFileOutput(file)); | |
| 174 new Directory(path.dirname(output)).createSync(recursive: true); | |
| 175 new File(input).copySync(output); | |
| 176 } | |
| 177 | |
| 178 new File(getOutputPath(source.uri)).openSync(mode: FileMode.WRITE) | 192 new File(getOutputPath(source.uri)).openSync(mode: FileMode.WRITE) |
| 179 ..writeStringSync(document.outerHtml) | 193 ..writeStringSync(document.outerHtml) |
| 180 ..writeStringSync('\n') | 194 ..writeStringSync('\n') |
| 181 ..closeSync(); | 195 ..closeSync(); |
| 182 } | 196 } |
| 183 | 197 |
| 184 html.DocumentFragment _linkLibraries( | 198 html.DocumentFragment _linkLibraries( |
| 185 LibraryElement mainLib, LinkedHashSet<Uri> loaded) { | 199 LibraryElement mainLib, LinkedHashSet<Uri> loaded, {String from}) { |
| 200 assert(from != null); |
| 186 var alreadyLoaded = loaded.length; | 201 var alreadyLoaded = loaded.length; |
| 187 _collectLibraries(mainLib, loaded); | 202 _collectLibraries(mainLib, loaded); |
| 188 | 203 |
| 189 var newLibs = loaded.skip(alreadyLoaded); | 204 var newLibs = loaded.skip(alreadyLoaded); |
| 190 var df = new html.DocumentFragment(); | 205 var df = new html.DocumentFragment(); |
| 191 for (var path in defaultRuntimeFiles) { | 206 |
| 192 df.append(html_codegen.libraryInclude(runtimeFileOutput(path))); | 207 for (var uri in newLibs) { |
| 208 if (uri.scheme == 'dart') { |
| 209 if (uri.path == 'core') { |
| 210 // TODO(jmesserly): it would be nice to not special case these. |
| 211 for (var file in defaultRuntimeFiles) { |
| 212 file = path.join(_runtimeOutputDir, file); |
| 213 df.append( |
| 214 html_codegen.libraryInclude(path.relative(file, from: from))); |
| 215 } |
| 216 } |
| 217 } else { |
| 218 var file = path.join(outputDir, getModulePath(uri)); |
| 219 df.append(html_codegen.libraryInclude(path.relative(file, from: from))); |
| 220 } |
| 193 } | 221 } |
| 194 for (var uri in newLibs) { | 222 |
| 195 if (uri.scheme == 'dart') continue; | |
| 196 df.append(html_codegen.libraryInclude(getModulePath(uri))); | |
| 197 } | |
| 198 df.append(html_codegen.invokeMain(getModuleName(mainLib.source.uri))); | 223 df.append(html_codegen.invokeMain(getModuleName(mainLib.source.uri))); |
| 199 return df; | 224 return df; |
| 200 } | 225 } |
| 201 | 226 |
| 202 void _collectLibraries(LibraryElement lib, LinkedHashSet<Uri> loaded) { | 227 void _collectLibraries(LibraryElement lib, LinkedHashSet<Uri> loaded) { |
| 203 var uri = lib.source.uri; | 228 var uri = lib.source.uri; |
| 204 if (!loaded.add(uri)) return; | 229 if (!loaded.add(uri)) return; |
| 230 _collectLibraries(_dartCore, loaded); |
| 205 for (var l in lib.importedLibraries) _collectLibraries(l, loaded); | 231 for (var l in lib.importedLibraries) _collectLibraries(l, loaded); |
| 206 for (var l in lib.exportedLibraries) _collectLibraries(l, loaded); | 232 for (var l in lib.exportedLibraries) _collectLibraries(l, loaded); |
| 207 // Move the item to the end of the list. | 233 // Move the item to the end of the list. |
| 208 loaded.remove(uri); | 234 loaded.remove(uri); |
| 209 loaded.add(uri); | 235 loaded.add(uri); |
| 210 } | 236 } |
| 211 | |
| 212 String runtimeFileOutput(String file) => | |
| 213 path.join('dev_compiler', 'runtime', file); | |
| 214 } | 237 } |
| 215 | 238 |
| 216 abstract class AbstractCompiler { | 239 abstract class AbstractCompiler { |
| 217 final CompilerOptions options; | 240 final CompilerOptions options; |
| 218 final AnalysisContext context; | 241 final AnalysisContext context; |
| 219 final CodeChecker checker; | 242 final CodeChecker checker; |
| 220 | 243 |
| 221 AbstractCompiler(AnalysisContext context, CompilerOptions options, | 244 AbstractCompiler(AnalysisContext context, CompilerOptions options, |
| 222 [AnalysisErrorListener reporter]) | 245 [AnalysisErrorListener reporter]) |
| 223 : context = context, | 246 : context = context, |
| 224 options = options, | 247 options = options, |
| 225 checker = createChecker(context.typeProvider, options.strongOptions, | 248 checker = createChecker(context.typeProvider, options.strongOptions, |
| 226 reporter == null ? AnalysisErrorListener.NULL_LISTENER : reporter) { | 249 reporter == null ? AnalysisErrorListener.NULL_LISTENER : reporter) { |
| 227 enableDevCompilerInference(context, options.strongOptions); | 250 enableDevCompilerInference(context, options.strongOptions); |
| 228 } | 251 } |
| 229 | 252 |
| 230 static CodeChecker createChecker(TypeProvider typeProvider, | 253 static CodeChecker createChecker(TypeProvider typeProvider, |
| 231 StrongModeOptions options, AnalysisErrorListener reporter) { | 254 StrongModeOptions options, AnalysisErrorListener reporter) { |
| 232 return new CodeChecker( | 255 return new CodeChecker( |
| 233 new RestrictedRules(typeProvider, options: options), reporter, options); | 256 new RestrictedRules(typeProvider, options: options), reporter, options); |
| 234 } | 257 } |
| 235 | 258 |
| 236 String get outputDir => options.codegenOptions.outputDir; | 259 String get outputDir => options.codegenOptions.outputDir; |
| 237 TypeRules get rules => checker.rules; | 260 TypeRules get rules => checker.rules; |
| 238 AnalysisErrorListener get reporter => checker.reporter; | 261 AnalysisErrorListener get reporter => checker.reporter; |
| 239 | 262 |
| 240 Uri stringToUri(String uriString) { | 263 Uri stringToUri(String uriString) { |
| 241 var uri = uriString.startsWith('dart:') || uriString.startsWith('package:') | 264 var uri = uriString.startsWith('dart:') || uriString.startsWith('package:') |
| 242 ? Uri.parse(uriString) | 265 ? Uri.parse(uriString) |
| 243 : new Uri.file(uriString); | 266 : new Uri.file(path.absolute(uriString)); |
| 244 return uri; | 267 return uri; |
| 245 } | 268 } |
| 246 | 269 |
| 247 /// Directory presumed to be the common prefix for all input file:// URIs. | 270 /// Directory presumed to be the common prefix for all input file:// URIs. |
| 248 /// Used when computing output paths. | 271 /// Used when computing output paths. |
| 249 /// | 272 /// |
| 250 /// For example: | 273 /// For example: |
| 251 /// dartdevc -o out foo/a.dart bar/b.dart | 274 /// dartdevc -o out foo/a.dart bar/b.dart |
| 252 /// | 275 /// |
| 253 /// Will produce: | 276 /// Will produce: |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 /// * dart:core -> dart/core | 320 /// * dart:core -> dart/core |
| 298 /// * file:foo/bar/baz.dart -> foo/bar/baz | 321 /// * file:foo/bar/baz.dart -> foo/bar/baz |
| 299 /// * package:qux/qux.dart -> qux/qux | 322 /// * package:qux/qux.dart -> qux/qux |
| 300 /// | 323 /// |
| 301 /// For file: URLs this will also make them relative to [inputBaseDir]. | 324 /// For file: URLs this will also make them relative to [inputBaseDir]. |
| 302 // TODO(jmesserly): we need to figure out a way to keep package and file URLs | 325 // TODO(jmesserly): we need to figure out a way to keep package and file URLs |
| 303 // from conflicting. | 326 // from conflicting. |
| 304 String getModuleName(Uri uri) { | 327 String getModuleName(Uri uri) { |
| 305 var filepath = path.withoutExtension(uri.path); | 328 var filepath = path.withoutExtension(uri.path); |
| 306 if (uri.scheme == 'dart') { | 329 if (uri.scheme == 'dart') { |
| 307 filepath = 'dart/$filepath'; | 330 return 'dart/$filepath'; |
| 308 } else if (uri.scheme == 'file') { | 331 } else if (uri.scheme == 'file') { |
| 309 filepath = path.relative(filepath, from: inputBaseDir); | 332 return path.relative(filepath, from: inputBaseDir); |
| 310 } else { | 333 } else { |
| 311 assert(uri.scheme == 'package'); | 334 assert(uri.scheme == 'package'); |
| 312 // filepath is good here, we want the output to start with a directory | 335 // filepath is good here, we want the output to start with a directory |
| 313 // matching the package name. | 336 // matching the package name. |
| 337 return filepath; |
| 314 } | 338 } |
| 315 return filepath; | |
| 316 } | 339 } |
| 317 | 340 |
| 318 /// Log any errors encountered when resolving [source] and return whether any | 341 /// Log any errors encountered when resolving [source] and return whether any |
| 319 /// errors were found. | 342 /// errors were found. |
| 320 bool logErrors(Source source) { | 343 bool logErrors(Source source) { |
| 321 List<AnalysisError> errors = context.computeErrors(source); | 344 List<AnalysisError> errors = context.computeErrors(source); |
| 322 bool failure = false; | 345 bool failure = false; |
| 323 if (errors.isNotEmpty) { | 346 if (errors.isNotEmpty) { |
| 324 for (var error in errors) { | 347 for (var error in errors) { |
| 325 // Always skip TODOs. | 348 // Always skip TODOs. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 'dart.async', | 382 'dart.async', |
| 360 'dart._foreign_helper', | 383 'dart._foreign_helper', |
| 361 'dart._js_embedded_names', | 384 'dart._js_embedded_names', |
| 362 'dart._js_helper', | 385 'dart._js_helper', |
| 363 'dart.isolate', | 386 'dart.isolate', |
| 364 'dart.typed_data', | 387 'dart.typed_data', |
| 365 'dart._native_typed_data', | 388 'dart._native_typed_data', |
| 366 'dart._isolate_helper', | 389 'dart._isolate_helper', |
| 367 'dart._js_primitives', | 390 'dart._js_primitives', |
| 368 'dart.convert', | 391 'dart.convert', |
| 392 // TODO(jmesserly): these are not part of corelib library cycle, and shouldn't |
| 393 // be listed here. Instead, their source should be copied on demand if they |
| 394 // are actually used by the application. |
| 369 'dart.mirrors', | 395 'dart.mirrors', |
| 370 'dart._js_mirrors', | 396 'dart._js_mirrors', |
| 371 'dart.js' | 397 'dart.js' |
| 372 // _foreign_helper is not included, as it only defines the JS builtin that | 398 // _foreign_helper is not included, as it only defines the JS builtin that |
| 373 // the compiler handles at compile time. | 399 // the compiler handles at compile time. |
| 374 ]; | 400 ]; |
| 375 | 401 |
| 376 /// Runtime files added to all applications when running the compiler in the | 402 /// Runtime files added to all applications when running the compiler in the |
| 377 /// command line. | 403 /// command line. |
| 378 final defaultRuntimeFiles = () { | 404 final defaultRuntimeFiles = () { |
| 379 var files = [ | 405 var files = [ |
| 380 'harmony_feature_check.js', | 406 'harmony_feature_check.js', |
| 381 'dart_utils.js', | 407 'dart_utils.js', |
| 382 'dart_library.js', | 408 'dart_library.js', |
| 383 '_errors.js', | 409 '_errors.js', |
| 384 '_types.js', | 410 '_types.js', |
| 385 '_rtti.js', | 411 '_rtti.js', |
| 386 '_classes.js', | 412 '_classes.js', |
| 387 '_operations.js', | 413 '_operations.js', |
| 388 'dart_runtime.js', | 414 'dart_runtime.js', |
| 389 ]; | 415 ]; |
| 390 files.addAll(corelibOrder.map((l) => l.replaceAll('.', '/') + '.js')); | 416 files.addAll(corelibOrder.map((l) => l.replaceAll('.', '/') + '.js')); |
| 391 return files; | 417 return files; |
| 392 }(); | 418 }(); |
| 393 | 419 |
| 394 final _log = new Logger('dev_compiler.src.compiler'); | 420 final _log = new Logger('dev_compiler.src.compiler'); |
| OLD | NEW |