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

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

Issue 1145243013: Check for duplicate library names (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Address comments Created 5 years, 6 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
« no previous file with comments | « lib/src/codegen/html_codegen.dart ('k') | lib/src/dependency_graph.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.js_codegen; 5 library dev_compiler.src.codegen.js_codegen;
6 6
7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; 7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet;
8 8
9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 const DSETINDEX = 'dsetindex'; 48 const DSETINDEX = 'dsetindex';
49 const DCALL = 'dcall'; 49 const DCALL = 'dcall';
50 const DSEND = 'dsend'; 50 const DSEND = 'dsend';
51 51
52 class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor { 52 class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
53 final AbstractCompiler compiler; 53 final AbstractCompiler compiler;
54 final CompilerOptions options; 54 final CompilerOptions options;
55 final TypeRules rules; 55 final TypeRules rules;
56 final LibraryInfo libraryInfo; 56 final LibraryInfo libraryInfo;
57 57
58 /// Entry point uri
59 final Uri root;
60
58 /// The global extension type table. 61 /// The global extension type table.
59 final HashSet<ClassElement> _extensionTypes; 62 final HashSet<ClassElement> _extensionTypes;
60 63
61 /// Information that is precomputed for this library, indicates which fields 64 /// Information that is precomputed for this library, indicates which fields
62 /// need storage slots. 65 /// need storage slots.
63 final HashSet<FieldElement> _fieldsNeedingStorage; 66 final HashSet<FieldElement> _fieldsNeedingStorage;
64 67
65 /// The variable for the target of the current `..` cascade expression. 68 /// The variable for the target of the current `..` cascade expression.
66 SimpleIdentifier _cascadeTarget; 69 SimpleIdentifier _cascadeTarget;
67 70
(...skipping 17 matching lines...) Expand all
85 final _namedArgTemp = new JS.TemporaryId('opts'); 88 final _namedArgTemp = new JS.TemporaryId('opts');
86 89
87 ConstFieldVisitor _constField; 90 ConstFieldVisitor _constField;
88 91
89 ModuleItemLoadOrder _loader; 92 ModuleItemLoadOrder _loader;
90 93
91 JSCodegenVisitor(AbstractCompiler compiler, this.libraryInfo, 94 JSCodegenVisitor(AbstractCompiler compiler, this.libraryInfo,
92 this._extensionTypes, this._fieldsNeedingStorage) 95 this._extensionTypes, this._fieldsNeedingStorage)
93 : compiler = compiler, 96 : compiler = compiler,
94 options = compiler.options, 97 options = compiler.options,
95 rules = compiler.rules { 98 rules = compiler.rules,
99 root = compiler.entryPointUri {
96 _loader = new ModuleItemLoadOrder(_emitModuleItem); 100 _loader = new ModuleItemLoadOrder(_emitModuleItem);
97 } 101 }
98 102
99 LibraryElement get currentLibrary => libraryInfo.library; 103 LibraryElement get currentLibrary => libraryInfo.library;
100 TypeProvider get types => rules.provider; 104 TypeProvider get types => rules.provider;
101 105
102 JS.Program emitLibrary(LibraryUnit library) { 106 JS.Program emitLibrary(LibraryUnit library) {
103 String jsDefaultValue = null; 107 String jsDefaultValue = null;
104 108
105 // Modify the AST to make coercions explicit. 109 // Modify the AST to make coercions explicit.
106 new CoercionReifier(library, compiler).reify(); 110 new CoercionReifier(library, compiler).reify();
107 111
108 var unit = library.library; 112 var unit = library.library;
109 if (unit.directives.isNotEmpty) { 113 if (unit.directives.isNotEmpty) {
110 var libraryDir = unit.directives.first; 114 var libraryDir = unit.directives.first;
111 if (libraryDir is LibraryDirective) { 115 if (libraryDir is LibraryDirective) {
112 var jsName = findAnnotation(libraryDir.element, _isJsNameAnnotation); 116 var jsName = findAnnotation(libraryDir.element, _isJsNameAnnotation);
113 jsDefaultValue = getConstantField(jsName, 'name', types.stringType); 117 jsDefaultValue = getConstantField(jsName, 'name', types.stringType);
114 } 118 }
115 } 119 }
116 if (jsDefaultValue == null) jsDefaultValue = '{}';
117 120
118 // TODO(jmesserly): visit scriptTag, directives? 121 // TODO(jmesserly): visit scriptTag, directives?
119 122
120 _loader.collectElements(currentLibrary, library.partsThenLibrary); 123 _loader.collectElements(currentLibrary, library.partsThenLibrary);
121 124
122 for (var unit in library.partsThenLibrary) { 125 for (var unit in library.partsThenLibrary) {
123 _constField = new ConstFieldVisitor(types, unit); 126 _constField = new ConstFieldVisitor(types, unit);
124 127
125 for (var decl in unit.declarations) { 128 for (var decl in unit.declarations) {
126 if (decl is TopLevelVariableDeclaration) { 129 if (decl is TopLevelVariableDeclaration) {
(...skipping 27 matching lines...) Expand all
154 _qualifiedIds.forEach(unqualifyIfNeeded); 157 _qualifiedIds.forEach(unqualifyIfNeeded);
155 _qualifiedGenericIds.forEach(unqualifyIfNeeded); 158 _qualifiedGenericIds.forEach(unqualifyIfNeeded);
156 159
157 if (_exports.isNotEmpty) _moduleItems.add(js.comment('Exports:')); 160 if (_exports.isNotEmpty) _moduleItems.add(js.comment('Exports:'));
158 161
159 // TODO(jmesserly): make these immutable in JS? 162 // TODO(jmesserly): make these immutable in JS?
160 for (var name in _exports) { 163 for (var name in _exports) {
161 _moduleItems.add(js.statement('#.# = #;', [_exportsVar, name, name])); 164 _moduleItems.add(js.statement('#.# = #;', [_exportsVar, name, name]));
162 } 165 }
163 166
164 var name = new JS.Identifier(jsLibraryName(currentLibrary)); 167 var jsPath = js.string(jsOutputBase(currentLibrary, root), "'");
165 168
166 // TODO(jmesserly): it would be great to run the renamer on the body, 169 // TODO(jmesserly): it would be great to run the renamer on the body,
167 // then figure out if we really need each of these parameters. 170 // then figure out if we really need each of these parameters.
168 // See ES6 modules: https://github.com/dart-lang/dev_compiler/issues/34 171 // See ES6 modules: https://github.com/dart-lang/dev_compiler/issues/34
172 var params = [_exportsVar];
173 var processImport = (LibraryElement library, JS.TemporaryId temp,
174 List list) {
175 params.add(temp);
176 list.add(js.string(jsOutputBase(library, root), "'"));
177 };
178
179 var imports = [];
180 _imports.forEach((library, temp) {
181 if (_loader.libraryIsLoaded(library)) {
182 processImport(library, temp, imports);
183 }
184 });
185
186 var lazyImports = [];
187 _imports.forEach((library, temp) {
188 if (!_loader.libraryIsLoaded(library)) {
189 processImport(library, temp, lazyImports);
190 }
191 });
192
193 var module =
194 js.call("function(#) { 'use strict'; #; }", [params, _moduleItems]);
195
169 var program = [ 196 var program = [
170 js.statement('var # = dart.defineLibrary(#, #);', [ 197 js.statement("dart.library(#, #, #, #, #)", [
171 name, 198 jsPath,
172 name, 199 jsDefaultValue != null ? jsDefaultValue : new JS.LiteralNull(),
173 js.call(jsDefaultValue) 200 js.commentExpression(
201 "Imports", new JS.ArrayInitializer(imports, multiline: true)),
202 js.commentExpression("Lazy imports",
203 new JS.ArrayInitializer(lazyImports, multiline: true)),
204 module
174 ]) 205 ])
175 ]; 206 ];
176 207
177 var params = [_exportsVar];
178 var args = [name];
179 _imports.forEach((library, temp) {
180 var name = new JS.Identifier(temp.name);
181 params.add(temp);
182 args.add(name);
183 var helper = _loader.libraryIsLoaded(library) ? 'import' : 'lazyImport';
184 program.add(js.statement('var # = dart.#(#);', [name, helper, name]));
185 });
186
187 program.add(js.statement("(function(#) { 'use strict'; #; })(#);", [
188 params,
189 _moduleItems,
190 args
191 ]));
192
193 return new JS.Program(program); 208 return new JS.Program(program);
194 } 209 }
195 210
196 void _emitModuleItem(AstNode node) { 211 void _emitModuleItem(AstNode node) {
197 // Attempt to group adjacent fields/properties. 212 // Attempt to group adjacent fields/properties.
198 if (node is! VariableDeclaration) _flushLazyFields(_moduleItems); 213 if (node is! VariableDeclaration) _flushLazyFields(_moduleItems);
199 if (node is! FunctionDeclaration) _flushLibraryProperties(_moduleItems); 214 if (node is! FunctionDeclaration) _flushLibraryProperties(_moduleItems);
200 215
201 var code = _visit(node); 216 var code = _visit(node);
202 if (code != null) _moduleItems.add(code); 217 if (code != null) _moduleItems.add(code);
(...skipping 2463 matching lines...) Expand 10 before | Expand all | Expand 10 after
2666 t = fillDynamicTypeArgs(t, rules.provider); 2681 t = fillDynamicTypeArgs(t, rules.provider);
2667 t.interfaces.forEach(_addExtensionType); 2682 t.interfaces.forEach(_addExtensionType);
2668 t.mixins.forEach(_addExtensionType); 2683 t.mixins.forEach(_addExtensionType);
2669 _addExtensionType(t.superclass); 2684 _addExtensionType(t.superclass);
2670 } 2685 }
2671 2686
2672 String generateLibrary(LibraryUnit unit, LibraryInfo info) { 2687 String generateLibrary(LibraryUnit unit, LibraryInfo info) {
2673 var fields = findFieldsNeedingStorage(unit); 2688 var fields = findFieldsNeedingStorage(unit);
2674 var codegen = new JSCodegenVisitor(compiler, info, _extensionTypes, fields); 2689 var codegen = new JSCodegenVisitor(compiler, info, _extensionTypes, fields);
2675 var module = codegen.emitLibrary(unit); 2690 var module = codegen.emitLibrary(unit);
2676 var dir = path.join(outDir, jsOutputPath(info, root)); 2691 var dir = path.join(outDir, jsOutputPath(info.library, root));
2677 return writeJsLibrary(module, dir, emitSourceMaps: options.emitSourceMaps); 2692 return writeJsLibrary(module, dir, emitSourceMaps: options.emitSourceMaps);
2678 } 2693 }
2679 } 2694 }
2680 2695
2681 /// Choose a canonical name from the library element. 2696 /// Choose a canonical name from the library element.
2682 /// This never uses the library's name (the identifier in the `library` 2697 /// This never uses the library's name (the identifier in the `library`
2683 /// declaration) as it doesn't have any meaningful rules enforced. 2698 /// declaration) as it doesn't have any meaningful rules enforced.
2684 String jsLibraryName(LibraryElement library) => canonicalLibraryName(library); 2699 String jsLibraryName(LibraryElement library) => canonicalLibraryName(library);
2685 2700
2686 /// Shorthand for identifier-like property names. 2701 /// Shorthand for identifier-like property names.
2687 /// For now, we emit them as strings and the printer restores them to 2702 /// For now, we emit them as strings and the printer restores them to
2688 /// identifiers if it can. 2703 /// identifiers if it can.
2689 // TODO(jmesserly): avoid the round tripping through quoted form. 2704 // TODO(jmesserly): avoid the round tripping through quoted form.
2690 JS.LiteralString _propertyName(String name) => js.string(name, "'"); 2705 JS.LiteralString _propertyName(String name) => js.string(name, "'");
2691 2706
2692 /// Path to file that will be generated for [info]. In case it's url is a 2707 /// Path to file that will be generated for [info]. In case it's url is a
2693 /// `file:` url, we use [root] to determine the relative path from the entry 2708 /// `file:` url, we use [root] to determine the relative path from the entry
2694 /// point file. 2709 /// point file.
2695 String jsOutputPath(LibraryInfo info, Uri root) { 2710 String jsOutputPath(LibraryElement library, Uri root) {
2696 var uri = info.library.source.uri; 2711 return '${jsOutputBase(library, root)}.js';
2697 var filepath = '${path.withoutExtension(uri.path)}.js'; 2712 }
2713
2714 String jsOutputBase(LibraryElement library, Uri root) {
2715 var uri = library.source.uri;
2716 var filepath = path.withoutExtension(uri.path);
2698 if (uri.scheme == 'dart') { 2717 if (uri.scheme == 'dart') {
2699 filepath = 'dart/$filepath'; 2718 filepath = 'dart/$filepath';
2700 } else if (uri.scheme == 'file') { 2719 } else if (uri.scheme == 'file') {
2701 filepath = path.relative(filepath, from: path.dirname(root.path)); 2720 filepath = path.relative(filepath, from: path.dirname(root.path));
2702 } else { 2721 } else {
2703 assert(uri.scheme == 'package'); 2722 assert(uri.scheme == 'package');
2704 // filepath is good here, we want the output to start with a directory 2723 // filepath is good here, we want the output to start with a directory
2705 // matching the package name. 2724 // matching the package name.
2706 } 2725 }
2707 return filepath; 2726 return filepath;
(...skipping 12 matching lines...) Expand all
2720 2739
2721 /// A special kind of element created by the compiler, signifying a temporary 2740 /// A special kind of element created by the compiler, signifying a temporary
2722 /// variable. These objects use instance equality, and should be shared 2741 /// variable. These objects use instance equality, and should be shared
2723 /// everywhere in the tree where they are treated as the same variable. 2742 /// everywhere in the tree where they are treated as the same variable.
2724 class TemporaryVariableElement extends LocalVariableElementImpl { 2743 class TemporaryVariableElement extends LocalVariableElementImpl {
2725 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); 2744 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name);
2726 2745
2727 int get hashCode => identityHashCode(this); 2746 int get hashCode => identityHashCode(this);
2728 bool operator ==(Object other) => identical(this, other); 2747 bool operator ==(Object other) => identical(this, other);
2729 } 2748 }
OLDNEW
« no previous file with comments | « lib/src/codegen/html_codegen.dart ('k') | lib/src/dependency_graph.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698