| 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 import 'dart:collection' show HashMap, HashSet; | 5 import 'dart:collection' show HashMap, HashSet; |
| 6 import 'dart:math' show min, max; | 6 import 'dart:math' show min, max; |
| 7 | 7 |
| 8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; | 10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 FunctionBody _currentFunction; | 109 FunctionBody _currentFunction; |
| 110 | 110 |
| 111 /// Helper class for emitting elements in the proper order to allow | 111 /// Helper class for emitting elements in the proper order to allow |
| 112 /// JS to load the module. | 112 /// JS to load the module. |
| 113 ElementLoader _loader; | 113 ElementLoader _loader; |
| 114 | 114 |
| 115 BuildUnit _buildUnit; | 115 BuildUnit _buildUnit; |
| 116 | 116 |
| 117 String _buildRoot; | 117 String _buildRoot; |
| 118 | 118 |
| 119 /// Whether we are currently generating code for the body of a `JS()` call. |
| 120 bool _isInForeignJS = false; |
| 121 |
| 119 CodeGenerator(AnalysisContext c, this.options, this._extensionTypes) | 122 CodeGenerator(AnalysisContext c, this.options, this._extensionTypes) |
| 120 : context = c, | 123 : context = c, |
| 121 types = c.typeProvider, | 124 types = c.typeProvider, |
| 122 _asyncStreamIterator = | 125 _asyncStreamIterator = |
| 123 _getLibrary(c, 'dart:async').getType('StreamIterator').type, | 126 _getLibrary(c, 'dart:async').getType('StreamIterator').type, |
| 124 _jsArray = _getLibrary(c, 'dart:_interceptors').getType('JSArray'), | 127 _jsArray = _getLibrary(c, 'dart:_interceptors').getType('JSArray'), |
| 125 dartCoreLibrary = _getLibrary(c, 'dart:core'), | 128 dartCoreLibrary = _getLibrary(c, 'dart:core'), |
| 126 dartJSLibrary = _getLibrary(c, 'dart:js'); | 129 dartJSLibrary = _getLibrary(c, 'dart:js'); |
| 127 | 130 |
| 128 LibraryElement get currentLibrary => _loader.currentElement.library; | 131 LibraryElement get currentLibrary => _loader.currentElement.library; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 | 215 |
| 213 // Collect all Element -> Node mappings, in case we need to forward declare | 216 // Collect all Element -> Node mappings, in case we need to forward declare |
| 214 // any nodes. | 217 // any nodes. |
| 215 var nodes = new HashMap<Element, AstNode>.identity(); | 218 var nodes = new HashMap<Element, AstNode>.identity(); |
| 216 compilationUnits.map(_collectElements).forEach(nodes.addAll); | 219 compilationUnits.map(_collectElements).forEach(nodes.addAll); |
| 217 _loader = new ElementLoader(_emitModuleItem, nodes); | 220 _loader = new ElementLoader(_emitModuleItem, nodes); |
| 218 | 221 |
| 219 // Add implicit dart:core dependency so it is first. | 222 // Add implicit dart:core dependency so it is first. |
| 220 emitLibraryName(dartCoreLibrary); | 223 emitLibraryName(dartCoreLibrary); |
| 221 | 224 |
| 222 // | |
| 223 // Visit each compilation unit and emit its code. | 225 // Visit each compilation unit and emit its code. |
| 224 // | 226 // |
| 225 // NOTE: declarations are not necessarily emitted in this order. | 227 // NOTE: declarations are not necessarily emitted in this order. |
| 226 // Order will be changed as needed so the resulting code can execute. | 228 // Order will be changed as needed so the resulting code can execute. |
| 227 // This is done by forward declaring items. | 229 // This is done by forward declaring items. |
| 228 compilationUnits.forEach(visitCompilationUnit); | 230 compilationUnits.forEach(visitCompilationUnit); |
| 229 | 231 |
| 230 // Declare imports | 232 // Declare imports |
| 231 _finishImports(items); | 233 _finishImports(items); |
| 232 | 234 |
| (...skipping 1769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2002 | 2004 |
| 2003 // Get the original declaring element. If we had a property accessor, this | 2005 // Get the original declaring element. If we had a property accessor, this |
| 2004 // indirects back to a (possibly synthetic) field. | 2006 // indirects back to a (possibly synthetic) field. |
| 2005 var element = accessor; | 2007 var element = accessor; |
| 2006 if (accessor is PropertyAccessorElement) element = accessor.variable; | 2008 if (accessor is PropertyAccessorElement) element = accessor.variable; |
| 2007 | 2009 |
| 2008 _loader.declareBeforeUse(element); | 2010 _loader.declareBeforeUse(element); |
| 2009 | 2011 |
| 2010 // type literal | 2012 // type literal |
| 2011 if (element is TypeDefiningElement) { | 2013 if (element is TypeDefiningElement) { |
| 2012 return _emitTypeName(fillDynamicTypeArgs(element.type)); | 2014 var typeName = _emitTypeName(fillDynamicTypeArgs(element.type)); |
| 2015 |
| 2016 // If the type is a type literal expression in Dart code, wrap the raw |
| 2017 // runtime type in a "Type" instance. |
| 2018 if (!_isInForeignJS && |
| 2019 node.parent is! MethodInvocation && |
| 2020 node.parent is! PrefixedIdentifier && |
| 2021 node.parent is! PropertyAccess) { |
| 2022 typeName = js.call('dart.wrapType(#)', typeName); |
| 2023 } |
| 2024 |
| 2025 return typeName; |
| 2013 } | 2026 } |
| 2014 | 2027 |
| 2015 // library member | 2028 // library member |
| 2016 if (element.enclosingElement is CompilationUnitElement) { | 2029 if (element.enclosingElement is CompilationUnitElement) { |
| 2017 return _emitTopLevelName(element); | 2030 return _emitTopLevelName(element); |
| 2018 } | 2031 } |
| 2019 | 2032 |
| 2020 var name = element.name; | 2033 var name = element.name; |
| 2021 | 2034 |
| 2022 // Unqualified class member. This could mean implicit-this, or implicit | 2035 // Unqualified class member. This could mean implicit-this, or implicit |
| (...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2470 return '#'; | 2483 return '#'; |
| 2471 } else { | 2484 } else { |
| 2472 return (element as InterpolationString).value; | 2485 return (element as InterpolationString).value; |
| 2473 } | 2486 } |
| 2474 }).join(); | 2487 }).join(); |
| 2475 } else { | 2488 } else { |
| 2476 templateArgs = args.skip(2); | 2489 templateArgs = args.skip(2); |
| 2477 source = (code as StringLiteral).stringValue; | 2490 source = (code as StringLiteral).stringValue; |
| 2478 } | 2491 } |
| 2479 | 2492 |
| 2493 // TODO(rnystrom): The JS() calls are almost never nested, and probably |
| 2494 // really shouldn't be, but there are at least a couple of calls in the |
| 2495 // HTML library where an argument to JS() is itself a JS() call. If those |
| 2496 // go away, this can just assert(!_isInForeignJS). |
| 2497 // Inside JS(), type names evaluate to the raw runtime type, not the |
| 2498 // wrapped Type object. |
| 2499 var wasInForeignJS = _isInForeignJS; |
| 2500 _isInForeignJS = true; |
| 2501 |
| 2480 var template = js.parseForeignJS(source); | 2502 var template = js.parseForeignJS(source); |
| 2481 var result = template.instantiate(_visitList(templateArgs)); | 2503 var result = template.instantiate(_visitList(templateArgs)); |
| 2504 |
| 2505 _isInForeignJS = wasInForeignJS; |
| 2506 |
| 2482 // `throw` is emitted as a statement by `parseForeignJS`. | 2507 // `throw` is emitted as a statement by `parseForeignJS`. |
| 2483 assert(result is JS.Expression || node.parent is ExpressionStatement); | 2508 assert(result is JS.Expression || node.parent is ExpressionStatement); |
| 2484 return result; | 2509 return result; |
| 2485 } | 2510 } |
| 2486 return null; | 2511 return null; |
| 2487 } | 2512 } |
| 2488 | 2513 |
| 2489 @override | 2514 @override |
| 2490 JS.Expression visitFunctionExpressionInvocation( | 2515 JS.Expression visitFunctionExpressionInvocation( |
| 2491 FunctionExpressionInvocation node) => | 2516 FunctionExpressionInvocation node) => |
| (...skipping 1733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4225 } | 4250 } |
| 4226 | 4251 |
| 4227 bool isLibraryPrefix(Expression node) => | 4252 bool isLibraryPrefix(Expression node) => |
| 4228 node is SimpleIdentifier && node.staticElement is PrefixElement; | 4253 node is SimpleIdentifier && node.staticElement is PrefixElement; |
| 4229 | 4254 |
| 4230 LibraryElement _getLibrary(AnalysisContext c, String uri) => | 4255 LibraryElement _getLibrary(AnalysisContext c, String uri) => |
| 4231 c.computeLibraryElement(c.sourceFactory.forUri(uri)); | 4256 c.computeLibraryElement(c.sourceFactory.forUri(uri)); |
| 4232 | 4257 |
| 4233 bool _isDartRuntime(LibraryElement l) => | 4258 bool _isDartRuntime(LibraryElement l) => |
| 4234 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; | 4259 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; |
| OLD | NEW |