Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(560)

Side by Side Diff: lib/src/codegen/dart_codegen.dart

Issue 1070453002: Refactor reifier to make it less dart_codegen specific. (Closed) Base URL: git@github.com:dart-lang/dart-dev-compiler.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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' as reifier; 24 import 'reify_coercions.dart' show CoercionReifier, NewTypeIdDesc;
25 25
26 final _log = new logger.Logger('dev_compiler.dart_codegen'); 26 final _log = new logger.Logger('dev_compiler.dart_codegen');
27 27
28 class DevCompilerRuntime { 28 class DevCompilerRuntime {
29 Identifier _runtimeId = AstBuilder.identifierFromString("DEVC\$RT"); 29 Identifier _runtimeId = AstBuilder.identifierFromString("DEVC\$RT");
30 30
31 Identifier _castId; 31 Identifier _castId;
32 Identifier _typeToTypeId; 32 Identifier _typeToTypeId;
33 Identifier _wrapId; 33 Identifier _wrapId;
34 34
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 s = d.format(s, uri: _path); 117 s = d.format(s, uri: _path);
118 } catch (e) { 118 } catch (e) {
119 _log.severe("Failed to format $_path: " + e.toString()); 119 _log.severe("Failed to format $_path: " + e.toString());
120 } 120 }
121 } 121 }
122 _log.fine("Writing file $_path"); 122 _log.fine("Writing file $_path");
123 new File(_path).writeAsStringSync(s); 123 new File(_path).writeAsStringSync(s);
124 } 124 }
125 } 125 }
126 126
127 bool _identifierNeedsQualification( 127 bool _identifierNeedsQualification(Identifier id, NewTypeIdDesc desc) {
128 Identifier id, LibraryElement current, Set<Identifier> restrict) { 128 var library = desc.importedFrom;
129 var element = id.bestElement; 129 if (library == null) return false;
130 return restrict.contains(id) && 130 if (library.isDartCore) return false;
131 element != null && 131 if (desc.fromCurrent) return false;
132 element.library != null && 132 return true;
133 (element is ClassElement || element is FunctionTypeAliasElement) &&
134 !element.library.isDartCore &&
135 element.library != current;
136 }
137
138 // For every type name to which we add a reference, record the library from
139 // which it comes so that we may add it to the list of imports.
140 class UnitImportResolver extends analyzer.GeneralizingAstVisitor
141 with ConversionVisitor {
142 final CompilationUnit unit;
143 final Set<LibraryElement> imports;
144 final _currentLibrary;
145 final _newIdentifiers;
146
147 UnitImportResolver(
148 this.unit, this._currentLibrary, this.imports, this._newIdentifiers);
149
150 void compute() {
151 visitCompilationUnit(unit);
152 return;
153 }
154
155 @override
156 void visitCompilationUnit(CompilationUnit node) {
157 node.declarations.forEach((node) => node.accept(this));
158 return;
159 }
160
161 @override
162 void visitIdentifier(Identifier id) {
Leaf 2015/04/07 22:29:58 All of this logic is now computed directly from th
163 if (id is PrefixedIdentifier) {
164 id.prefix.accept(this);
165 return;
166 }
167 if (_identifierNeedsQualification(id, _currentLibrary, _newIdentifiers)) {
168 if (utils.isDartPrivateLibrary(id.bestElement.library)) {
169 _log.severe(
170 "Dropping import of private library ${id.bestElement.library}\n");
171 return;
172 }
173 imports.add(id.bestElement.library);
174 }
175 return;
176 }
177 } 133 }
178 134
179 // This class just holds some additional syntactic helpers and 135 // This class just holds some additional syntactic helpers and
180 // fixes to the general ToSourceVisitor for use by subclasses. 136 // fixes to the general ToSourceVisitor for use by subclasses.
181 abstract class UnitGeneratorCommon extends analyzer.ToSourceVisitor { 137 abstract class UnitGeneratorCommon extends analyzer.ToSourceVisitor {
182 UnitGeneratorCommon(java_core.PrintWriter out) : super(out); 138 UnitGeneratorCommon(java_core.PrintWriter out) : super(out);
183 139
184 void output(String s); 140 void output(String s);
185 void outputln(String s); 141 void outputln(String s);
186 142
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 } 225 }
270 226
271 // TODO(leafp) Not sure if this is the right way to generate 227 // TODO(leafp) Not sure if this is the right way to generate
272 // Dart source going forward, but it's a quick way to get started. 228 // Dart source going forward, but it's a quick way to get started.
273 class UnitGenerator extends UnitGeneratorCommon with ConversionVisitor<Object> { 229 class UnitGenerator extends UnitGeneratorCommon with ConversionVisitor<Object> {
274 CompilationUnit unit; 230 CompilationUnit unit;
275 final java_core.PrintWriter _out; 231 final java_core.PrintWriter _out;
276 final String outDir; 232 final String outDir;
277 Set<LibraryElement> _extraImports; 233 Set<LibraryElement> _extraImports;
278 final _runtime = new DevCompilerRuntime(); 234 final _runtime = new DevCompilerRuntime();
279 LibraryElement _currentLibrary;
280 bool _qualifyNames = true; 235 bool _qualifyNames = true;
281 Set<Identifier> _newIdentifiers; 236 Map<Identifier, NewTypeIdDesc> _newIdentifiers;
282 237
283 UnitGenerator(this.unit, java_core.PrintWriter out, String this.outDir, 238 UnitGenerator(this.unit, java_core.PrintWriter out, String this.outDir,
284 this._extraImports, this._newIdentifiers) 239 this._extraImports, this._newIdentifiers)
285 : _out = out, 240 : _out = out,
286 super(out) { 241 super(out);
287 _currentLibrary = unit.element.enclosingElement;
288 final UnitImportResolver r = new UnitImportResolver(
289 unit, _currentLibrary, _extraImports, _newIdentifiers);
290 r.compute();
291 }
292 242
293 void output(String s) => _out.print(s); 243 void output(String s) => _out.print(s);
294 void outputln(String s) => _out.println(s); 244 void outputln(String s) => _out.println(s);
295 245
296 // Choose a canonical prefix for a library that we are adding. 246 // Choose a canonical prefix for a library that we are adding.
297 // Currently just chooses something unlikely to conflict with a user 247 // Currently just chooses something unlikely to conflict with a user
298 // prefix. 248 // prefix.
299 // TODO(leafp): Make this robust. 249 // TODO(leafp): Make this robust.
300 String canonizeLibraryName(String name) { 250 String canonizeLibraryName(String name) {
301 name = name.replaceAll(".", "DOT"); 251 name = name.replaceAll(".", "DOT");
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 @override 333 @override
384 Object visitPrefixedIdentifier(PrefixedIdentifier id) { 334 Object visitPrefixedIdentifier(PrefixedIdentifier id) {
385 safelyVisitNode(id.prefix); 335 safelyVisitNode(id.prefix);
386 output('.'); 336 output('.');
387 output(id.identifier.token.lexeme); 337 output(id.identifier.token.lexeme);
388 return null; 338 return null;
389 } 339 }
390 340
391 @override 341 @override
392 Object visitSimpleIdentifier(SimpleIdentifier id) { 342 Object visitSimpleIdentifier(SimpleIdentifier id) {
393 var element = id.bestElement; 343 if (!(_qualifyNames
394 if (!(_qualifyNames && 344 && _newIdentifiers.containsKey(id)
395 _identifierNeedsQualification(id, _currentLibrary, _newIdentifiers))) { 345 && _identifierNeedsQualification(id, _newIdentifiers[id]))) {
396 return super.visitSimpleIdentifier(id); 346 return super.visitSimpleIdentifier(id);
397 } 347 }
398 if (!utils.isDartPrivateLibrary(element.library)) { 348 var library = _newIdentifiers[id].importedFrom;
399 var lib = utils.canonicalLibraryName(element.library); 349 if (!utils.isDartPrivateLibrary(library)) {
350 var lib = utils.canonicalLibraryName(library);
400 var libname = canonizeLibraryName(lib); 351 var libname = canonizeLibraryName(lib);
401 output(libname); 352 output(libname);
402 output('.'); 353 output('.');
403 } 354 }
404 output(id.name); 355 output(id.name);
405 return null; 356 return null;
406 } 357 }
407 358
408 void generate() { 359 void generate() {
409 visitCompilationUnit(unit); 360 visitCompilationUnit(unit);
410 } 361 }
411 } 362 }
412 363
413 class DartGenerator extends codegenerator.CodeGenerator { 364 class DartGenerator extends codegenerator.CodeGenerator {
414 final CompilerOptions options; 365 final CompilerOptions options;
415 reifier.VariableManager _vm;
416 Set<LibraryElement> _extraImports;
417 TypeRules _rules; 366 TypeRules _rules;
418 367
419 DartGenerator(String outDir, Uri root, TypeRules rules, this.options) 368 DartGenerator(String outDir, Uri root, TypeRules rules, this.options)
420 : _rules = rules, 369 : _rules = rules,
421 super(outDir, root, rules); 370 super(outDir, root, rules);
422 371
423 void generateUnit(CompilationUnit unit, LibraryInfo info, String libraryDir) { 372 Set<LibraryElement> computeExtraImports(Map<Identifier, NewTypeIdDesc> ids) {
Leaf 2015/04/07 22:29:58 This seemed kind of pointless as a separate functi
Jennifer Messerly 2015/04/08 20:28:16 +1, looks nice
424 var uri = unit.element.source.uri; 373 var imports = new Set<LibraryElement>();
425 _log.fine("Generating unit " + uri.toString()); 374 void process(Identifier id, NewTypeIdDesc desc) {
426 FileWriter out = new FileWriter( 375 if (_identifierNeedsQualification(id, desc)) {
427 options, path.join(libraryDir, '${uri.pathSegments.last}')); 376 var library = desc.importedFrom;
428 var tm = new reifier.TypeManager(_vm); 377 if (utils.isDartPrivateLibrary(library)) {
429 var r = new reifier.UnitCoercionReifier(tm, _vm, _rules); 378 _log.severe(
430 r.reify(unit); 379 "Dropping import of private library ${library}\n");
431 var ids = new Set<Identifier>.from(tm.addedTypes.map((tn) => tn.name)); 380 return;
432 var unitGen = new UnitGenerator(unit, out, outDir, _extraImports, ids); 381 }
433 unitGen.generate(); 382 imports.add(library);
434 out.finalize(); 383 }
384 }
385 ids.forEach(process);
386 return imports;
435 } 387 }
436 388
437 String generateLibrary(LibraryUnit library, LibraryInfo info) { 389 String generateLibrary(LibraryUnit library, LibraryInfo info) {
438 _vm = new reifier.VariableManager(); 390 var r = new CoercionReifier(library, rules);
439 _extraImports = new Set<LibraryElement>(); 391 var ids = r.reify();
392 var extraImports = computeExtraImports(ids);
440 393
441 for (var unit in library.partsThenLibrary) { 394 for (var unit in library.partsThenLibrary) {
442 var outputDir = makeOutputDirectory(info, unit); 395 var libraryDir = makeOutputDirectory(info, unit);
443 generateUnit(unit, info, outputDir); 396 var uri = unit.element.source.uri;
397 _log.fine("Generating unit " + uri.toString());
Jennifer Messerly 2015/04/08 20:28:16 "Generating unit $uri" ?
398 FileWriter out = new FileWriter(
399 options, path.join(libraryDir, '${uri.pathSegments.last}'));
400 var unitGen = new UnitGenerator(unit, out, outDir, extraImports, ids);
401 unitGen.generate();
402 out.finalize();
444 } 403 }
445 404
446 _extraImports = null;
447 _vm = null;
448 return null; 405 return null;
449 } 406 }
450 } 407 }
451 408
452 class EmptyUnitGenerator extends UnitGeneratorCommon { 409 class EmptyUnitGenerator extends UnitGeneratorCommon {
453 final java_core.PrintWriter _out; 410 final java_core.PrintWriter _out;
454 CompilationUnit unit; 411 CompilationUnit unit;
455 412
456 EmptyUnitGenerator(this.unit, java_core.PrintWriter out) 413 EmptyUnitGenerator(this.unit, java_core.PrintWriter out)
457 : _out = out, 414 : _out = out,
(...skipping 25 matching lines...) Expand all
483 void generateUnit(CompilationUnit unit, LibraryInfo info, String libraryDir) { 440 void generateUnit(CompilationUnit unit, LibraryInfo info, String libraryDir) {
484 var uri = unit.element.source.uri; 441 var uri = unit.element.source.uri;
485 _log.fine("Emitting original unit " + uri.toString()); 442 _log.fine("Emitting original unit " + uri.toString());
486 FileWriter out = new FileWriter( 443 FileWriter out = new FileWriter(
487 options, path.join(libraryDir, '${uri.pathSegments.last}')); 444 options, path.join(libraryDir, '${uri.pathSegments.last}'));
488 var unitGen = new EmptyUnitGenerator(unit, out); 445 var unitGen = new EmptyUnitGenerator(unit, out);
489 unitGen.generate(); 446 unitGen.generate();
490 out.finalize(); 447 out.finalize();
491 } 448 }
492 } 449 }
OLDNEW
« no previous file with comments | « no previous file | lib/src/codegen/reify_coercions.dart » ('j') | lib/src/codegen/reify_coercions.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698