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 library dev_compiler.src.codegen.dart_codegen; | 5 library dev_compiler.src.codegen.dart_codegen; |
6 | 6 |
7 import 'dart:io' show File; | 7 import 'dart:io' show File; |
8 | 8 |
9 import 'package:analyzer/analyzer.dart' as analyzer; | 9 import 'package:analyzer/analyzer.dart' as analyzer; |
10 import 'package:analyzer/src/generated/ast.dart'; | 10 import 'package:analyzer/src/generated/ast.dart'; |
11 import 'package:analyzer/src/generated/element.dart'; | 11 import 'package:analyzer/src/generated/element.dart'; |
12 import 'package:analyzer/src/generated/java_core.dart' as java_core; | 12 import 'package:analyzer/src/generated/java_core.dart' as java_core; |
13 import 'package:analyzer/src/generated/scanner.dart' show Token; | 13 import 'package:analyzer/src/generated/scanner.dart' show Token; |
14 import 'package:dart_style/dart_style.dart'; | 14 import 'package:dart_style/dart_style.dart'; |
15 import 'package:logging/logging.dart' as logger; | 15 import 'package:logging/logging.dart' as logger; |
16 import 'package:path/path.dart' as path; | 16 import 'package:path/path.dart' as path; |
17 | 17 |
18 import 'package:dev_compiler/src/info.dart'; | 18 import 'package:dev_compiler/src/info.dart'; |
19 import 'package:dev_compiler/src/checker/rules.dart'; | 19 import 'package:dev_compiler/src/checker/rules.dart'; |
20 import 'package:dev_compiler/src/options.dart'; | 20 import 'package:dev_compiler/src/options.dart'; |
21 import 'package:dev_compiler/src/utils.dart' as utils; | 21 import 'package:dev_compiler/src/utils.dart' as utils; |
22 import 'ast_builder.dart'; | 22 import 'ast_builder.dart'; |
23 import 'code_generator.dart' as codegenerator; | 23 import 'code_generator.dart' as codegenerator; |
24 import 'reify_coercions.dart' show CoercionReifier, NewTypeIdDesc; | 24 import 'reify_coercions.dart' |
| 25 show CoercionReifier, NewTypeIdDesc, InstrumentedRuntime; |
25 | 26 |
26 final _log = new logger.Logger('dev_compiler.dart_codegen'); | 27 final _log = new logger.Logger('dev_compiler.dart_codegen'); |
27 | 28 |
28 class DevCompilerRuntime { | 29 class DevCompilerRuntime extends InstrumentedRuntime { |
29 Identifier _runtimeId = AstBuilder.identifierFromString("DEVC\$RT"); | 30 Identifier _runtimeId = AstBuilder.identifierFromString("DEVC\$RT"); |
30 | 31 |
31 Identifier _castId; | 32 Identifier _castId; |
32 Identifier _typeToTypeId; | 33 Identifier _typeToTypeId; |
33 Identifier _wrapId; | 34 Identifier _wrapId; |
34 | 35 |
35 DevCompilerRuntime() { | 36 DevCompilerRuntime() { |
36 _castId = _prefixId(AstBuilder.identifierFromString("cast")); | 37 _castId = _prefixId(AstBuilder.identifierFromString("cast")); |
37 _typeToTypeId = _prefixId(AstBuilder.identifierFromString("type")); | 38 _typeToTypeId = _prefixId(AstBuilder.identifierFromString("type")); |
38 _wrapId = _prefixId(AstBuilder.identifierFromString("wrap")); | 39 _wrapId = _prefixId(AstBuilder.identifierFromString("wrap")); |
(...skipping 14 matching lines...) Expand all Loading... |
53 if (oper.operation == "type") return _typeToTypeId; | 54 if (oper.operation == "type") return _typeToTypeId; |
54 assert(false); | 55 assert(false); |
55 return null; | 56 return null; |
56 } | 57 } |
57 | 58 |
58 Expression runtimeOperation(RuntimeOperation oper) { | 59 Expression runtimeOperation(RuntimeOperation oper) { |
59 var id = runtimeId(oper); | 60 var id = runtimeId(oper); |
60 var args = oper.arguments; | 61 var args = oper.arguments; |
61 return AstBuilder.application(id, args); | 62 return AstBuilder.application(id, args); |
62 } | 63 } |
| 64 |
| 65 @override |
| 66 Expression wrap(Expression coercion, Expression e, Expression fromType, |
| 67 Expression toType, Expression dartIs, String kind, String location) { |
| 68 var k = AstBuilder.stringLiteral(kind); |
| 69 var key = AstBuilder.multiLineStringLiteral(location); |
| 70 var arguments = <Expression>[coercion, e, fromType, toType, k, key, dartIs]; |
| 71 return new RuntimeOperation("wrap", arguments); |
| 72 } |
| 73 |
| 74 Expression cast(Expression e, Expression fromType, Expression toType, |
| 75 Expression dartIs, String kind, String location, bool ground) { |
| 76 var k = AstBuilder.stringLiteral(kind); |
| 77 var key = AstBuilder.multiLineStringLiteral(location); |
| 78 var g = AstBuilder.booleanLiteral(ground); |
| 79 var arguments = <Expression>[e, fromType, toType, k, key, dartIs, g]; |
| 80 return new RuntimeOperation("cast", arguments); |
| 81 } |
| 82 |
| 83 Expression type(Expression witnessFunction) { |
| 84 return new RuntimeOperation("type", <Expression>[witnessFunction]); |
| 85 } |
63 } | 86 } |
64 | 87 |
65 // TODO(leafp) This is kind of a hack, but it works for now. | 88 // TODO(leafp) This is kind of a hack, but it works for now. |
66 class FileWriter extends java_core.PrintStringWriter { | 89 class FileWriter extends java_core.PrintStringWriter { |
67 final CompilerOptions options; | 90 final CompilerOptions options; |
68 String _path; | 91 String _path; |
69 FileWriter(this.options, this._path); | 92 FileWriter(this.options, this._path); |
70 int indent = 0; | 93 int indent = 0; |
71 int withinInterpolationExpression = 0; | 94 int withinInterpolationExpression = 0; |
72 bool insideForLoop = false; | 95 bool insideForLoop = false; |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 } | 247 } |
225 } | 248 } |
226 | 249 |
227 // TODO(leafp) Not sure if this is the right way to generate | 250 // TODO(leafp) Not sure if this is the right way to generate |
228 // Dart source going forward, but it's a quick way to get started. | 251 // Dart source going forward, but it's a quick way to get started. |
229 class UnitGenerator extends UnitGeneratorCommon with ConversionVisitor<Object> { | 252 class UnitGenerator extends UnitGeneratorCommon with ConversionVisitor<Object> { |
230 CompilationUnit unit; | 253 CompilationUnit unit; |
231 final java_core.PrintWriter _out; | 254 final java_core.PrintWriter _out; |
232 final String outDir; | 255 final String outDir; |
233 Set<LibraryElement> _extraImports; | 256 Set<LibraryElement> _extraImports; |
234 final _runtime = new DevCompilerRuntime(); | 257 final _runtime; |
235 bool _qualifyNames = true; | 258 bool _qualifyNames = true; |
236 Map<Identifier, NewTypeIdDesc> _newIdentifiers; | 259 Map<Identifier, NewTypeIdDesc> _newIdentifiers; |
237 | 260 |
238 UnitGenerator(this.unit, java_core.PrintWriter out, String this.outDir, | 261 UnitGenerator(this.unit, java_core.PrintWriter out, String this.outDir, |
239 this._extraImports, this._newIdentifiers) | 262 this._extraImports, this._newIdentifiers, this._runtime) |
240 : _out = out, | 263 : _out = out, |
241 super(out); | 264 super(out); |
242 | 265 |
243 void output(String s) => _out.print(s); | 266 void output(String s) => _out.print(s); |
244 void outputln(String s) => _out.println(s); | 267 void outputln(String s) => _out.println(s); |
245 | 268 |
246 // Choose a canonical prefix for a library that we are adding. | 269 // Choose a canonical prefix for a library that we are adding. |
247 // Currently just chooses something unlikely to conflict with a user | 270 // Currently just chooses something unlikely to conflict with a user |
248 // prefix. | 271 // prefix. |
249 // TODO(leafp): Make this robust. | 272 // TODO(leafp): Make this robust. |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 } | 380 } |
358 | 381 |
359 void generate() { | 382 void generate() { |
360 visitCompilationUnit(unit); | 383 visitCompilationUnit(unit); |
361 } | 384 } |
362 } | 385 } |
363 | 386 |
364 class DartGenerator extends codegenerator.CodeGenerator { | 387 class DartGenerator extends codegenerator.CodeGenerator { |
365 final CompilerOptions options; | 388 final CompilerOptions options; |
366 TypeRules _rules; | 389 TypeRules _rules; |
| 390 final DevCompilerRuntime _runtime = new DevCompilerRuntime(); |
367 | 391 |
368 DartGenerator(String outDir, Uri root, TypeRules rules, this.options) | 392 DartGenerator(String outDir, Uri root, TypeRules rules, this.options) |
369 : _rules = rules, | 393 : _rules = rules, |
370 super(outDir, root, rules); | 394 super(outDir, root, rules); |
371 | 395 |
372 Set<LibraryElement> computeExtraImports(Map<Identifier, NewTypeIdDesc> ids) { | 396 Set<LibraryElement> computeExtraImports(Map<Identifier, NewTypeIdDesc> ids) { |
373 var imports = new Set<LibraryElement>(); | 397 var imports = new Set<LibraryElement>(); |
374 void process(Identifier id, NewTypeIdDesc desc) { | 398 void process(Identifier id, NewTypeIdDesc desc) { |
375 if (_identifierNeedsQualification(id, desc)) { | 399 if (_identifierNeedsQualification(id, desc)) { |
376 var library = desc.importedFrom; | 400 var library = desc.importedFrom; |
377 if (utils.isDartPrivateLibrary(library)) { | 401 if (utils.isDartPrivateLibrary(library)) { |
378 _log.severe("Dropping import of private library ${library}\n"); | 402 _log.severe("Dropping import of private library ${library}\n"); |
379 return; | 403 return; |
380 } | 404 } |
381 imports.add(library); | 405 imports.add(library); |
382 } | 406 } |
383 } | 407 } |
384 ids.forEach(process); | 408 ids.forEach(process); |
385 return imports; | 409 return imports; |
386 } | 410 } |
387 | 411 |
388 String generateLibrary(LibraryUnit library, LibraryInfo info) { | 412 String generateLibrary(LibraryUnit library, LibraryInfo info) { |
389 var r = new CoercionReifier(library, rules); | 413 var r = new CoercionReifier(library, rules, options, _runtime); |
390 var ids = r.reify(); | 414 var ids = r.reify(); |
391 var extraImports = computeExtraImports(ids); | 415 var extraImports = computeExtraImports(ids); |
392 | 416 |
393 for (var unit in library.partsThenLibrary) { | 417 for (var unit in library.partsThenLibrary) { |
394 var libraryDir = makeOutputDirectory(info, unit); | 418 var libraryDir = makeOutputDirectory(info, unit); |
395 var uri = unit.element.source.uri; | 419 var uri = unit.element.source.uri; |
396 _log.fine("Generating unit $uri"); | 420 _log.fine("Generating unit $uri"); |
397 FileWriter out = new FileWriter( | 421 FileWriter out = new FileWriter( |
398 options, path.join(libraryDir, '${uri.pathSegments.last}')); | 422 options, path.join(libraryDir, '${uri.pathSegments.last}')); |
399 var unitGen = new UnitGenerator(unit, out, outDir, extraImports, ids); | 423 var unitGen = |
| 424 new UnitGenerator(unit, out, outDir, extraImports, ids, _runtime); |
400 unitGen.generate(); | 425 unitGen.generate(); |
401 out.finalize(); | 426 out.finalize(); |
402 } | 427 } |
403 | 428 |
404 return null; | 429 return null; |
405 } | 430 } |
406 } | 431 } |
407 | 432 |
408 class EmptyUnitGenerator extends UnitGeneratorCommon { | 433 class EmptyUnitGenerator extends UnitGeneratorCommon { |
409 final java_core.PrintWriter _out; | 434 final java_core.PrintWriter _out; |
(...skipping 29 matching lines...) Expand all Loading... |
439 void generateUnit(CompilationUnit unit, LibraryInfo info, String libraryDir) { | 464 void generateUnit(CompilationUnit unit, LibraryInfo info, String libraryDir) { |
440 var uri = unit.element.source.uri; | 465 var uri = unit.element.source.uri; |
441 _log.fine("Emitting original unit " + uri.toString()); | 466 _log.fine("Emitting original unit " + uri.toString()); |
442 FileWriter out = new FileWriter( | 467 FileWriter out = new FileWriter( |
443 options, path.join(libraryDir, '${uri.pathSegments.last}')); | 468 options, path.join(libraryDir, '${uri.pathSegments.last}')); |
444 var unitGen = new EmptyUnitGenerator(unit, out); | 469 var unitGen = new EmptyUnitGenerator(unit, out); |
445 unitGen.generate(); | 470 unitGen.generate(); |
446 out.finalize(); | 471 out.finalize(); |
447 } | 472 } |
448 } | 473 } |
OLD | NEW |