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

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

Issue 1724463003: refactor: avoid parts (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 10 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 | « no previous file | lib/src/codegen/js_interop.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 js_codegen;
6
7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; 5 import 'dart:collection' show HashSet, HashMap, SplayTreeSet;
8 6
9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 7 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
10 import 'package:analyzer/dart/ast/token.dart'; 8 import 'package:analyzer/dart/ast/token.dart';
11 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; 9 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
12 import 'package:analyzer/src/generated/constant.dart'; 10 import 'package:analyzer/src/generated/constant.dart';
13 import 'package:analyzer/src/generated/element.dart'; 11 import 'package:analyzer/src/generated/element.dart';
14 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; 12 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
15 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; 13 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
16 import 'package:analyzer/src/dart/ast/token.dart' 14 import 'package:analyzer/src/dart/ast/token.dart'
17 show StringToken, Token, TokenType; 15 show StringToken, Token, TokenType;
18 import 'package:analyzer/src/generated/type_system.dart' 16 import 'package:analyzer/src/generated/type_system.dart'
19 show StrongTypeSystemImpl; 17 show StrongTypeSystemImpl;
20 import 'package:analyzer/src/task/dart.dart' show PublicNamespaceBuilder; 18 import 'package:analyzer/src/task/dart.dart' show PublicNamespaceBuilder;
21 19
22 import 'ast_builder.dart' show AstBuilder; 20 import 'ast_builder.dart' show AstBuilder;
23 import 'reify_coercions.dart' show CoercionReifier, Tuple2; 21 import 'reify_coercions.dart' show CoercionReifier, Tuple2;
24 22
25 // TODO(jmesserly): import from its own package
26 import '../js/js_ast.dart' as JS; 23 import '../js/js_ast.dart' as JS;
27 import '../js/js_ast.dart' show js; 24 import '../js/js_ast.dart' show js;
28 25
29 import '../closure/closure_annotator.dart' show ClosureAnnotator; 26 import '../closure/closure_annotator.dart' show ClosureAnnotator;
30 import '../compiler.dart' 27 import '../compiler.dart'
31 show AbstractCompiler, corelibOrder, getCorelibModuleName; 28 show AbstractCompiler, corelibOrder, getCorelibModuleName;
32 import '../info.dart'; 29 import '../info.dart';
33 import '../options.dart' show CodegenOptions; 30 import '../options.dart' show CodegenOptions;
34 import '../utils.dart'; 31 import '../utils.dart';
35 32
36 import 'code_generator.dart'; 33 import 'code_generator.dart';
37 import 'js_field_storage.dart'; 34 import 'js_field_storage.dart';
38 import 'js_interop.dart'; 35 import 'js_interop.dart';
39 import 'js_names.dart' as JS; 36 import 'js_names.dart' as JS;
40 import 'js_metalet.dart' as JS; 37 import 'js_metalet.dart' as JS;
41 import 'js_module_item_order.dart'; 38 import 'js_module_item_order.dart';
42 import 'js_names.dart'; 39 import 'js_names.dart';
43 import 'js_printer.dart' show writeJsLibrary; 40 import 'js_printer.dart' show writeJsLibrary;
41 import 'js_typeref_codegen.dart';
44 import 'module_builder.dart'; 42 import 'module_builder.dart';
45 import 'nullability_inferrer.dart'; 43 import 'nullability_inferrer.dart';
46 import 'side_effect_analysis.dart'; 44 import 'side_effect_analysis.dart';
47 45
48 part 'js_typeref_codegen.dart';
49
50 // Various dynamic helpers we call. 46 // Various dynamic helpers we call.
51 // If renaming these, make sure to check other places like the 47 // If renaming these, make sure to check other places like the
52 // _runtime.js file and comments. 48 // _runtime.js file and comments.
53 // TODO(jmesserly): ideally we'd have a "dynamic call" dart library we can 49 // TODO(jmesserly): ideally we'd have a "dynamic call" dart library we can
54 // import and generate calls to, rather than dart_runtime.js 50 // import and generate calls to, rather than dart_runtime.js
55 const DPUT = 'dput'; 51 const DPUT = 'dput';
56 const DLOAD = 'dload'; 52 const DLOAD = 'dload';
57 const DINDEX = 'dindex'; 53 const DINDEX = 'dindex';
58 const DSETINDEX = 'dsetindex'; 54 const DSETINDEX = 'dsetindex';
59 const DCALL = 'dcall'; 55 const DCALL = 'dcall';
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 final _privateNames = new HashMap<String, JS.TemporaryId>(); 88 final _privateNames = new HashMap<String, JS.TemporaryId>();
93 final _moduleItems = <JS.Statement>[]; 89 final _moduleItems = <JS.Statement>[];
94 final _temps = new HashMap<Element, JS.TemporaryId>(); 90 final _temps = new HashMap<Element, JS.TemporaryId>();
95 final _qualifiedIds = new List<Tuple2<Element, JS.MaybeQualifiedId>>(); 91 final _qualifiedIds = new List<Tuple2<Element, JS.MaybeQualifiedId>>();
96 92
97 /// The name for the library's exports inside itself. 93 /// The name for the library's exports inside itself.
98 /// `exports` was chosen as the most similar to ES module patterns. 94 /// `exports` was chosen as the most similar to ES module patterns.
99 final _dartxVar = new JS.Identifier('dartx'); 95 final _dartxVar = new JS.Identifier('dartx');
100 final _exportsVar = new JS.TemporaryId('exports'); 96 final _exportsVar = new JS.TemporaryId('exports');
101 final _runtimeLibVar = new JS.Identifier('dart'); 97 final _runtimeLibVar = new JS.Identifier('dart');
102 final _namedArgTemp = new JS.TemporaryId('opts'); 98 final namedArgumentTemp = new JS.TemporaryId('opts');
103 99
104 final TypeProvider _types; 100 final TypeProvider _types;
105 101
106 ConstFieldVisitor _constField; 102 ConstFieldVisitor _constField;
107 103
108 ModuleItemLoadOrder _loader; 104 ModuleItemLoadOrder _loader;
109 105
110 /// _interceptors.JSArray<E>, used for List literals. 106 /// _interceptors.JSArray<E>, used for List literals.
111 ClassElement _jsArray; 107 ClassElement _jsArray;
112 108
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 _jsModuleValue = 235 _jsModuleValue =
240 getConstantField(jsName, 'name', types.stringType)?.toStringValue(); 236 getConstantField(jsName, 'name', types.stringType)?.toStringValue();
241 } 237 }
242 238
243 @override 239 @override
244 void visitImportDirective(ImportDirective node) { 240 void visitImportDirective(ImportDirective node) {
245 // Nothing to do yet, but we'll want to convert this to an ES6 import once 241 // Nothing to do yet, but we'll want to convert this to an ES6 import once
246 // we have support for modules. 242 // we have support for modules.
247 } 243 }
248 244
249 @override void visitPartDirective(PartDirective node) {} 245 @override
250 @override void visitPartOfDirective(PartOfDirective node) {} 246 void visitPartDirective(PartDirective node) {}
247 @override
248 void visitPartOfDirective(PartOfDirective node) {}
251 249
252 @override 250 @override
253 void visitExportDirective(ExportDirective node) { 251 void visitExportDirective(ExportDirective node) {
254 var exportName = _libraryName(node.uriElement); 252 var exportName = emitLibraryName(node.uriElement);
255 253
256 var currentLibNames = currentLibrary.publicNamespace.definedNames; 254 var currentLibNames = currentLibrary.publicNamespace.definedNames;
257 255
258 var args = [_exportsVar, exportName]; 256 var args = [_exportsVar, exportName];
259 if (node.combinators.isNotEmpty) { 257 if (node.combinators.isNotEmpty) {
260 var shownNames = <JS.Expression>[]; 258 var shownNames = <JS.Expression>[];
261 var hiddenNames = <JS.Expression>[]; 259 var hiddenNames = <JS.Expression>[];
262 260
263 var show = node.combinators.firstWhere((c) => c is ShowCombinator, 261 var show = node.combinators.firstWhere((c) => c is ShowCombinator,
264 orElse: () => null) as ShowCombinator; 262 orElse: () => null) as ShowCombinator;
(...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after
1333 1331
1334 if (param.kind == ParameterKind.NAMED) { 1332 if (param.kind == ParameterKind.NAMED) {
1335 if (!options.destructureNamedParams) { 1333 if (!options.destructureNamedParams) {
1336 // Parameters will be passed using their real names, not the (possibly 1334 // Parameters will be passed using their real names, not the (possibly
1337 // renamed) local variable. 1335 // renamed) local variable.
1338 var paramName = js.string(param.identifier.name, "'"); 1336 var paramName = js.string(param.identifier.name, "'");
1339 1337
1340 // TODO(ochafik): Fix `'prop' in obj` to please Closure's renaming. 1338 // TODO(ochafik): Fix `'prop' in obj` to please Closure's renaming.
1341 body.add(js.statement('let # = # && # in # ? #.# : #;', [ 1339 body.add(js.statement('let # = # && # in # ? #.# : #;', [
1342 jsParam, 1340 jsParam,
1343 _namedArgTemp, 1341 namedArgumentTemp,
1344 paramName, 1342 paramName,
1345 _namedArgTemp, 1343 namedArgumentTemp,
1346 _namedArgTemp, 1344 namedArgumentTemp,
1347 paramName, 1345 paramName,
1348 _defaultParamValue(param), 1346 _defaultParamValue(param),
1349 ])); 1347 ]));
1350 } 1348 }
1351 } else if (param.kind == ParameterKind.POSITIONAL && 1349 } else if (param.kind == ParameterKind.POSITIONAL &&
1352 !options.destructureNamedParams) { 1350 !options.destructureNamedParams) {
1353 body.add(js.statement('if (# === void 0) # = #;', 1351 body.add(js.statement('if (# === void 0) # = #;',
1354 [jsParam, jsParam, _defaultParamValue(param)])); 1352 [jsParam, jsParam, _defaultParamValue(param)]));
1355 } 1353 }
1356 1354
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 1445
1448 return annotate( 1446 return annotate(
1449 new JS.Method(_elementMemberName(node.element), fn, 1447 new JS.Method(_elementMemberName(node.element), fn,
1450 isGetter: node.isGetter, 1448 isGetter: node.isGetter,
1451 isSetter: node.isSetter, 1449 isSetter: node.isSetter,
1452 isStatic: node.isStatic), 1450 isStatic: node.isStatic),
1453 node, 1451 node,
1454 node.element); 1452 node.element);
1455 } 1453 }
1456 1454
1457 /// Returns the name value of the `JSExportName` annotation (when compiling
1458 /// the SDK), or `null` if there's none. This is used to control the name
1459 /// under which functions are compiled and exported.
1460 String _getJSExportName(Element e) {
1461 if (!e.source.isInSystemLibrary) {
1462 return null;
1463 }
1464 var jsName = findAnnotation(e, isJSExportNameAnnotation);
1465 return getConstantField(jsName, 'name', types.stringType)?.toStringValue();
1466 }
1467
1468 @override 1455 @override
1469 JS.Statement visitFunctionDeclaration(FunctionDeclaration node) { 1456 JS.Statement visitFunctionDeclaration(FunctionDeclaration node) {
1470 assert(node.parent is CompilationUnit); 1457 assert(node.parent is CompilationUnit);
1471 1458
1472 if (_externalOrNative(node)) return null; 1459 if (_externalOrNative(node)) return null;
1473 1460
1474 if (node.isGetter || node.isSetter) { 1461 if (node.isGetter || node.isSetter) {
1475 // Add these later so we can use getter/setter syntax. 1462 // Add these later so we can use getter/setter syntax.
1476 _properties.add(node); 1463 _properties.add(node);
1477 return null; 1464 return null;
(...skipping 12 matching lines...) Expand all
1490 } 1477 }
1491 1478
1492 var id = new JS.Identifier(name); 1479 var id = new JS.Identifier(name);
1493 body.add(annotate(new JS.FunctionDeclaration(id, fn), node, node.element)); 1480 body.add(annotate(new JS.FunctionDeclaration(id, fn), node, node.element));
1494 if (!_isDartRuntime) { 1481 if (!_isDartRuntime) {
1495 body.add(_emitFunctionTagged(id, node.element.type, topLevel: true) 1482 body.add(_emitFunctionTagged(id, node.element.type, topLevel: true)
1496 .toStatement()); 1483 .toStatement());
1497 } 1484 }
1498 1485
1499 if (isPublic(name)) { 1486 if (isPublic(name)) {
1500 _addExport(name, _getJSExportName(node.element) ?? name); 1487 _addExport(name, getJSExportName(node.element, types) ?? name);
1501 } 1488 }
1502 return _statement(body); 1489 return _statement(body);
1503 } 1490 }
1504 1491
1505 bool _isInlineJSFunction(FunctionExpression functionExpression) { 1492 bool _isInlineJSFunction(FunctionExpression functionExpression) {
1506 var body = functionExpression.body; 1493 var body = functionExpression.body;
1507 if (body is ExpressionFunctionBody) { 1494 if (body is ExpressionFunctionBody) {
1508 return _isJSInvocation(body.expression); 1495 return _isJSInvocation(body.expression);
1509 } else if (body is BlockFunctionBody) { 1496 } else if (body is BlockFunctionBody) {
1510 if (body.block.statements.length == 1) { 1497 if (body.block.statements.length == 1) {
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
1955 if (jsArgs != null) { 1942 if (jsArgs != null) {
1956 var genericName = _emitTopLevelName(element, suffix: '\$'); 1943 var genericName = _emitTopLevelName(element, suffix: '\$');
1957 return js.call('#(#)', [genericName, jsArgs]); 1944 return js.call('#(#)', [genericName, jsArgs]);
1958 } 1945 }
1959 } 1946 }
1960 1947
1961 return _emitTopLevelName(element); 1948 return _emitTopLevelName(element);
1962 } 1949 }
1963 1950
1964 JS.Expression _emitTopLevelName(Element e, {String suffix: ''}) { 1951 JS.Expression _emitTopLevelName(Element e, {String suffix: ''}) {
1965 var libName = _libraryName(e.library); 1952 var libName = emitLibraryName(e.library);
1966 1953
1967 // Always qualify: 1954 // Always qualify:
1968 // * mutable top-level fields 1955 // * mutable top-level fields
1969 // * elements from other libraries 1956 // * elements from other libraries
1970 bool mutableTopLevel = e is TopLevelVariableElement && 1957 bool mutableTopLevel = e is TopLevelVariableElement &&
1971 !e.isConst && 1958 !e.isConst &&
1972 !_isFinalJSDecl(e.computeNode()); 1959 !_isFinalJSDecl(e.computeNode());
1973 bool fromAnotherLibrary = e.library != currentLibrary; 1960 bool fromAnotherLibrary = e.library != currentLibrary;
1974 var nameExpr; 1961 var nameExpr;
1975 if (fromAnotherLibrary) { 1962 if (fromAnotherLibrary) {
1976 nameExpr = _propertyName((_getJSExportName(e) ?? e.name) + suffix); 1963 nameExpr = _propertyName((getJSExportName(e, types) ?? e.name) + suffix);
1977 } else { 1964 } else {
1978 nameExpr = _propertyName(e.name + suffix); 1965 nameExpr = _propertyName(e.name + suffix);
1979 } 1966 }
1980 if (mutableTopLevel || fromAnotherLibrary) { 1967 if (mutableTopLevel || fromAnotherLibrary) {
1981 return new JS.PropertyAccess(libName, nameExpr); 1968 return new JS.PropertyAccess(libName, nameExpr);
1982 } 1969 }
1983 1970
1984 var id = new JS.MaybeQualifiedId(libName, nameExpr); 1971 var id = new JS.MaybeQualifiedId(libName, nameExpr);
1985 _qualifiedIds.add(new Tuple2(e, id)); 1972 _qualifiedIds.add(new Tuple2(e, id));
1986 return id; 1973 return id;
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
2274 } else { 2261 } else {
2275 var jsParam = _visit(param); 2262 var jsParam = _visit(param);
2276 result.add(param is DefaultFormalParameter && destructure 2263 result.add(param is DefaultFormalParameter && destructure
2277 ? new JS.DestructuredVariable( 2264 ? new JS.DestructuredVariable(
2278 name: jsParam, defaultValue: _defaultParamValue(param)) 2265 name: jsParam, defaultValue: _defaultParamValue(param))
2279 : jsParam); 2266 : jsParam);
2280 } 2267 }
2281 } 2268 }
2282 2269
2283 if (needsOpts) { 2270 if (needsOpts) {
2284 result.add(_namedArgTemp); 2271 result.add(namedArgumentTemp);
2285 } else if (namedVars.isNotEmpty) { 2272 } else if (namedVars.isNotEmpty) {
2286 // Note: `var {valueOf} = {}` extracts `Object.prototype.valueOf`, so 2273 // Note: `var {valueOf} = {}` extracts `Object.prototype.valueOf`, so
2287 // in case there are conflicting names we create an object without 2274 // in case there are conflicting names we create an object without
2288 // any prototype. 2275 // any prototype.
2289 var defaultOpts = hasNamedArgsConflictingWithObjectProperties 2276 var defaultOpts = hasNamedArgsConflictingWithObjectProperties
2290 ? js.call('Object.create(null)') 2277 ? js.call('Object.create(null)')
2291 : js.call('{}'); 2278 : js.call('{}');
2292 result.add(new JS.DestructuredVariable( 2279 result.add(new JS.DestructuredVariable(
2293 structure: new JS.ObjectBindingPattern(namedVars), 2280 structure: new JS.ObjectBindingPattern(namedVars),
2294 type: emitNamedParamsArgType(node.parameterElements), 2281 type: emitNamedParamsArgType(node.parameterElements),
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
2497 } 2484 }
2498 2485
2499 // Treat `final x = JS('', '...')` as a const (non-lazy) to help compile 2486 // Treat `final x = JS('', '...')` as a const (non-lazy) to help compile
2500 // runtime helpers. 2487 // runtime helpers.
2501 var isJSTopLevel = field.isFinal && _isFinalJSDecl(field); 2488 var isJSTopLevel = field.isFinal && _isFinalJSDecl(field);
2502 if (isJSTopLevel) eagerInit = true; 2489 if (isJSTopLevel) eagerInit = true;
2503 2490
2504 var fieldName = field.name.name; 2491 var fieldName = field.name.name;
2505 var exportName = fieldName; 2492 var exportName = fieldName;
2506 if (element is TopLevelVariableElement) { 2493 if (element is TopLevelVariableElement) {
2507 exportName = _getJSExportName(element) ?? fieldName; 2494 exportName = getJSExportName(element, types) ?? fieldName;
2508 } 2495 }
2509 if ((field.isConst && eagerInit && element is TopLevelVariableElement) || 2496 if ((field.isConst && eagerInit && element is TopLevelVariableElement) ||
2510 isJSTopLevel) { 2497 isJSTopLevel) {
2511 // constant fields don't change, so we can generate them as `let` 2498 // constant fields don't change, so we can generate them as `let`
2512 // but add them to the module's exports. However, make sure we generate 2499 // but add them to the module's exports. However, make sure we generate
2513 // anything they depend on first. 2500 // anything they depend on first.
2514 2501
2515 if (isPublic(fieldName)) _addExport(fieldName, exportName); 2502 if (isPublic(fieldName)) _addExport(fieldName, exportName);
2516 var declKeyword = field.isConst || field.isFinal ? 'const' : 'let'; 2503 var declKeyword = field.isConst || field.isFinal ? 'const' : 'let';
2517 if (isJSTopLevel && jsInit is JS.ClassExpression) { 2504 if (isJSTopLevel && jsInit is JS.ClassExpression) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 isSetter: true), 2555 isSetter: true),
2569 node, 2556 node,
2570 _findAccessor(element, getter: false))); 2557 _findAccessor(element, getter: false)));
2571 } 2558 }
2572 } 2559 }
2573 2560
2574 JS.Expression objExpr; 2561 JS.Expression objExpr;
2575 if (target is ClassElement) { 2562 if (target is ClassElement) {
2576 objExpr = new JS.Identifier(target.type.name); 2563 objExpr = new JS.Identifier(target.type.name);
2577 } else { 2564 } else {
2578 objExpr = _libraryName(target); 2565 objExpr = emitLibraryName(target);
2579 } 2566 }
2580 2567
2581 return js 2568 return js
2582 .statement('dart.defineLazyProperties(#, { # });', [objExpr, methods]); 2569 .statement('dart.defineLazyProperties(#, { # });', [objExpr, methods]);
2583 } 2570 }
2584 2571
2585 PropertyAccessorElement _findAccessor(VariableElement element, 2572 PropertyAccessorElement _findAccessor(VariableElement element,
2586 {bool getter}) { 2573 {bool getter}) {
2587 var parent = element.enclosingElement; 2574 var parent = element.enclosingElement;
2588 if (parent is ClassElement) { 2575 if (parent is ClassElement) {
(...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after
3519 3506
3520 _visit(AstNode node) { 3507 _visit(AstNode node) {
3521 if (node == null) return null; 3508 if (node == null) return null;
3522 var result = node.accept(this); 3509 var result = node.accept(this);
3523 if (result is JS.Node) result = annotate(result, node); 3510 if (result is JS.Node) result = annotate(result, node);
3524 return result; 3511 return result;
3525 } 3512 }
3526 3513
3527 // TODO(jmesserly): this will need to be a generic method, if we ever want to 3514 // TODO(jmesserly): this will need to be a generic method, if we ever want to
3528 // self-host strong mode. 3515 // self-host strong mode.
3529 List /*<T>*/ _visitList /*<T>*/ (Iterable<AstNode> nodes) { 3516 List/*<T>*/ _visitList/*<T>*/(Iterable<AstNode> nodes) {
3530 if (nodes == null) return null; 3517 if (nodes == null) return null;
3531 var result = /*<T>*/ []; 3518 var result = /*<T>*/ [];
3532 for (var node in nodes) result.add(_visit(node)); 3519 for (var node in nodes) result.add(_visit(node));
3533 return result; 3520 return result;
3534 } 3521 }
3535 3522
3536 /// Visits a list of expressions, creating a comma expression if needed in JS. 3523 /// Visits a list of expressions, creating a comma expression if needed in JS.
3537 JS.Expression _visitListToBinary(List<Expression> nodes, String operator) { 3524 JS.Expression _visitListToBinary(List<Expression> nodes, String operator) {
3538 if (nodes == null || nodes.isEmpty) return null; 3525 if (nodes == null || nodes.isEmpty) return null;
3539 return new JS.Expression.binary( 3526 return new JS.Expression.binary(
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
3647 3634
3648 bool _externalOrNative(node) => 3635 bool _externalOrNative(node) =>
3649 node.externalKeyword != null || _functionBody(node) is NativeFunctionBody; 3636 node.externalKeyword != null || _functionBody(node) is NativeFunctionBody;
3650 3637
3651 FunctionBody _functionBody(node) => 3638 FunctionBody _functionBody(node) =>
3652 node is FunctionDeclaration ? node.functionExpression.body : node.body; 3639 node is FunctionDeclaration ? node.functionExpression.body : node.body;
3653 3640
3654 /// Choose a canonical name from the library element. 3641 /// Choose a canonical name from the library element.
3655 /// This never uses the library's name (the identifier in the `library` 3642 /// This never uses the library's name (the identifier in the `library`
3656 /// declaration) as it doesn't have any meaningful rules enforced. 3643 /// declaration) as it doesn't have any meaningful rules enforced.
3657 JS.Identifier _libraryName(LibraryElement library) { 3644 JS.Identifier emitLibraryName(LibraryElement library) {
3658 if (library == currentLibrary) return _exportsVar; 3645 if (library == currentLibrary) return _exportsVar;
3659 if (library.name == 'dart._runtime') return _runtimeLibVar; 3646 if (library.name == 'dart._runtime') return _runtimeLibVar;
3660 return _imports.putIfAbsent( 3647 return _imports.putIfAbsent(
3661 library, () => new JS.TemporaryId(jsLibraryName(library))); 3648 library, () => new JS.TemporaryId(jsLibraryName(library)));
3662 } 3649 }
3663 3650
3664 DartType getStaticType(Expression e) => 3651 DartType getStaticType(Expression e) =>
3665 e.staticType ?? DynamicTypeImpl.instance; 3652 e.staticType ?? DynamicTypeImpl.instance;
3666 3653
3667 JS.Node annotate(JS.Node node, AstNode original, [Element element]) { 3654 JS.Node annotate(JS.Node node, AstNode original, [Element element]) {
3668 if (options.closure && element != null) { 3655 if (options.closure && element != null) {
3669 node = node.withClosureAnnotation( 3656 node = node.withClosureAnnotation(closureAnnotationFor(
3670 closureAnnotationFor(node, original, element, _namedArgTemp.name)); 3657 node, original, element, namedArgumentTemp.name));
3671 } 3658 }
3672 return node..sourceInformation = original; 3659 return node..sourceInformation = original;
3673 } 3660 }
3674 3661
3675 /// Returns true if this is any kind of object represented by `Number` in JS. 3662 /// Returns true if this is any kind of object represented by `Number` in JS.
3676 /// 3663 ///
3677 /// In practice, this is 4 types: num, int, double, and JSNumber. 3664 /// In practice, this is 4 types: num, int, double, and JSNumber.
3678 /// 3665 ///
3679 /// JSNumber is the type that actually "implements" all numbers, hence it's 3666 /// JSNumber is the type that actually "implements" all numbers, hence it's
3680 /// a subtype of int and double (and num). It's in our "dart:_interceptors". 3667 /// a subtype of int and double (and num). It's in our "dart:_interceptors".
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
3836 3823
3837 /// A special kind of element created by the compiler, signifying a temporary 3824 /// A special kind of element created by the compiler, signifying a temporary
3838 /// variable. These objects use instance equality, and should be shared 3825 /// variable. These objects use instance equality, and should be shared
3839 /// everywhere in the tree where they are treated as the same variable. 3826 /// everywhere in the tree where they are treated as the same variable.
3840 class TemporaryVariableElement extends LocalVariableElementImpl { 3827 class TemporaryVariableElement extends LocalVariableElementImpl {
3841 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); 3828 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name);
3842 3829
3843 int get hashCode => identityHashCode(this); 3830 int get hashCode => identityHashCode(this);
3844 bool operator ==(Object other) => identical(this, other); 3831 bool operator ==(Object other) => identical(this, other);
3845 } 3832 }
OLDNEW
« no previous file with comments | « no previous file | lib/src/codegen/js_interop.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698