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.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; |
11 import 'package:analyzer/src/generated/constant.dart'; | 11 import 'package:analyzer/src/generated/constant.dart'; |
12 import 'package:analyzer/src/generated/element.dart'; | 12 import 'package:analyzer/src/generated/element.dart'; |
13 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; | 13 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; |
14 import 'package:analyzer/src/generated/scanner.dart' | 14 import 'package:analyzer/src/generated/scanner.dart' |
15 show StringToken, Token, TokenType; | 15 show StringToken, Token, TokenType; |
16 import 'package:analyzer/src/generated/type_system.dart' | 16 import 'package:analyzer/src/generated/type_system.dart' |
17 show StrongTypeSystemImpl; | 17 show StrongTypeSystemImpl; |
18 import 'package:analyzer/src/task/dart.dart' show PublicNamespaceBuilder; | 18 import 'package:analyzer/src/task/dart.dart' show PublicNamespaceBuilder; |
19 | 19 |
20 import 'ast_builder.dart' show AstBuilder; | 20 import 'ast_builder.dart' show AstBuilder; |
21 import 'reify_coercions.dart' show CoercionReifier, Tuple2; | 21 import 'reify_coercions.dart' show CoercionReifier, Tuple2; |
22 | 22 |
23 // TODO(jmesserly): import from its own package | 23 // TODO(jmesserly): import from its own package |
24 import '../js/js_ast.dart' as JS; | 24 import '../js/js_ast.dart' as JS; |
25 import '../js/js_ast.dart' show js; | 25 import '../js/js_ast.dart' show js; |
26 | 26 |
27 import '../closure/closure_annotator.dart' show ClosureAnnotator; | 27 import '../closure/closure_annotator.dart' show ClosureAnnotator; |
28 import '../compiler.dart' show AbstractCompiler; | 28 import '../compiler.dart' show AbstractCompiler, corelibUriOrder; |
29 import '../info.dart'; | 29 import '../info.dart'; |
30 import '../options.dart' show CodegenOptions; | 30 import '../options.dart' show CodegenOptions; |
31 import '../utils.dart'; | 31 import '../utils.dart'; |
32 | 32 |
33 import 'code_generator.dart'; | 33 import 'code_generator.dart'; |
34 import 'js_field_storage.dart'; | 34 import 'js_field_storage.dart'; |
35 import 'js_interop.dart'; | 35 import 'js_interop.dart'; |
36 import 'js_names.dart' as JS; | 36 import 'js_names.dart' as JS; |
37 import 'js_metalet.dart' as JS; | 37 import 'js_metalet.dart' as JS; |
38 import 'js_module_item_order.dart'; | 38 import 'js_module_item_order.dart'; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 Expression _cascadeTarget; | 73 Expression _cascadeTarget; |
74 | 74 |
75 /// The variable for the current catch clause | 75 /// The variable for the current catch clause |
76 SimpleIdentifier _catchParameter; | 76 SimpleIdentifier _catchParameter; |
77 | 77 |
78 /// In an async* function, this represents the stream controller parameter. | 78 /// In an async* function, this represents the stream controller parameter. |
79 JS.TemporaryId _asyncStarController; | 79 JS.TemporaryId _asyncStarController; |
80 | 80 |
81 /// Imported libraries, and the temporaries used to refer to them. | 81 /// Imported libraries, and the temporaries used to refer to them. |
82 final _imports = new Map<LibraryElement, JS.TemporaryId>(); | 82 final _imports = new Map<LibraryElement, JS.TemporaryId>(); |
83 final _exports = new Set<String>(); | 83 final _exports = <String, String>{}; |
84 final _lazyFields = <VariableDeclaration>[]; | 84 final _lazyFields = <VariableDeclaration>[]; |
85 final _properties = <FunctionDeclaration>[]; | 85 final _properties = <FunctionDeclaration>[]; |
86 final _privateNames = new HashMap<String, JS.TemporaryId>(); | 86 final _privateNames = new HashMap<String, JS.TemporaryId>(); |
87 final _moduleItems = <JS.Statement>[]; | 87 final _moduleItems = <JS.Statement>[]; |
88 final _temps = new HashMap<Element, JS.TemporaryId>(); | 88 final _temps = new HashMap<Element, JS.TemporaryId>(); |
89 final _qualifiedIds = new List<Tuple2<Element, JS.MaybeQualifiedId>>(); | 89 final _qualifiedIds = new List<Tuple2<Element, JS.MaybeQualifiedId>>(); |
90 | 90 |
91 /// The name for the library's exports inside itself. | 91 /// The name for the library's exports inside itself. |
92 /// `exports` was chosen as the most similar to ES module patterns. | 92 /// `exports` was chosen as the most similar to ES module patterns. |
93 final _dartxVar = new JS.Identifier('dartx'); | 93 final _dartxVar = new JS.Identifier('dartx'); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 _flushLibraryProperties(_moduleItems); | 172 _flushLibraryProperties(_moduleItems); |
173 | 173 |
174 // Mark all qualified names as qualified or not, depending on if they need | 174 // Mark all qualified names as qualified or not, depending on if they need |
175 // to be loaded lazily or not. | 175 // to be loaded lazily or not. |
176 for (var elementIdPairs in _qualifiedIds) { | 176 for (var elementIdPairs in _qualifiedIds) { |
177 var element = elementIdPairs.e0; | 177 var element = elementIdPairs.e0; |
178 var id = elementIdPairs.e1; | 178 var id = elementIdPairs.e1; |
179 id.setQualified(!_loader.isLoaded(element)); | 179 id.setQualified(!_loader.isLoaded(element)); |
180 } | 180 } |
181 | 181 |
182 var moduleBuilder = new ModuleBuilder( | 182 var moduleBuilder = new ModuleBuilder(options.moduleFormat); |
183 compiler.getModuleName(currentLibrary.source.uri), | |
184 _jsModuleValue, | |
185 _exportsVar, | |
186 options.moduleFormat); | |
187 | |
188 _exports.forEach(moduleBuilder.addExport); | 183 _exports.forEach(moduleBuilder.addExport); |
189 | 184 |
190 var items = <JS.ModuleItem>[]; | 185 var items = <JS.ModuleItem>[]; |
191 if (!_isDartRuntime) { | 186 if (!_isDartRuntime) { |
| 187 if (currentLibrary.source.isInSystemLibrary) { |
| 188 // Force the import order of runtime libs. |
| 189 // TODO(ochafik): Reduce this to a minimum. |
| 190 for (var lib in corelibUriOrder.reversed) { |
| 191 moduleBuilder.addImport(lib.replaceAll(':', '/'), null); |
| 192 } |
| 193 } |
192 moduleBuilder.addImport('dart/_runtime', _runtimeLibVar); | 194 moduleBuilder.addImport('dart/_runtime', _runtimeLibVar); |
193 | 195 |
194 var dartxImport = | 196 var dartxImport = |
195 js.statement("let # = #.dartx;", [_dartxVar, _runtimeLibVar]); | 197 js.statement("let # = #.dartx;", [_dartxVar, _runtimeLibVar]); |
196 items.add(dartxImport); | 198 items.add(dartxImport); |
197 } | 199 } |
198 items.addAll(_moduleItems); | 200 items.addAll(_moduleItems); |
199 | 201 |
200 _imports.forEach((LibraryElement lib, JS.TemporaryId temp) { | 202 _imports.forEach((LibraryElement lib, JS.TemporaryId temp) { |
201 moduleBuilder.addImport(compiler.getModuleName(lib.source.uri), temp, | 203 moduleBuilder.addImport(compiler.getModuleName(lib.source.uri), temp, |
202 isLazy: _isDartRuntime || !_loader.libraryIsLoaded(lib)); | 204 isLazy: _isDartRuntime || !_loader.libraryIsLoaded(lib)); |
203 }); | 205 }); |
204 | 206 |
205 // TODO(jmesserly): scriptTag support. | 207 // TODO(jmesserly): scriptTag support. |
206 // Enable this if we know we're targetting command line environment? | 208 // Enable this if we know we're targetting command line environment? |
207 // It doesn't work in browser. | 209 // It doesn't work in browser. |
208 // var jsBin = compiler.options.runnerOptions.v8Binary; | 210 // var jsBin = compiler.options.runnerOptions.v8Binary; |
209 // String scriptTag = null; | 211 // String scriptTag = null; |
210 // if (library.library.scriptTag != null) scriptTag = '/usr/bin/env $jsBin'; | 212 // if (library.library.scriptTag != null) scriptTag = '/usr/bin/env $jsBin'; |
211 return moduleBuilder.build(items); | 213 return moduleBuilder.build( |
| 214 compiler.getModuleName(currentLibrary.source.uri), |
| 215 _jsModuleValue, |
| 216 _exportsVar, |
| 217 items); |
212 } | 218 } |
213 | 219 |
214 void _emitModuleItem(AstNode node) { | 220 void _emitModuleItem(AstNode node) { |
215 // Attempt to group adjacent fields/properties. | 221 // Attempt to group adjacent fields/properties. |
216 if (node is! VariableDeclaration) _flushLazyFields(_moduleItems); | 222 if (node is! VariableDeclaration) _flushLazyFields(_moduleItems); |
217 if (node is! FunctionDeclaration) _flushLibraryProperties(_moduleItems); | 223 if (node is! FunctionDeclaration) _flushLibraryProperties(_moduleItems); |
218 | 224 |
219 var code = _visit(node); | 225 var code = _visit(node); |
220 if (code != null) _moduleItems.add(code); | 226 if (code != null) _moduleItems.add(code); |
221 } | 227 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 .where((s) => !currentLibNames.containsKey(s)) | 265 .where((s) => !currentLibNames.containsKey(s)) |
260 .map((s) => js.string(s, "'"))); | 266 .map((s) => js.string(s, "'"))); |
261 } | 267 } |
262 if (hide != null) { | 268 if (hide != null) { |
263 hiddenNames.addAll(hide.hiddenNames.map((i) => js.string(i.name, "'"))); | 269 hiddenNames.addAll(hide.hiddenNames.map((i) => js.string(i.name, "'"))); |
264 } | 270 } |
265 args.add(new JS.ArrayInitializer(shownNames)); | 271 args.add(new JS.ArrayInitializer(shownNames)); |
266 args.add(new JS.ArrayInitializer(hiddenNames)); | 272 args.add(new JS.ArrayInitializer(hiddenNames)); |
267 } | 273 } |
268 | 274 |
269 // When we compile _runtime.js, we need to source export_ from _utils.js: | 275 _moduleItems.add(js.statement('dart.export_(#);', [args])); |
270 _moduleItems.add(js.statement('dart.export(#);', [args])); | |
271 } | 276 } |
272 | 277 |
273 JS.Identifier _initSymbol(JS.Identifier id) { | 278 JS.Identifier _initSymbol(JS.Identifier id) { |
274 var s = | 279 var s = |
275 js.statement('const # = $_SYMBOL(#);', [id, js.string(id.name, "'")]); | 280 js.statement('const # = $_SYMBOL(#);', [id, js.string(id.name, "'")]); |
276 _moduleItems.add(s); | 281 _moduleItems.add(s); |
277 return id; | 282 return id; |
278 } | 283 } |
279 | 284 |
280 // TODO(jmesserly): this is a temporary workaround for `Symbol` in core, | 285 // TODO(jmesserly): this is a temporary workaround for `Symbol` in core, |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 return js.statement( | 528 return js.statement( |
524 'dart.defineLazyClass(#, { get #() { #; return #; } });', | 529 'dart.defineLazyClass(#, { get #() { #; return #; } });', |
525 [_exportsVar, _propertyName(name), body, name]); | 530 [_exportsVar, _propertyName(name), body, name]); |
526 } | 531 } |
527 | 532 |
528 if (isPublic(name)) _addExport(name); | 533 if (isPublic(name)) _addExport(name); |
529 | 534 |
530 if (genericDef != null) { | 535 if (genericDef != null) { |
531 var dynType = fillDynamicTypeArgs(type, types); | 536 var dynType = fillDynamicTypeArgs(type, types); |
532 var genericInst = _emitTypeName(dynType, lowerGeneric: true); | 537 var genericInst = _emitTypeName(dynType, lowerGeneric: true); |
533 return js.statement('{ #; let # = #; }', [genericDef, name, genericInst]); | 538 return js |
| 539 .statement('{ #; const # = #; }', [genericDef, name, genericInst]); |
534 } | 540 } |
535 return body; | 541 return body; |
536 } | 542 } |
537 | 543 |
538 JS.Statement _emitGenericClassDef(ParameterizedType type, JS.Statement body) { | 544 JS.Statement _emitGenericClassDef(ParameterizedType type, JS.Statement body) { |
539 var name = type.name; | 545 var name = type.name; |
540 var genericName = '$name\$'; | 546 var genericName = '$name\$'; |
541 var typeParams = _boundTypeParametersOf(type).map((p) => p.name); | 547 var typeParams = _boundTypeParametersOf(type).map((p) => p.name); |
542 if (isPublic(name)) _exports.add(genericName); | 548 if (isPublic(name)) _addExport(genericName); |
543 return js.statement('const # = dart.generic(function(#) { #; return #; });', | 549 return js.statement('const # = dart.generic(function(#) { #; return #; });', |
544 [genericName, typeParams, body, name]); | 550 [genericName, typeParams, body, name]); |
545 } | 551 } |
546 | 552 |
547 final _hasDeferredSupertype = new HashSet<ClassElement>(); | 553 final _hasDeferredSupertype = new HashSet<ClassElement>(); |
548 | 554 |
549 bool _deferIfNeeded(DartType type, ClassElement current) { | 555 bool _deferIfNeeded(DartType type, ClassElement current) { |
550 if (type is ParameterizedType) { | 556 if (type is ParameterizedType) { |
551 var typeArguments = type.typeArguments; | 557 var typeArguments = type.typeArguments; |
552 for (var typeArg in typeArguments) { | 558 for (var typeArg in typeArguments) { |
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1278 | 1284 |
1279 if (node.isGetter || node.isSetter) { | 1285 if (node.isGetter || node.isSetter) { |
1280 // Add these later so we can use getter/setter syntax. | 1286 // Add these later so we can use getter/setter syntax. |
1281 _properties.add(node); | 1287 _properties.add(node); |
1282 return null; | 1288 return null; |
1283 } | 1289 } |
1284 | 1290 |
1285 var body = <JS.Statement>[]; | 1291 var body = <JS.Statement>[]; |
1286 _flushLibraryProperties(body); | 1292 _flushLibraryProperties(body); |
1287 | 1293 |
1288 var name = _getJSExportName(node.element) ?? node.name.name; | 1294 var name = node.name.name; |
1289 | 1295 |
1290 var fn = _visit(node.functionExpression); | 1296 var fn = _visit(node.functionExpression); |
1291 | 1297 |
1292 if (currentLibrary.source.isInSystemLibrary && | 1298 if (currentLibrary.source.isInSystemLibrary && |
1293 _isInlineJSFunction(node.functionExpression)) { | 1299 _isInlineJSFunction(node.functionExpression)) { |
1294 fn = _simplifyPassThroughArrowFunCallBody(fn); | 1300 fn = _simplifyPassThroughArrowFunCallBody(fn); |
1295 } | 1301 } |
1296 | 1302 |
1297 var id = new JS.Identifier(name); | 1303 var id = new JS.Identifier(name); |
1298 body.add(annotate(new JS.FunctionDeclaration(id, fn), node.element)); | 1304 body.add(annotate(new JS.FunctionDeclaration(id, fn), node.element)); |
1299 if (!_isDartRuntime) { | 1305 if (!_isDartRuntime) { |
1300 body.add(_emitFunctionTagged(id, node.element.type, topLevel: true) | 1306 body.add(_emitFunctionTagged(id, node.element.type, topLevel: true) |
1301 .toStatement()); | 1307 .toStatement()); |
1302 } | 1308 } |
1303 | 1309 |
1304 if (isPublic(name)) _addExport(name); | 1310 if (isPublic(name)) { |
| 1311 _addExport(name, _getJSExportName(node.element) ?? name); |
| 1312 } |
1305 return _statement(body); | 1313 return _statement(body); |
1306 } | 1314 } |
1307 | 1315 |
1308 bool _isInlineJSFunction(FunctionExpression functionExpression) { | 1316 bool _isInlineJSFunction(FunctionExpression functionExpression) { |
1309 var body = functionExpression.body; | 1317 var body = functionExpression.body; |
1310 if (body is ExpressionFunctionBody) { | 1318 if (body is ExpressionFunctionBody) { |
1311 return _isJSInvocation(body.expression); | 1319 return _isJSInvocation(body.expression); |
1312 } else if (body is BlockFunctionBody) { | 1320 } else if (body is BlockFunctionBody) { |
1313 if (body.block.statements.length == 1) { | 1321 if (body.block.statements.length == 1) { |
1314 var stat = body.block.statements.single; | 1322 var stat = body.block.statements.single; |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1728 var genericName = _emitTopLevelName(element, suffix: '\$'); | 1736 var genericName = _emitTopLevelName(element, suffix: '\$'); |
1729 return js.call('#(#)', [genericName, jsArgs]); | 1737 return js.call('#(#)', [genericName, jsArgs]); |
1730 } | 1738 } |
1731 } | 1739 } |
1732 | 1740 |
1733 return _emitTopLevelName(element); | 1741 return _emitTopLevelName(element); |
1734 } | 1742 } |
1735 | 1743 |
1736 JS.Expression _emitTopLevelName(Element e, {String suffix: ''}) { | 1744 JS.Expression _emitTopLevelName(Element e, {String suffix: ''}) { |
1737 var libName = _libraryName(e.library); | 1745 var libName = _libraryName(e.library); |
1738 var nameExpr = _propertyName((_getJSExportName(e) ?? e.name) + suffix); | |
1739 | 1746 |
1740 // Always qualify: | 1747 // Always qualify: |
1741 // * mutable top-level fields | 1748 // * mutable top-level fields |
1742 // * elements from other libraries | 1749 // * elements from other libraries |
1743 bool mutableTopLevel = e is TopLevelVariableElement && | 1750 bool mutableTopLevel = e is TopLevelVariableElement && |
1744 !e.isConst && | 1751 !e.isConst && |
1745 !_isFinalJSDecl(e.computeNode()); | 1752 !_isFinalJSDecl(e.computeNode()); |
1746 bool fromAnotherLibrary = e.library != currentLibrary; | 1753 bool fromAnotherLibrary = e.library != currentLibrary; |
| 1754 var nameExpr; |
| 1755 if (fromAnotherLibrary) { |
| 1756 nameExpr = _propertyName((_getJSExportName(e) ?? e.name) + suffix); |
| 1757 } else { |
| 1758 nameExpr = _propertyName(e.name + suffix); |
| 1759 } |
1747 if (mutableTopLevel || fromAnotherLibrary) { | 1760 if (mutableTopLevel || fromAnotherLibrary) { |
1748 return new JS.PropertyAccess(libName, nameExpr); | 1761 return new JS.PropertyAccess(libName, nameExpr); |
1749 } | 1762 } |
1750 | 1763 |
1751 var id = new JS.MaybeQualifiedId(libName, nameExpr); | 1764 var id = new JS.MaybeQualifiedId(libName, nameExpr); |
1752 _qualifiedIds.add(new Tuple2(e, id)); | 1765 _qualifiedIds.add(new Tuple2(e, id)); |
1753 return id; | 1766 return id; |
1754 } | 1767 } |
1755 | 1768 |
1756 @override | 1769 @override |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2129 /// [visitTopLevelVariableDeclaration]. | 2142 /// [visitTopLevelVariableDeclaration]. |
2130 @override | 2143 @override |
2131 visitFieldDeclaration(FieldDeclaration node) { | 2144 visitFieldDeclaration(FieldDeclaration node) { |
2132 if (!node.isStatic) return; | 2145 if (!node.isStatic) return; |
2133 | 2146 |
2134 for (var f in node.fields.variables) { | 2147 for (var f in node.fields.variables) { |
2135 _loader.loadDeclaration(f, f.element); | 2148 _loader.loadDeclaration(f, f.element); |
2136 } | 2149 } |
2137 } | 2150 } |
2138 | 2151 |
2139 _addExport(String name) { | 2152 _addExport(String name, [String exportName]) { |
2140 if (!_exports.add(name)) throw 'Duplicate top level name found: $name'; | 2153 if (_exports.containsKey(name)) |
| 2154 throw 'Duplicate top level name found: $name'; |
| 2155 _exports[name] = exportName ?? name; |
2141 } | 2156 } |
2142 | 2157 |
2143 @override | 2158 @override |
2144 JS.Statement visitVariableDeclarationStatement( | 2159 JS.Statement visitVariableDeclarationStatement( |
2145 VariableDeclarationStatement node) { | 2160 VariableDeclarationStatement node) { |
2146 // Special case a single variable with an initializer. | 2161 // Special case a single variable with an initializer. |
2147 // This helps emit cleaner code for things like: | 2162 // This helps emit cleaner code for things like: |
2148 // var result = []..add(1)..add(2); | 2163 // var result = []..add(1)..add(2); |
2149 if (node.variables.variables.length == 1) { | 2164 if (node.variables.variables.length == 1) { |
2150 var v = node.variables.variables.single; | 2165 var v = node.variables.variables.single; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2192 jsInit = _visitInitializer(field); | 2207 jsInit = _visitInitializer(field); |
2193 eagerInit = false; | 2208 eagerInit = false; |
2194 } | 2209 } |
2195 | 2210 |
2196 // Treat `final x = JS('', '...')` as a const (non-lazy) to help compile | 2211 // Treat `final x = JS('', '...')` as a const (non-lazy) to help compile |
2197 // runtime helpers. | 2212 // runtime helpers. |
2198 var isJSTopLevel = field.isFinal && _isFinalJSDecl(field); | 2213 var isJSTopLevel = field.isFinal && _isFinalJSDecl(field); |
2199 if (isJSTopLevel) eagerInit = true; | 2214 if (isJSTopLevel) eagerInit = true; |
2200 | 2215 |
2201 var fieldName = field.name.name; | 2216 var fieldName = field.name.name; |
| 2217 var exportName = fieldName; |
2202 if (element is TopLevelVariableElement) { | 2218 if (element is TopLevelVariableElement) { |
2203 fieldName = _getJSExportName(element) ?? fieldName; | 2219 exportName = _getJSExportName(element) ?? fieldName; |
2204 } | 2220 } |
2205 if ((field.isConst && eagerInit && element is TopLevelVariableElement) || | 2221 if ((field.isConst && eagerInit && element is TopLevelVariableElement) || |
2206 isJSTopLevel) { | 2222 isJSTopLevel) { |
2207 // constant fields don't change, so we can generate them as `let` | 2223 // constant fields don't change, so we can generate them as `let` |
2208 // but add them to the module's exports. However, make sure we generate | 2224 // but add them to the module's exports. However, make sure we generate |
2209 // anything they depend on first. | 2225 // anything they depend on first. |
2210 | 2226 |
2211 if (isPublic(fieldName)) _addExport(fieldName); | 2227 if (isPublic(fieldName)) _addExport(fieldName, exportName); |
2212 var declKeyword = field.isConst || field.isFinal ? 'const' : 'let'; | 2228 var declKeyword = field.isConst || field.isFinal ? 'const' : 'let'; |
2213 return annotateVariable( | 2229 return annotateVariable( |
2214 js.statement( | 2230 js.statement( |
2215 '$declKeyword # = #;', [new JS.Identifier(fieldName), jsInit]), | 2231 '$declKeyword # = #;', [new JS.Identifier(fieldName), jsInit]), |
2216 field.element); | 2232 field.element); |
2217 } | 2233 } |
2218 | 2234 |
2219 if (eagerInit && !JS.invalidStaticFieldName(fieldName)) { | 2235 if (eagerInit && !JS.invalidStaticFieldName(fieldName)) { |
2220 return annotateVariable( | 2236 return annotateVariable( |
2221 js.statement('# = #;', [_visit(field.name), jsInit]), field.element); | 2237 js.statement('# = #;', [_visit(field.name), jsInit]), field.element); |
(...skipping 1370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3592 | 3608 |
3593 /// A special kind of element created by the compiler, signifying a temporary | 3609 /// A special kind of element created by the compiler, signifying a temporary |
3594 /// variable. These objects use instance equality, and should be shared | 3610 /// variable. These objects use instance equality, and should be shared |
3595 /// everywhere in the tree where they are treated as the same variable. | 3611 /// everywhere in the tree where they are treated as the same variable. |
3596 class TemporaryVariableElement extends LocalVariableElementImpl { | 3612 class TemporaryVariableElement extends LocalVariableElementImpl { |
3597 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); | 3613 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); |
3598 | 3614 |
3599 int get hashCode => identityHashCode(this); | 3615 int get hashCode => identityHashCode(this); |
3600 bool operator ==(Object other) => identical(this, other); | 3616 bool operator ==(Object other) => identical(this, other); |
3601 } | 3617 } |
OLD | NEW |