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; |
(...skipping 21 matching lines...) Expand all Loading... | |
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'; |
39 import 'js_names.dart'; | 39 import 'js_names.dart'; |
40 import 'js_printer.dart' show writeJsLibrary; | 40 import 'js_printer.dart' show writeJsLibrary; |
41 import 'side_effect_analysis.dart'; | 41 import 'side_effect_analysis.dart'; |
42 import 'package:collection/equality.dart'; | |
43 | 42 |
44 // Various dynamic helpers we call. | 43 // Various dynamic helpers we call. |
45 // If renaming these, make sure to check other places like the | 44 // If renaming these, make sure to check other places like the |
46 // _runtime.js file and comments. | 45 // _runtime.js file and comments. |
47 // TODO(jmesserly): ideally we'd have a "dynamic call" dart library we can | 46 // TODO(jmesserly): ideally we'd have a "dynamic call" dart library we can |
48 // import and generate calls to, rather than dart_runtime.js | 47 // import and generate calls to, rather than dart_runtime.js |
49 const DPUT = 'dput'; | 48 const DPUT = 'dput'; |
50 const DLOAD = 'dload'; | 49 const DLOAD = 'dload'; |
51 const DINDEX = 'dindex'; | 50 const DINDEX = 'dindex'; |
52 const DSETINDEX = 'dsetindex'; | 51 const DSETINDEX = 'dsetindex'; |
53 const DCALL = 'dcall'; | 52 const DCALL = 'dcall'; |
54 const DSEND = 'dsend'; | 53 const DSEND = 'dsend'; |
55 | 54 |
56 const ListEquality _listEquality = const ListEquality(); | |
57 | |
58 class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { | 55 class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
59 final AbstractCompiler compiler; | 56 final AbstractCompiler compiler; |
60 final CodegenOptions options; | 57 final CodegenOptions options; |
61 final LibraryElement currentLibrary; | 58 final LibraryElement currentLibrary; |
62 final StrongTypeSystemImpl rules; | 59 final StrongTypeSystemImpl rules; |
63 | 60 |
64 /// The global extension type table. | 61 /// The global extension type table. |
65 final HashSet<ClassElement> _extensionTypes; | 62 final HashSet<ClassElement> _extensionTypes; |
66 | 63 |
67 /// Information that is precomputed for this library, indicates which fields | 64 /// Information that is precomputed for this library, indicates which fields |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 ConstFieldVisitor _constField; | 99 ConstFieldVisitor _constField; |
103 | 100 |
104 ModuleItemLoadOrder _loader; | 101 ModuleItemLoadOrder _loader; |
105 | 102 |
106 /// _interceptors.JSArray<E>, used for List literals. | 103 /// _interceptors.JSArray<E>, used for List literals. |
107 ClassElement _jsArray; | 104 ClassElement _jsArray; |
108 | 105 |
109 /// The default value of the module object. See [visitLibraryDirective]. | 106 /// The default value of the module object. See [visitLibraryDirective]. |
110 String _jsModuleValue; | 107 String _jsModuleValue; |
111 | 108 |
112 bool _isDartUtils; | 109 bool _isDartRuntime; |
113 | 110 |
114 JSCodegenVisitor(AbstractCompiler compiler, this.rules, this.currentLibrary, | 111 JSCodegenVisitor(AbstractCompiler compiler, this.rules, this.currentLibrary, |
115 this._extensionTypes, this._fieldsNeedingStorage) | 112 this._extensionTypes, this._fieldsNeedingStorage) |
116 : compiler = compiler, | 113 : compiler = compiler, |
117 options = compiler.options.codegenOptions, | 114 options = compiler.options.codegenOptions, |
118 _types = compiler.context.typeProvider { | 115 _types = compiler.context.typeProvider { |
119 _loader = new ModuleItemLoadOrder(_emitModuleItem); | 116 _loader = new ModuleItemLoadOrder(_emitModuleItem); |
120 | 117 |
121 var context = compiler.context; | 118 var context = compiler.context; |
122 var src = context.sourceFactory.forUri('dart:_interceptors'); | 119 var src = context.sourceFactory.forUri('dart:_interceptors'); |
123 var interceptors = context.computeLibraryElement(src); | 120 var interceptors = context.computeLibraryElement(src); |
124 _jsArray = interceptors.getType('JSArray'); | 121 _jsArray = interceptors.getType('JSArray'); |
125 _isDartUtils = currentLibrary.source.uri.toString() == 'dart:_utils'; | 122 _isDartRuntime = currentLibrary.source.uri.toString() == 'dart:_runtime'; |
126 } | 123 } |
127 | 124 |
128 TypeProvider get types => _types; | 125 TypeProvider get types => _types; |
129 | 126 |
130 JS.Program emitLibrary(LibraryUnit library) { | 127 JS.Program emitLibrary(LibraryUnit library) { |
131 // Modify the AST to make coercions explicit. | 128 // Modify the AST to make coercions explicit. |
132 new CoercionReifier(library, rules).reify(); | 129 new CoercionReifier(library, rules).reify(); |
133 | 130 |
134 // Build the public namespace for this library. This allows us to do | 131 // Build the public namespace for this library. This allows us to do |
135 // constant time lookups (contrast with `Element.getChild(name)`). | 132 // constant time lookups (contrast with `Element.getChild(name)`). |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 // TODO(jmesserly): make these immutable in JS? | 183 // TODO(jmesserly): make these immutable in JS? |
187 for (var name in _exports) { | 184 for (var name in _exports) { |
188 _moduleItems.add(js.statement('#.# = #;', [_exportsVar, name, name])); | 185 _moduleItems.add(js.statement('#.# = #;', [_exportsVar, name, name])); |
189 } | 186 } |
190 | 187 |
191 var jsPath = compiler.getModuleName(currentLibrary.source.uri); | 188 var jsPath = compiler.getModuleName(currentLibrary.source.uri); |
192 | 189 |
193 // TODO(jmesserly): it would be great to run the renamer on the body, | 190 // TODO(jmesserly): it would be great to run the renamer on the body, |
194 // then figure out if we really need each of these parameters. | 191 // then figure out if we really need each of these parameters. |
195 // See ES6 modules: https://github.com/dart-lang/dev_compiler/issues/34 | 192 // See ES6 modules: https://github.com/dart-lang/dev_compiler/issues/34 |
196 var params = [_exportsVar, _runtimeLibVar]; | 193 var params = [_exportsVar]; |
197 var processImport = | 194 var lazyParams = []; |
198 (LibraryElement library, JS.TemporaryId temp, List list) { | |
199 params.add(temp); | |
200 list.add(js.string(compiler.getModuleName(library.source.uri), "'")); | |
201 }; | |
202 | |
203 var needsDartRuntime = !_isDartUtils; | |
204 | 195 |
205 var imports = <JS.Expression>[]; | 196 var imports = <JS.Expression>[]; |
197 var lazyImports = <JS.Expression>[]; | |
206 var moduleStatements = <JS.Statement>[]; | 198 var moduleStatements = <JS.Statement>[]; |
207 if (needsDartRuntime) { | 199 |
208 imports.add(js.string('dart/_runtime')); | 200 addImport(String name, JS.Expression libVar, {bool lazy: false}) { |
201 (lazy ? lazyImports : imports).add(js.string(name, "'")); | |
202 (lazy ? lazyParams : params).add(libVar); | |
203 } | |
204 | |
205 if (!_isDartRuntime) { | |
206 addImport('dart/_runtime', _runtimeLibVar); | |
209 | 207 |
210 var dartxImport = | 208 var dartxImport = |
211 js.statement("let # = #.dartx;", [_dartxVar, _runtimeLibVar]); | 209 js.statement("let # = #.dartx;", [_dartxVar, _runtimeLibVar]); |
212 moduleStatements.add(dartxImport); | 210 moduleStatements.add(dartxImport); |
213 } | 211 } |
212 _imports.forEach((LibraryElement lib, JS.TemporaryId temp) { | |
213 addImport(compiler.getModuleName(lib.source.uri), temp, | |
214 lazy: _isDartRuntime || !_loader.libraryIsLoaded(lib)); | |
215 }); | |
216 params.addAll(lazyParams); | |
217 | |
214 moduleStatements.addAll(_moduleItems); | 218 moduleStatements.addAll(_moduleItems); |
215 | 219 |
216 _imports.forEach((library, temp) { | |
217 if (_loader.libraryIsLoaded(library)) { | |
218 processImport(library, temp, imports); | |
219 } | |
220 }); | |
221 | |
222 var lazyImports = <JS.Expression>[]; | |
223 _imports.forEach((library, temp) { | |
224 if (!_loader.libraryIsLoaded(library)) { | |
225 processImport(library, temp, lazyImports); | |
226 } | |
227 }); | |
228 | 220 |
229 var module = | 221 var module = |
230 js.call("function(#) { 'use strict'; #; }", [params, moduleStatements]); | 222 js.call("function(#) { 'use strict'; #; }", [params, moduleStatements]); |
231 | 223 |
232 var moduleDef = js.statement("dart_library.library(#, #, #, #, #)", [ | 224 var moduleDef = js.statement("dart_library.library(#, #, #, #, #)", [ |
233 js.string(jsPath, "'"), | 225 js.string(jsPath, "'"), |
234 _jsModuleValue ?? new JS.LiteralNull(), | 226 _jsModuleValue ?? new JS.LiteralNull(), |
235 js.commentExpression( | 227 js.commentExpression( |
236 "Imports", new JS.ArrayInitializer(imports, multiline: true)), | 228 "Imports", new JS.ArrayInitializer(imports, multiline: true)), |
237 js.commentExpression("Lazy imports", | 229 js.commentExpression("Lazy imports", |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 .map((i) => i.name) | 287 .map((i) => i.name) |
296 .where((s) => !currentLibNames.containsKey(s)) | 288 .where((s) => !currentLibNames.containsKey(s)) |
297 .map((s) => js.string(s, "'"))); | 289 .map((s) => js.string(s, "'"))); |
298 } | 290 } |
299 if (hide != null) { | 291 if (hide != null) { |
300 hiddenNames.addAll(hide.hiddenNames.map((i) => js.string(i.name, "'"))); | 292 hiddenNames.addAll(hide.hiddenNames.map((i) => js.string(i.name, "'"))); |
301 } | 293 } |
302 args.add(new JS.ArrayInitializer(shownNames)); | 294 args.add(new JS.ArrayInitializer(shownNames)); |
303 args.add(new JS.ArrayInitializer(hiddenNames)); | 295 args.add(new JS.ArrayInitializer(hiddenNames)); |
304 } | 296 } |
305 _moduleItems.add(js.statement('dart.export_(#);', [args])); | 297 |
298 // When we compile _runtime.js, we need to source export_ from _utils.js: | |
299 _moduleItems.add(js.statement('dart.export(#);', [args])); | |
306 } | 300 } |
307 | 301 |
308 JS.Identifier _initSymbol(JS.Identifier id) { | 302 JS.Identifier _initSymbol(JS.Identifier id) { |
309 var s = | 303 var s = |
310 js.statement('const # = $_SYMBOL(#);', [id, js.string(id.name, "'")]); | 304 js.statement('const # = $_SYMBOL(#);', [id, js.string(id.name, "'")]); |
311 _moduleItems.add(s); | 305 _moduleItems.add(s); |
312 return id; | 306 return id; |
313 } | 307 } |
314 | 308 |
315 // TODO(jmesserly): this is a temporary workaround for `Symbol` in core, | 309 // TODO(jmesserly): this is a temporary workaround for `Symbol` in core, |
(...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1291 isGetter: node.isGetter, | 1285 isGetter: node.isGetter, |
1292 isSetter: node.isSetter, | 1286 isSetter: node.isSetter, |
1293 isStatic: node.isStatic), | 1287 isStatic: node.isStatic), |
1294 node.element); | 1288 node.element); |
1295 } | 1289 } |
1296 | 1290 |
1297 /// Returns the name value of the `JSExportName` annotation (when compiling | 1291 /// Returns the name value of the `JSExportName` annotation (when compiling |
1298 /// the SDK), or `null` if there's none. This is used to control the name | 1292 /// the SDK), or `null` if there's none. This is used to control the name |
1299 /// under which functions are compiled and exported. | 1293 /// under which functions are compiled and exported. |
1300 String _getJSExportName(Element e) { | 1294 String _getJSExportName(Element e) { |
1301 if (e is! FunctionElement || !currentLibrary.source.isInSystemLibrary) { | 1295 if (!currentLibrary.source.isInSystemLibrary) { |
1302 return null; | 1296 return null; |
1303 } | 1297 } |
1304 var jsName = findAnnotation(e, isJSExportNameAnnotation); | 1298 var jsName = findAnnotation(e, isJSExportNameAnnotation); |
1305 return getConstantField(jsName, 'name', types.stringType)?.toStringValue(); | 1299 return getConstantField(jsName, 'name', types.stringType)?.toStringValue(); |
1306 } | 1300 } |
1307 | 1301 |
1308 @override | 1302 @override |
1309 JS.Statement visitFunctionDeclaration(FunctionDeclaration node) { | 1303 JS.Statement visitFunctionDeclaration(FunctionDeclaration node) { |
1310 assert(node.parent is CompilationUnit); | 1304 assert(node.parent is CompilationUnit); |
1311 | 1305 |
1312 if (_externalOrNative(node)) return null; | 1306 if (_externalOrNative(node)) return null; |
1313 | 1307 |
1314 if (node.isGetter || node.isSetter) { | 1308 if (node.isGetter || node.isSetter) { |
1315 // Add these later so we can use getter/setter syntax. | 1309 // Add these later so we can use getter/setter syntax. |
1316 _properties.add(node); | 1310 _properties.add(node); |
1317 return null; | 1311 return null; |
1318 } | 1312 } |
1319 | 1313 |
1320 var body = <JS.Statement>[]; | 1314 var body = <JS.Statement>[]; |
1321 _flushLibraryProperties(body); | 1315 _flushLibraryProperties(body); |
1322 | 1316 |
1323 var name = _getJSExportName(node.element) ?? node.name.name; | 1317 var name = _getJSExportName(node.element) ?? node.name.name; |
1324 | 1318 |
1325 var fn = _visit(node.functionExpression); | 1319 var fn = _visit(node.functionExpression); |
1326 bool needsTagging = true; | |
1327 | 1320 |
1328 if (currentLibrary.source.isInSystemLibrary && | 1321 if (currentLibrary.source.isInSystemLibrary && |
1329 _isInlineJSFunction(node.functionExpression)) { | 1322 _isInlineJSFunction(node.functionExpression)) { |
1330 fn = _simplifyPassThroughArrowFunCallBody(fn); | 1323 fn = _simplifyPassThroughArrowFunCallBody(fn); |
1331 needsTagging = !_isDartUtils; | |
1332 } | 1324 } |
1333 | 1325 |
1334 var id = new JS.Identifier(name); | 1326 var id = new JS.Identifier(name); |
1335 body.add(annotate(new JS.FunctionDeclaration(id, fn), node.element)); | 1327 body.add(annotate(new JS.FunctionDeclaration(id, fn), node.element)); |
1336 if (needsTagging) { | 1328 if (!_isDartRuntime) { |
1337 body.add(_emitFunctionTagged(id, node.element.type, topLevel: true) | 1329 body.add(_emitFunctionTagged(id, node.element.type, topLevel: true) |
1338 .toStatement()); | 1330 .toStatement()); |
1339 } | 1331 } |
1340 | 1332 |
1341 if (isPublic(name)) _addExport(name); | 1333 if (isPublic(name)) _addExport(name); |
1342 return _statement(body); | 1334 return _statement(body); |
1343 } | 1335 } |
1344 | 1336 |
1345 bool _isInlineJSFunction(FunctionExpression functionExpression) { | 1337 bool _isInlineJSFunction(FunctionExpression functionExpression) { |
1346 var body = functionExpression.body; | 1338 var body = functionExpression.body; |
1347 if (body is ExpressionFunctionBody) { | 1339 if (body is ExpressionFunctionBody) { |
1348 return _isJSInvocation(body.expression); | 1340 return _isJSInvocation(body.expression); |
1349 } else if (body is BlockFunctionBody) { | 1341 } else if (body is BlockFunctionBody) { |
1350 if (body.block.statements.length == 1) { | 1342 if (body.block.statements.length == 1) { |
1351 var stat = body.block.statements.single; | 1343 var stat = body.block.statements.single; |
1352 if (stat is ReturnStatement) { | 1344 if (stat is ReturnStatement) { |
1353 return _isJSInvocation(stat.expression); | 1345 return _isJSInvocation(stat.expression); |
1354 } | 1346 } |
1355 } | 1347 } |
1356 } | 1348 } |
1357 return false; | 1349 return false; |
1358 } | 1350 } |
1359 | 1351 |
1360 bool _isJSInvocation(Expression expr) => | 1352 bool _isJSInvocation(Expression expr) => |
1361 expr is MethodInvocation && isInlineJS(expr.methodName.staticElement); | 1353 expr is MethodInvocation && isInlineJS(expr.methodName.staticElement); |
1362 | 1354 |
1363 // Simplify `(args) => ((x, y) => { ... })(x, y)` to `(args) => { ... }`. | 1355 // Simplify `(args) => (() => { ... })()` to `(args) => { ... }`. |
1364 // Note: we don't check if the top-level args match the ones passed through | 1356 // Note: this allows silently passing args through to the body, which only |
1365 // the arrow function, which allows silently passing args through to the | 1357 // works if we don't do weird renamings of Dart params. |
1366 // body (which only works if we don't do weird renamings of Dart params). | |
1367 JS.Fun _simplifyPassThroughArrowFunCallBody(JS.Fun fn) { | 1358 JS.Fun _simplifyPassThroughArrowFunCallBody(JS.Fun fn) { |
1368 String getIdent(JS.Node node) => node is JS.Identifier ? node.name : null; | |
1369 List<String> getIdents(List params) => | |
1370 params.map(getIdent).toList(growable: false); | |
1371 | |
1372 if (fn.body is JS.Block && fn.body.statements.length == 1) { | 1359 if (fn.body is JS.Block && fn.body.statements.length == 1) { |
1373 var stat = fn.body.statements.single; | 1360 var stat = fn.body.statements.single; |
1374 if (stat is JS.Return && stat.value is JS.Call) { | 1361 if (stat is JS.Return && stat.value is JS.Call) { |
1375 JS.Call call = stat.value; | 1362 JS.Call call = stat.value; |
1376 if (call.target is JS.ArrowFun) { | 1363 if (call.target is JS.ArrowFun && call.arguments.isEmpty) { |
1377 var passedArgs = getIdents(call.arguments); | |
1378 JS.ArrowFun innerFun = call.target; | 1364 JS.ArrowFun innerFun = call.target; |
1379 if (_listEquality.equals(getIdents(innerFun.params), passedArgs)) { | 1365 if (innerFun.params.isEmpty) { |
1380 return new JS.Fun(fn.params, innerFun.body); | 1366 return new JS.Fun(fn.params, innerFun.body); |
1381 } | 1367 } |
1382 } | 1368 } |
1383 } | 1369 } |
1384 } | 1370 } |
1385 return fn; | 1371 return fn; |
1386 } | 1372 } |
1387 | 1373 |
1388 JS.Method _emitTopLevelProperty(FunctionDeclaration node) { | 1374 JS.Method _emitTopLevelProperty(FunctionDeclaration node) { |
1389 var name = node.name.name; | 1375 var name = node.name.name; |
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1904 var stmts = _visitList(node.block.statements) as List<JS.Statement>; | 1890 var stmts = _visitList(node.block.statements) as List<JS.Statement>; |
1905 if (initArgs != null) stmts.insert(0, initArgs); | 1891 if (initArgs != null) stmts.insert(0, initArgs); |
1906 return new JS.Block(stmts); | 1892 return new JS.Block(stmts); |
1907 } | 1893 } |
1908 | 1894 |
1909 @override | 1895 @override |
1910 JS.Block visitBlock(Block node) => | 1896 JS.Block visitBlock(Block node) => |
1911 new JS.Block(_visitList(node.statements) as List<JS.Statement>, | 1897 new JS.Block(_visitList(node.statements) as List<JS.Statement>, |
1912 isScope: true); | 1898 isScope: true); |
1913 | 1899 |
1900 /// Return the type constructor `_foolib.Bar$` given `Bar` from lib `_foolib`. | |
1901 /// | |
1902 /// This implements / expands the `genericTypeConstructor` intrinsic defined | |
1903 /// in `foreign_helper.dart`: | |
1904 /// `JS('', '#(type)', genericTypeConstructor(List))` will generate | |
1905 /// `core.List$(type)`. | |
1906 JS.Expression _emitGenericTypeConstructor(Expression typeExpression) { | |
Jennifer Messerly
2016/01/20 23:44:58
we chatted about moving this hack into the generat
ochafik
2016/01/21 00:11:35
So actually, JS('', '$Future\$($type)') is just JS
| |
1907 var ref = _visit(typeExpression); | |
1908 if (ref is JS.PropertyAccess) { | |
1909 var name = (ref.selector as JS.LiteralString).valueWithoutQuotes; | |
1910 return new JS.PropertyAccess( | |
1911 ref.receiver, new JS.LiteralString("'$name\$'")); | |
1912 } else if (ref is JS.MaybeQualifiedId) { | |
1913 var name = (ref.name as JS.Identifier).name; | |
1914 return new JS.PropertyAccess(ref.qualifier, new JS.Identifier('$name\$')); | |
1915 } else { | |
1916 throw new ArgumentError('Invalid type ref: $ref (${ref?.runtimeType})'); | |
1917 } | |
1918 } | |
1919 | |
1914 @override | 1920 @override |
1915 visitMethodInvocation(MethodInvocation node) { | 1921 visitMethodInvocation(MethodInvocation node) { |
1916 if (node.operator != null && node.operator.lexeme == '?.') { | 1922 if (node.operator != null && node.operator.lexeme == '?.') { |
1917 return _emitNullSafe(node); | 1923 return _emitNullSafe(node); |
1918 } | 1924 } |
1925 if (isGenericTypeConstructorIntrinsic(node)) { | |
1926 assert(currentLibrary.source.isInSystemLibrary); | |
1927 return _emitGenericTypeConstructor(node.argumentList.arguments.single); | |
1928 } | |
1919 | 1929 |
1920 var target = _getTarget(node); | 1930 var target = _getTarget(node); |
1921 var result = _emitForeignJS(node); | 1931 var result = _emitForeignJS(node); |
1922 if (result != null) return result; | 1932 if (result != null) return result; |
1923 | 1933 |
1924 String code; | 1934 String code; |
1925 if (target == null || isLibraryPrefix(target)) { | 1935 if (target == null || isLibraryPrefix(target)) { |
1926 if (DynamicInvoke.get(node.methodName)) { | 1936 if (DynamicInvoke.get(node.methodName)) { |
1927 code = 'dart.$DCALL(#, #)'; | 1937 code = 'dart.$DCALL(#, #)'; |
1928 } else { | 1938 } else { |
(...skipping 1525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3454 node.externalKeyword != null || _functionBody(node) is NativeFunctionBody; | 3464 node.externalKeyword != null || _functionBody(node) is NativeFunctionBody; |
3455 | 3465 |
3456 FunctionBody _functionBody(node) => | 3466 FunctionBody _functionBody(node) => |
3457 node is FunctionDeclaration ? node.functionExpression.body : node.body; | 3467 node is FunctionDeclaration ? node.functionExpression.body : node.body; |
3458 | 3468 |
3459 /// Choose a canonical name from the library element. | 3469 /// Choose a canonical name from the library element. |
3460 /// This never uses the library's name (the identifier in the `library` | 3470 /// This never uses the library's name (the identifier in the `library` |
3461 /// declaration) as it doesn't have any meaningful rules enforced. | 3471 /// declaration) as it doesn't have any meaningful rules enforced. |
3462 JS.Identifier _libraryName(LibraryElement library) { | 3472 JS.Identifier _libraryName(LibraryElement library) { |
3463 if (library == currentLibrary) return _exportsVar; | 3473 if (library == currentLibrary) return _exportsVar; |
3474 if (library.name == 'dart._runtime') return _runtimeLibVar; | |
3464 return _imports.putIfAbsent( | 3475 return _imports.putIfAbsent( |
3465 library, () => new JS.TemporaryId(jsLibraryName(library))); | 3476 library, () => new JS.TemporaryId(jsLibraryName(library))); |
3466 } | 3477 } |
3467 | 3478 |
3468 DartType getStaticType(Expression e) => | 3479 DartType getStaticType(Expression e) => |
3469 e.staticType ?? DynamicTypeImpl.instance; | 3480 e.staticType ?? DynamicTypeImpl.instance; |
3470 | 3481 |
3471 @override | 3482 @override |
3472 String getQualifiedName(TypeDefiningElement type) { | 3483 String getQualifiedName(TypeDefiningElement type) { |
3473 JS.TemporaryId id = _imports[type.library]; | 3484 JS.TemporaryId id = _imports[type.library]; |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3634 | 3645 |
3635 /// A special kind of element created by the compiler, signifying a temporary | 3646 /// A special kind of element created by the compiler, signifying a temporary |
3636 /// variable. These objects use instance equality, and should be shared | 3647 /// variable. These objects use instance equality, and should be shared |
3637 /// everywhere in the tree where they are treated as the same variable. | 3648 /// everywhere in the tree where they are treated as the same variable. |
3638 class TemporaryVariableElement extends LocalVariableElementImpl { | 3649 class TemporaryVariableElement extends LocalVariableElementImpl { |
3639 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); | 3650 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); |
3640 | 3651 |
3641 int get hashCode => identityHashCode(this); | 3652 int get hashCode => identityHashCode(this); |
3642 bool operator ==(Object other) => identical(this, other); | 3653 bool operator ==(Object other) => identical(this, other); |
3643 } | 3654 } |
OLD | NEW |