| OLD | NEW |
| 1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Fletch 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 library fletchc.fletch_compiler_implementation; | 5 library fletchc.fletch_compiler_implementation; |
| 6 | 6 |
| 7 import 'dart:async' show | 7 import 'dart:async' show |
| 8 EventSink; | 8 EventSink; |
| 9 | 9 |
| 10 import 'package:sdk_library_metadata/libraries.dart' show | 10 import 'package:sdk_library_metadata/libraries.dart' show |
| 11 libraries, | |
| 12 LibraryInfo; | 11 LibraryInfo; |
| 13 | 12 |
| 14 import 'package:compiler/compiler_new.dart' as api; | 13 import 'package:compiler/compiler_new.dart' as api; |
| 15 | 14 |
| 16 import 'package:compiler/src/apiimpl.dart' as apiimpl; | 15 import 'package:compiler/src/apiimpl.dart' as apiimpl; |
| 17 | 16 |
| 17 import 'package:compiler/src/compiler.dart' show |
| 18 GlobalDependencyRegistry; |
| 19 |
| 18 import 'package:compiler/src/io/source_file.dart'; | 20 import 'package:compiler/src/io/source_file.dart'; |
| 19 | 21 |
| 20 import 'package:compiler/src/source_file_provider.dart' show | 22 import 'package:compiler/src/source_file_provider.dart' show |
| 21 SourceFileProvider; | 23 SourceFileProvider; |
| 22 | 24 |
| 23 import 'package:compiler/src/elements/modelx.dart' show | 25 import 'package:compiler/src/elements/modelx.dart' show |
| 24 CompilationUnitElementX, | 26 CompilationUnitElementX, |
| 25 LibraryElementX; | 27 LibraryElementX; |
| 26 | 28 |
| 27 import 'package:compiler/compiler_new.dart' show | 29 import 'package:compiler/compiler_new.dart' show |
| 28 CompilerOutput; | 30 CompilerOutput; |
| 29 | 31 |
| 30 import 'package:compiler/src/util/uri_extras.dart' show | 32 import 'package:compiler/src/diagnostics/messages.dart' show |
| 31 relativize; | |
| 32 | |
| 33 import 'package:compiler/src/dart2jslib.dart' show | |
| 34 CodegenRegistry, | |
| 35 Message, | 33 Message, |
| 36 MessageKind, | 34 MessageKind, |
| 37 MessageTemplate; | 35 MessageTemplate; |
| 36 import 'package:compiler/src/diagnostics/source_span.dart' show |
| 37 SourceSpan; |
| 38 | 38 |
| 39 import 'package:compiler/src/util/util.dart' show | 39 import 'package:compiler/src/diagnostics/diagnostic_listener.dart' show |
| 40 DiagnosticMessage, |
| 41 DiagnosticReporter; |
| 42 |
| 43 import 'package:compiler/src/diagnostics/spannable.dart' show |
| 40 Spannable; | 44 Spannable; |
| 41 | 45 |
| 42 import 'fletch_registry.dart' show | 46 import 'fletch_registry.dart' show |
| 43 FletchRegistry; | 47 FletchRegistry; |
| 44 | 48 |
| 45 import 'please_report_crash.dart' show | 49 import 'please_report_crash.dart' show |
| 46 crashReportRequested, | 50 crashReportRequested, |
| 47 requestBugReportOnCompilerCrashMessage; | 51 requestBugReportOnCompilerCrashMessage; |
| 48 | 52 |
| 49 import 'fletch_function_builder.dart'; | 53 import 'fletch_function_builder.dart'; |
| 50 import 'debug_info.dart'; | 54 import 'debug_info.dart'; |
| 51 import 'find_position_visitor.dart'; | 55 import 'find_position_visitor.dart'; |
| 52 import 'fletch_context.dart'; | 56 import 'fletch_context.dart'; |
| 53 | 57 |
| 58 import 'fletch_enqueuer.dart' show |
| 59 FletchEnqueueTask; |
| 60 |
| 54 import '../fletch_system.dart'; | 61 import '../fletch_system.dart'; |
| 62 import 'package:compiler/src/diagnostics/diagnostic_listener.dart'; |
| 63 import 'package:compiler/src/elements/elements.dart'; |
| 55 | 64 |
| 56 const EXTRA_DART2JS_OPTIONS = const <String>[ | 65 const EXTRA_DART2JS_OPTIONS = const <String>[ |
| 57 // TODO(ahe): This doesn't completely disable type inference. Investigate. | 66 // TODO(ahe): This doesn't completely disable type inference. Investigate. |
| 58 '--disable-type-inference', | 67 '--disable-type-inference', |
| 59 '--output-type=dart', | 68 '--output-type=dart', |
| 60 // We want to continue generating code in the case of errors, to support | 69 // We want to continue generating code in the case of errors, to support |
| 61 // incremental fixes of erroneous code. | 70 // incremental fixes of erroneous code. |
| 62 '--generate-code-with-compile-time-errors', | 71 '--generate-code-with-compile-time-errors', |
| 63 ]; | 72 ]; |
| 64 | 73 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 documented: false, | 114 documented: false, |
| 106 platforms: FLETCH_PLATFORM), | 115 platforms: FLETCH_PLATFORM), |
| 107 | 116 |
| 108 "fletch.os": const LibraryInfo( | 117 "fletch.os": const LibraryInfo( |
| 109 "os/os.dart", | 118 "os/os.dart", |
| 110 categories: "Client,Server,Embedded", | 119 categories: "Client,Server,Embedded", |
| 111 documented: false, | 120 documented: false, |
| 112 platforms: FLETCH_PLATFORM), | 121 platforms: FLETCH_PLATFORM), |
| 113 }; | 122 }; |
| 114 | 123 |
| 115 class FletchCompilerImplementation extends apiimpl.Compiler { | 124 class FletchCompilerImplementation extends apiimpl.CompilerImpl { |
| 116 final Map<String, LibraryInfo> fletchLibraries = <String, LibraryInfo>{}; | 125 final Map<String, LibraryInfo> fletchLibraries = <String, LibraryInfo>{}; |
| 117 | 126 |
| 118 final Uri fletchVm; | 127 final Uri fletchVm; |
| 119 | 128 |
| 120 /// Location of fletch patch files. | 129 /// Location of fletch patch files. |
| 121 final Uri patchRoot; | 130 final Uri patchRoot; |
| 122 | 131 |
| 123 final Uri nativesJson; | 132 final Uri nativesJson; |
| 124 | 133 |
| 125 Map<Uri, CompilationUnitElementX> compilationUnits; | 134 Map<Uri, CompilationUnitElementX> compilationUnits; |
| 126 FletchContext internalContext; | 135 FletchContext internalContext; |
| 127 | 136 |
| 128 /// A reference to [../compiler.dart:FletchCompiler] used for testing. | 137 /// A reference to [../compiler.dart:FletchCompiler] used for testing. |
| 129 // TODO(ahe): Clean this up and remove this. | 138 // TODO(ahe): Clean this up and remove this. |
| 130 var helper; | 139 var helper; |
| 131 | 140 |
| 141 @override |
| 142 FletchEnqueueTask get enqueuer => super.enqueuer; |
| 143 |
| 144 FletchDiagnosticReporter reporter; |
| 145 |
| 132 FletchCompilerImplementation( | 146 FletchCompilerImplementation( |
| 133 api.CompilerInput provider, | 147 api.CompilerInput provider, |
| 134 api.CompilerOutput outputProvider, | 148 api.CompilerOutput outputProvider, |
| 135 api.CompilerDiagnostics handler, | 149 api.CompilerDiagnostics handler, |
| 136 Uri libraryRoot, | 150 Uri libraryRoot, |
| 137 Uri packageConfig, | 151 Uri packageConfig, |
| 138 this.patchRoot, | 152 this.patchRoot, |
| 139 this.nativesJson, | 153 this.nativesJson, |
| 140 List<String> options, | 154 List<String> options, |
| 141 Map<String, dynamic> environment, | 155 Map<String, dynamic> environment, |
| 142 this.fletchVm) | 156 this.fletchVm) |
| 143 : super( | 157 : super( |
| 144 provider, outputProvider, handler, libraryRoot, null, | 158 provider, outputProvider, handler, libraryRoot, null, |
| 145 EXTRA_DART2JS_OPTIONS.toList()..addAll(options), environment, | 159 EXTRA_DART2JS_OPTIONS.toList()..addAll(options), environment, |
| 146 packageConfig, null, FletchBackend.newInstance) { | 160 packageConfig, null, FletchBackend.newInstance) { |
| 147 CodegenRegistry global = globalDependencies; | 161 reporter = new FletchDiagnosticReporter(super.reporter); |
| 148 globalDependencies = | |
| 149 new FletchRegistry(this, global.treeElements).asRegistry; | |
| 150 } | 162 } |
| 151 | 163 |
| 152 bool get showPackageWarnings => true; | 164 bool get showPackageWarnings => true; |
| 153 | 165 |
| 154 FletchContext get context { | 166 FletchContext get context { |
| 155 if (internalContext == null) { | 167 if (internalContext == null) { |
| 156 internalContext = new FletchContext(this); | 168 internalContext = new FletchContext(this); |
| 157 } | 169 } |
| 158 return internalContext; | 170 return internalContext; |
| 159 } | 171 } |
| 160 | 172 |
| 161 String fletchPatchLibraryFor(String name) => FLETCH_PATCHES[name]; | 173 String fletchPatchLibraryFor(String name) => FLETCH_PATCHES[name]; |
| 162 | 174 |
| 163 LibraryInfo lookupLibraryInfo(String name) { | 175 @override |
| 164 return fletchLibraries.putIfAbsent(name, () { | 176 Uri lookupLibraryUri(String libraryName) { |
| 165 // Let FLETCH_LIBRARIES shadow libraries. | 177 LibraryInfo info = FLETCH_LIBRARIES[libraryName]; |
| 166 if (FLETCH_LIBRARIES.containsKey(name)) { | 178 if (info == null) return super.lookupLibraryUri(libraryName); |
| 167 return computeFletchLibraryInfo(name); | 179 return patchRoot.resolve("lib/${info.path}"); |
| 168 } | |
| 169 LibraryInfo info = libraries[name]; | |
| 170 if (info == null) { | |
| 171 return computeFletchLibraryInfo(name); | |
| 172 } | |
| 173 return new LibraryInfo( | |
| 174 info.path, | |
| 175 categories: info.categoriesString, | |
| 176 dart2jsPath: info.dart2jsPath, | |
| 177 dart2jsPatchPath: fletchPatchLibraryFor(name), | |
| 178 implementation: info.implementation, | |
| 179 documented: info.documented, | |
| 180 maturity: info.maturity, | |
| 181 platforms: info.platforms); | |
| 182 }); | |
| 183 } | |
| 184 | |
| 185 LibraryInfo computeFletchLibraryInfo(String name) { | |
| 186 LibraryInfo info = FLETCH_LIBRARIES[name]; | |
| 187 if (info == null) return null; | |
| 188 // Since this LibraryInfo is completely internal to Fletch, there's no need | |
| 189 // for dart2js extensions and patches. | |
| 190 assert(info.dart2jsPath == null); | |
| 191 assert(info.dart2jsPatchPath == null); | |
| 192 String path = relativize( | |
| 193 libraryRoot, patchRoot.resolve("lib/${info.path}"), false); | |
| 194 return new LibraryInfo( | |
| 195 '../$path', | |
| 196 categories: info.categoriesString, | |
| 197 implementation: info.implementation, | |
| 198 documented: info.documented, | |
| 199 maturity: info.maturity, | |
| 200 platforms: info.platforms); | |
| 201 } | 180 } |
| 202 | 181 |
| 203 Uri resolvePatchUri(String dartLibraryPath) { | 182 Uri resolvePatchUri(String dartLibraryPath) { |
| 204 String patchPath = lookupPatchPath(dartLibraryPath); | 183 String patchPath = fletchPatchLibraryFor(dartLibraryPath); |
| 205 if (patchPath == null) return null; | 184 if (patchPath == null) return null; |
| 206 return patchRoot.resolve(patchPath); | 185 return patchRoot.resolve("lib/$patchPath"); |
| 207 } | 186 } |
| 208 | 187 |
| 209 CompilationUnitElementX compilationUnitForUri(Uri uri) { | 188 CompilationUnitElementX compilationUnitForUri(Uri uri) { |
| 210 if (compilationUnits == null) { | 189 if (compilationUnits == null) { |
| 211 compilationUnits = <Uri, CompilationUnitElementX>{}; | 190 compilationUnits = <Uri, CompilationUnitElementX>{}; |
| 212 libraryLoader.libraries.forEach((LibraryElementX library) { | 191 libraryLoader.libraries.forEach((LibraryElementX library) { |
| 213 for (CompilationUnitElementX unit in library.compilationUnits) { | 192 for (CompilationUnitElementX unit in library.compilationUnits) { |
| 214 compilationUnits[unit.script.resourceUri] = unit; | 193 compilationUnits[unit.script.resourceUri] = unit; |
| 215 } | 194 } |
| 216 }); | 195 }); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 // TODO(ahe): [file] should be a Uri. | 238 // TODO(ahe): [file] should be a Uri. |
| 260 Uri uri = Uri.base.resolve(file); | 239 Uri uri = Uri.base.resolve(file); |
| 261 SourceFile sourceFile = getSourceFile(provider, uri); | 240 SourceFile sourceFile = getSourceFile(provider, uri); |
| 262 if (sourceFile == null) return null; | 241 if (sourceFile == null) return null; |
| 263 if (line >= sourceFile.lineStarts.length) return null; | 242 if (line >= sourceFile.lineStarts.length) return null; |
| 264 return sourceFile.lineStarts[line] + column; | 243 return sourceFile.lineStarts[line] + column; |
| 265 } | 244 } |
| 266 | 245 |
| 267 void reportVerboseInfo( | 246 void reportVerboseInfo( |
| 268 Spannable node, | 247 Spannable node, |
| 269 String message, | 248 String messageText, |
| 270 {bool forceVerbose: false}) { | 249 {bool forceVerbose: false}) { |
| 271 // TODO(johnniwinther): Use super.reportVerboseInfo once added. | 250 // TODO(johnniwinther): Use super.reportVerboseInfo once added. |
| 272 if (forceVerbose || verbose) { | 251 if (forceVerbose || verbose) { |
| 273 MessageTemplate template = MessageTemplate.TEMPLATES[MessageKind.GENERIC]; | 252 MessageTemplate template = MessageTemplate.TEMPLATES[MessageKind.GENERIC]; |
| 274 reportDiagnostic( | 253 SourceSpan span = reporter.spanFromSpannable(node); |
| 275 node, template.message({'text': message}, true), api.Diagnostic.HINT); | 254 Message message = template.message({'text': messageText}); |
| 255 reportDiagnostic(new DiagnosticMessage(span, node, message), |
| 256 [], api.Diagnostic.HINT); |
| 276 } | 257 } |
| 277 } | 258 } |
| 278 | 259 |
| 279 void pleaseReportCrash() { | 260 void pleaseReportCrash() { |
| 280 if (crashReportRequested) return; | 261 if (crashReportRequested) return; |
| 281 crashReportRequested = true; | 262 crashReportRequested = true; |
| 282 print(requestBugReportOnCompilerCrashMessage); | 263 print(requestBugReportOnCompilerCrashMessage); |
| 283 } | 264 } |
| 284 | 265 |
| 285 void reportError( | 266 void reportError( |
| 286 Spannable node, | 267 Spannable node, |
| 287 MessageKind messageKind, | 268 MessageKind messageKind, |
| 288 [Map arguments = const {}]) { | 269 [Map arguments = const {}]) { |
| 289 if (messageKind == MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND) { | 270 if (messageKind == MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND) { |
| 290 const String noMirrors = | 271 const String noMirrors = |
| 291 "Fletch doesn't support 'dart:mirrors'. See https://goo.gl/Kwrd0O"; | 272 "Fletch doesn't support 'dart:mirrors'. See https://goo.gl/Kwrd0O"; |
| 292 messageKind = MessageKind.GENERIC; | 273 messageKind = MessageKind.GENERIC; |
| 293 arguments = {'text': noMirrors}; | 274 arguments = {'text': noMirrors}; |
| 294 } | 275 } |
| 295 super.reportError(node, messageKind, arguments); | 276 super.reporter.reportErrorMessage(node, messageKind, arguments); |
| 296 } | 277 } |
| 297 } | 278 } |
| 298 | 279 |
| 299 /// Output provider which collects output in [output]. | 280 /// Output provider which collects output in [output]. |
| 300 class OutputProvider implements CompilerOutput { | 281 class OutputProvider implements CompilerOutput { |
| 301 final Map<String, String> output = new Map<String, String>(); | 282 final Map<String, String> output = new Map<String, String>(); |
| 302 | 283 |
| 303 EventSink<String> createEventSink(String name, String extension) { | 284 EventSink<String> createEventSink(String name, String extension) { |
| 304 return new StringEventSink((String data) { | 285 return new StringEventSink((String data) { |
| 305 output['$name.$extension'] = data; | 286 output['$name.$extension'] = data; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 334 } | 315 } |
| 335 } | 316 } |
| 336 | 317 |
| 337 SourceFile getSourceFile(api.CompilerInput provider, Uri uri) { | 318 SourceFile getSourceFile(api.CompilerInput provider, Uri uri) { |
| 338 if (provider is SourceFileProvider) { | 319 if (provider is SourceFileProvider) { |
| 339 return provider.sourceFiles[uri]; | 320 return provider.sourceFiles[uri]; |
| 340 } else { | 321 } else { |
| 341 return null; | 322 return null; |
| 342 } | 323 } |
| 343 } | 324 } |
| 325 |
| 326 /// A wrapper around a DiagnosticReporter, that customizes some messages to |
| 327 /// Fletch. |
| 328 class FletchDiagnosticReporter extends DiagnosticReporter { |
| 329 DiagnosticReporter _internalReporter; |
| 330 |
| 331 FletchDiagnosticReporter(this._internalReporter); |
| 332 |
| 333 @override |
| 334 DiagnosticMessage createMessage(Spannable spannable, |
| 335 MessageKind messageKind, |
| 336 [Map arguments = const {}]) { |
| 337 return _internalReporter.createMessage(spannable, messageKind, arguments); |
| 338 } |
| 339 |
| 340 @override |
| 341 internalError(Spannable spannable, message) { |
| 342 return _internalReporter.internalError(spannable, message); |
| 343 } |
| 344 |
| 345 @override |
| 346 void log(message) { |
| 347 _internalReporter.log(message); |
| 348 } |
| 349 |
| 350 @override |
| 351 DiagnosticOptions get options => _internalReporter.options; |
| 352 |
| 353 @override |
| 354 void reportError(DiagnosticMessage message, |
| 355 [List<DiagnosticMessage> infos = const <DiagnosticMessage> []]) { |
| 356 if (message.message.kind == |
| 357 MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND) { |
| 358 const String noMirrors = |
| 359 "Fletch doesn't support 'dart:mirrors'. See https://goo.gl/Kwrd0O"; |
| 360 message = createMessage(message.spannable, |
| 361 MessageKind.GENERIC, |
| 362 {'text': message}); |
| 363 } |
| 364 _internalReporter.reportError(message, infos); |
| 365 } |
| 366 |
| 367 @override |
| 368 void reportHint(DiagnosticMessage message, |
| 369 [List<DiagnosticMessage> infos = const <DiagnosticMessage> []]) { |
| 370 _internalReporter.reportHint(message, infos); |
| 371 } |
| 372 |
| 373 @override |
| 374 void reportInfo(Spannable node, |
| 375 MessageKind errorCode, |
| 376 [Map arguments = const {}]) { |
| 377 _internalReporter.reportInfo(node, errorCode, arguments); |
| 378 } |
| 379 |
| 380 @override |
| 381 void reportWarning(DiagnosticMessage message, |
| 382 [List<DiagnosticMessage> infos = const <DiagnosticMessage> []]) { |
| 383 _internalReporter.reportWarning(message, infos); |
| 384 } |
| 385 |
| 386 @override |
| 387 SourceSpan spanFromSpannable(Spannable node) { |
| 388 return _internalReporter.spanFromSpannable(node); |
| 389 } |
| 390 |
| 391 @override |
| 392 withCurrentElement(Element element, f()) { |
| 393 return _internalReporter.withCurrentElement(element, f); |
| 394 } |
| 395 } |
| OLD | NEW |