Chromium Code Reviews| 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 | 2 |
| 3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
| 4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
| 5 | 5 |
| 6 import 'dart:collection' show HashMap, HashSet; | 6 import 'dart:collection' show HashMap, HashSet; |
| 7 import 'dart:math' show min, max; | 7 import 'dart:math' show min, max; |
| 8 | 8 |
| 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
| 10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 import 'js_metalet.dart' as JS; | 46 import 'js_metalet.dart' as JS; |
| 47 import 'js_names.dart' as JS; | 47 import 'js_names.dart' as JS; |
| 48 import 'js_typeref_codegen.dart' show JsTypeRefCodegen; | 48 import 'js_typeref_codegen.dart' show JsTypeRefCodegen; |
| 49 import 'module_builder.dart' show pathToJSIdentifier; | 49 import 'module_builder.dart' show pathToJSIdentifier; |
| 50 import 'nullable_type_inference.dart' show NullableTypeInference; | 50 import 'nullable_type_inference.dart' show NullableTypeInference; |
| 51 import 'property_model.dart'; | 51 import 'property_model.dart'; |
| 52 import 'reify_coercions.dart' show CoercionReifier; | 52 import 'reify_coercions.dart' show CoercionReifier; |
| 53 import 'side_effect_analysis.dart' show ConstFieldVisitor, isStateless; | 53 import 'side_effect_analysis.dart' show ConstFieldVisitor, isStateless; |
| 54 import 'type_utilities.dart'; | 54 import 'type_utilities.dart'; |
| 55 | 55 |
| 56 class CodeGenerator extends GeneralizingAstVisitor | 56 /// The code generator for Dart Dev Compiler. |
| 57 with ClosureAnnotator, JsTypeRefCodegen, NullableTypeInference { | 57 /// |
| 58 /// Takes as input resolved Dart ASTs for every compilation unit in every | |
| 59 /// library in the module. Produces a single JavaScript AST for the module as | |
| 60 /// output, along with its source map. | |
| 61 /// | |
| 62 /// This class attempts to preserve identifier names and structure of the input | |
| 63 /// Dart code, whenever this is possible to do in the generated code. | |
| 64 // | |
| 65 // TODO(jmesserly): we should use separate visitors for statements and | |
| 66 // expressions. Declarations are handled directly, and many minor component | |
| 67 // AST nodes aren't visited, so the visitor pattern isn't helping except for | |
| 68 // expressions (which result in JS.Expression) and statements | |
| 69 // (which result in (JS.Statement). | |
| 70 class CodeGenerator extends Object | |
| 71 with ClosureAnnotator, JsTypeRefCodegen, NullableTypeInference | |
| 72 implements AstVisitor<JS.Node> { | |
| 58 final AnalysisContext context; | 73 final AnalysisContext context; |
| 59 final SummaryDataStore summaryData; | 74 final SummaryDataStore summaryData; |
| 60 | 75 |
| 61 final CompilerOptions options; | 76 final CompilerOptions options; |
| 62 final StrongTypeSystemImpl rules; | 77 final StrongTypeSystemImpl rules; |
| 63 | 78 |
| 64 /// The set of libraries we are currently compiling, and the temporaries used | 79 /// The set of libraries we are currently compiling, and the temporaries used |
| 65 /// to refer to them. | 80 /// to refer to them. |
| 66 /// | 81 /// |
| 67 /// We sometimes special case codegen for a single library, as it simplifies | 82 /// We sometimes special case codegen for a single library, as it simplifies |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 232 null, | 247 null, |
| 233 sdk is SummaryBasedDartSdk | 248 sdk is SummaryBasedDartSdk |
| 234 ? sdk.bundle | 249 ? sdk.bundle |
| 235 : (sdk as FolderBasedDartSdk).getSummarySdkBundle(true)); | 250 : (sdk as FolderBasedDartSdk).getSummarySdkBundle(true)); |
| 236 } | 251 } |
| 237 | 252 |
| 238 var assembler = new PackageBundleAssembler(); | 253 var assembler = new PackageBundleAssembler(); |
| 239 assembler.recordDependencies(summaryData); | 254 assembler.recordDependencies(summaryData); |
| 240 | 255 |
| 241 var uriToUnit = new Map<String, UnlinkedUnit>.fromIterable(units, | 256 var uriToUnit = new Map<String, UnlinkedUnit>.fromIterable(units, |
| 242 key: (u) => u.element.source.uri.toString(), value: (unit) { | 257 key: (u) => u.element.source.uri.toString(), |
| 243 var unlinked = serializeAstUnlinked(unit); | 258 value: (unit) { |
| 244 assembler.addUnlinkedUnit(unit.element.source, unlinked); | 259 var unlinked = serializeAstUnlinked(unit); |
| 245 return unlinked; | 260 assembler.addUnlinkedUnit(unit.element.source, unlinked); |
| 246 }); | 261 return unlinked; |
| 262 }); | |
| 247 | 263 |
| 248 summary_link | 264 summary_link |
| 249 .link( | 265 .link( |
| 250 uriToUnit.keys.toSet(), | 266 uriToUnit.keys.toSet(), |
| 251 (uri) => summaryData.linkedMap[uri], | 267 (uri) => summaryData.linkedMap[uri], |
| 252 (uri) => summaryData.unlinkedMap[uri] ?? uriToUnit[uri], | 268 (uri) => summaryData.unlinkedMap[uri] ?? uriToUnit[uri], |
| 253 context.declaredVariables.get, | 269 context.declaredVariables.get, |
| 254 true) | 270 true) |
| 255 .forEach(assembler.addLinkedLibrary); | 271 .forEach(assembler.addLinkedLibrary); |
| 256 | 272 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 } | 338 } |
| 323 | 339 |
| 324 // Add implicit dart:core dependency so it is first. | 340 // Add implicit dart:core dependency so it is first. |
| 325 emitLibraryName(dartCoreLibrary); | 341 emitLibraryName(dartCoreLibrary); |
| 326 | 342 |
| 327 // Visit each compilation unit and emit its code. | 343 // Visit each compilation unit and emit its code. |
| 328 // | 344 // |
| 329 // NOTE: declarations are not necessarily emitted in this order. | 345 // NOTE: declarations are not necessarily emitted in this order. |
| 330 // Order will be changed as needed so the resulting code can execute. | 346 // Order will be changed as needed so the resulting code can execute. |
| 331 // This is done by forward declaring items. | 347 // This is done by forward declaring items. |
| 332 compilationUnits.forEach(_emitCompilationUnit); | 348 compilationUnits.forEach(visitCompilationUnit); |
| 333 assert(_deferredProperties.isEmpty); | 349 assert(_deferredProperties.isEmpty); |
| 334 | 350 |
| 335 // Visit directives (for exports) | 351 // Visit directives (for exports) |
| 336 compilationUnits.forEach(_emitExportDirectives); | 352 compilationUnits.forEach(_emitExportDirectives); |
| 337 | 353 |
| 338 // Declare imports | 354 // Declare imports |
| 339 _finishImports(items); | 355 _finishImports(items); |
| 340 | 356 |
| 341 // Discharge the type table cache variables and | 357 // Discharge the type table cache variables and |
| 342 // hoisted definitions. | 358 // hoisted definitions. |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 558 void _declareBeforeUse(TypeDefiningElement e) { | 574 void _declareBeforeUse(TypeDefiningElement e) { |
| 559 if (e == null) return; | 575 if (e == null) return; |
| 560 | 576 |
| 561 var topLevel = _topLevelElements; | 577 var topLevel = _topLevelElements; |
| 562 if (topLevel.isNotEmpty && identical(currentElement, topLevel.last)) { | 578 if (topLevel.isNotEmpty && identical(currentElement, topLevel.last)) { |
| 563 // If the item is from our library, try to emit it now. | 579 // If the item is from our library, try to emit it now. |
| 564 _emitTypeDeclaration(e); | 580 _emitTypeDeclaration(e); |
| 565 } | 581 } |
| 566 } | 582 } |
| 567 | 583 |
| 568 void _emitCompilationUnit(CompilationUnit unit) { | 584 @override |
| 585 visitCompilationUnit(CompilationUnit unit) { | |
| 569 // NOTE: this method isn't the right place to initialize | 586 // NOTE: this method isn't the right place to initialize |
| 570 // per-compilation-unit state. Declarations can be visited out of order, | 587 // per-compilation-unit state. Declarations can be visited out of order, |
| 571 // this is only to catch things that haven't been emitted yet. | 588 // this is only to catch things that haven't been emitted yet. |
| 572 // | 589 // |
| 573 // See _emitTypeDeclaration. | 590 // See _emitTypeDeclaration. |
| 574 var library = unit.element.library; | 591 var library = unit.element.library; |
| 575 bool internalSdk = isSdkInternalRuntime(library); | 592 bool internalSdk = isSdkInternalRuntime(library); |
| 576 _currentElements.add(library); | 593 _currentElements.add(library); |
| 577 | 594 |
| 578 List<VariableDeclaration> fields; | 595 List<VariableDeclaration> fields; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 614 | 631 |
| 615 void _emitExportDirectives(CompilationUnit unit) { | 632 void _emitExportDirectives(CompilationUnit unit) { |
| 616 for (var directive in unit.directives) { | 633 for (var directive in unit.directives) { |
| 617 _currentElements.add(directive.element); | 634 _currentElements.add(directive.element); |
| 618 directive.accept(this); | 635 directive.accept(this); |
| 619 _currentElements.removeLast(); | 636 _currentElements.removeLast(); |
| 620 } | 637 } |
| 621 } | 638 } |
| 622 | 639 |
| 623 @override | 640 @override |
| 624 void visitLibraryDirective(LibraryDirective node) {} | 641 visitLibraryDirective(LibraryDirective node) => null; |
| 625 | 642 |
| 626 @override | 643 @override |
| 627 void visitImportDirective(ImportDirective node) { | 644 visitImportDirective(ImportDirective node) { |
| 628 // We don't handle imports here. | 645 // We don't handle imports here. |
| 629 // | 646 // |
| 630 // Instead, we collect imports whenever we need to generate a reference | 647 // Instead, we collect imports whenever we need to generate a reference |
| 631 // to another library. This has the effect of collecting the actually used | 648 // to another library. This has the effect of collecting the actually used |
| 632 // imports. | 649 // imports. |
| 633 // | 650 // |
| 634 // TODO(jmesserly): if this is a prefixed import, consider adding the prefix | 651 // TODO(jmesserly): if this is a prefixed import, consider adding the prefix |
| 635 // as an alias? | 652 // as an alias? |
| 653 return null; | |
| 636 } | 654 } |
| 637 | 655 |
| 638 @override | 656 @override |
| 639 void visitPartDirective(PartDirective node) {} | 657 visitPartDirective(PartDirective node) => null; |
| 640 | 658 |
| 641 @override | 659 @override |
| 642 void visitPartOfDirective(PartOfDirective node) {} | 660 visitPartOfDirective(PartOfDirective node) => null; |
| 643 | 661 |
| 644 @override | 662 @override |
| 645 void visitExportDirective(ExportDirective node) { | 663 visitExportDirective(ExportDirective node) { |
| 646 ExportElement element = node.element; | 664 ExportElement element = node.element; |
| 647 var currentLibrary = element.library; | 665 var currentLibrary = element.library; |
| 648 | 666 |
| 649 var currentNames = currentLibrary.publicNamespace.definedNames; | 667 var currentNames = currentLibrary.publicNamespace.definedNames; |
| 650 var exportedNames = | 668 var exportedNames = |
| 651 new NamespaceBuilder().createExportNamespaceForDirective(element); | 669 new NamespaceBuilder().createExportNamespaceForDirective(element); |
| 652 | 670 |
| 653 // We only need to export main as it is the only method part of the | 671 // We only need to export main as it is the only method part of the |
| 654 // publicly exposed JS API for a library. | 672 // publicly exposed JS API for a library. |
| 655 // TODO(jacobr): add a library level annotation indicating that all | 673 // TODO(jacobr): add a library level annotation indicating that all |
| 656 // contents of a library need to be exposed to JS. | 674 // contents of a library need to be exposed to JS. |
| 657 // https://github.com/dart-lang/sdk/issues/26368 | 675 // https://github.com/dart-lang/sdk/issues/26368 |
| 658 var export = exportedNames.get('main'); | 676 var export = exportedNames.get('main'); |
| 659 | 677 |
| 660 if (export is FunctionElement) { | 678 if (export is FunctionElement) { |
| 661 // Don't allow redefining names from this library. | 679 // Don't allow redefining names from this library. |
| 662 if (currentNames.containsKey(export.name)) return; | 680 if (currentNames.containsKey(export.name)) return null; |
| 663 | 681 |
| 664 var name = _emitTopLevelName(export); | 682 var name = _emitTopLevelName(export); |
| 665 _moduleItems.add(js.statement( | 683 _moduleItems.add(js.statement( |
| 666 '#.# = #;', [emitLibraryName(currentLibrary), name.selector, name])); | 684 '#.# = #;', [emitLibraryName(currentLibrary), name.selector, name])); |
| 667 } | 685 } |
| 668 } | 686 } |
| 669 | 687 |
| 670 @override | 688 @override |
| 671 visitAsExpression(AsExpression node) { | 689 visitAsExpression(AsExpression node) { |
| 672 Expression fromExpr = node.expression; | 690 Expression fromExpr = node.expression; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 748 var typeFormals = element.typeParameters; | 766 var typeFormals = element.typeParameters; |
| 749 if (typeFormals.isNotEmpty) { | 767 if (typeFormals.isNotEmpty) { |
| 750 return _defineClassTypeArguments(element, typeFormals, | 768 return _defineClassTypeArguments(element, typeFormals, |
| 751 js.statement('const # = #;', [element.name, body])); | 769 js.statement('const # = #;', [element.name, body])); |
| 752 } else { | 770 } else { |
| 753 return js.statement('# = #;', [_emitTopLevelName(element), body]); | 771 return js.statement('# = #;', [_emitTopLevelName(element), body]); |
| 754 } | 772 } |
| 755 } | 773 } |
| 756 | 774 |
| 757 @override | 775 @override |
| 776 visitGenericTypeAlias(GenericTypeAlias node) { | |
| 777 throw new UnimplementedError('Generic type aliases are not implemented. ' | |
| 778 'See https://github.com/dart-lang/sdk/issues/27971'); | |
| 779 } | |
| 780 | |
| 781 @override | |
| 758 JS.Expression visitTypeName(TypeName node) { | 782 JS.Expression visitTypeName(TypeName node) { |
| 759 if (node.type == null) { | 783 if (node.type == null) { |
| 760 // TODO(jmesserly): if the type fails to resolve, should we generate code | 784 // TODO(jmesserly): if the type fails to resolve, should we generate code |
| 761 // that throws instead? | 785 // that throws instead? |
| 762 assert(options.unsafeForceCompile || options.replCompile); | 786 assert(options.unsafeForceCompile || options.replCompile); |
| 763 return _callHelper('dynamic'); | 787 return _callHelper('dynamic'); |
| 764 } | 788 } |
| 765 return _emitType(node.type); | 789 return _emitType(node.type); |
| 766 } | 790 } |
| 767 | 791 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 789 [jsParams, _constructorName(parentCtor), jsParams]) as JS.Fun; | 813 [jsParams, _constructorName(parentCtor), jsParams]) as JS.Fun; |
| 790 methods.add(new JS.Method(_constructorName(ctor), fun)); | 814 methods.add(new JS.Method(_constructorName(ctor), fun)); |
| 791 } | 815 } |
| 792 } | 816 } |
| 793 | 817 |
| 794 var typeFormals = element.typeParameters; | 818 var typeFormals = element.typeParameters; |
| 795 var isGeneric = typeFormals.isNotEmpty; | 819 var isGeneric = typeFormals.isNotEmpty; |
| 796 var className = isGeneric ? element.name : _emitTopLevelName(element); | 820 var className = isGeneric ? element.name : _emitTopLevelName(element); |
| 797 JS.Statement declareInterfaces(JS.Statement decl) { | 821 JS.Statement declareInterfaces(JS.Statement decl) { |
| 798 if (element.interfaces.isNotEmpty) { | 822 if (element.interfaces.isNotEmpty) { |
| 799 var body = [decl] | 823 var body = [decl]..add(js.statement('#[#.implements] = () => #;', [ |
| 800 ..add(js.statement('#[#.implements] = () => #;', [ | |
| 801 className, | 824 className, |
| 802 _runtimeModule, | 825 _runtimeModule, |
| 803 new JS.ArrayInitializer( | 826 new JS.ArrayInitializer( |
| 804 new List<JS.Expression>.from(element.interfaces.map(_emitType))) | 827 new List<JS.Expression>.from(element.interfaces.map(_emitType))) |
| 805 ])); | 828 ])); |
| 806 decl = _statement(body); | 829 decl = _statement(body); |
| 807 } | 830 } |
| 808 return decl; | 831 return decl; |
| 809 } | 832 } |
| 810 | 833 |
| (...skipping 1255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2066 var redirect = node.redirectedConstructor; | 2089 var redirect = node.redirectedConstructor; |
| 2067 if (redirect != null) { | 2090 if (redirect != null) { |
| 2068 var newKeyword = | 2091 var newKeyword = |
| 2069 resolutionMap.staticElementForConstructorReference(redirect).isFactory | 2092 resolutionMap.staticElementForConstructorReference(redirect).isFactory |
| 2070 ? '' | 2093 ? '' |
| 2071 : 'new'; | 2094 : 'new'; |
| 2072 // Pass along all arguments verbatim, and let the callee handle them. | 2095 // Pass along all arguments verbatim, and let the callee handle them. |
| 2073 // TODO(jmesserly): we'll need something different once we have | 2096 // TODO(jmesserly): we'll need something different once we have |
| 2074 // rest/spread support, but this should work for now. | 2097 // rest/spread support, but this should work for now. |
| 2075 var params = | 2098 var params = |
| 2076 visitFormalParameterList(node.parameters, destructure: false); | 2099 _emitFormalParameterList(node.parameters, destructure: false); |
| 2077 | 2100 |
| 2078 var fun = new JS.Fun( | 2101 var fun = new JS.Fun( |
| 2079 params, | 2102 params, |
| 2080 js.statement('{ return $newKeyword #(#); }', | 2103 js.statement( |
| 2081 [_visit(redirect) as JS.Node, params]), | 2104 '{ return $newKeyword #(#); }', [_visit(redirect), params]), |
| 2082 returnType: returnType); | 2105 returnType: returnType); |
| 2083 return annotate( | 2106 return annotate( |
| 2084 new JS.Method(name, fun, isStatic: true), node, node.element); | 2107 new JS.Method(name, fun, isStatic: true), node, node.element); |
| 2085 } | 2108 } |
| 2086 | 2109 |
| 2087 var params = visitFormalParameterList(node.parameters); | 2110 var params = _emitFormalParameterList(node.parameters); |
| 2088 | 2111 |
| 2089 // Factory constructors are essentially static methods. | 2112 // Factory constructors are essentially static methods. |
| 2090 if (node.factoryKeyword != null) { | 2113 if (node.factoryKeyword != null) { |
| 2091 var body = <JS.Statement>[]; | 2114 var body = <JS.Statement>[]; |
| 2092 var init = _emitArgumentInitializers(node, constructor: true); | 2115 var init = _emitArgumentInitializers(node, constructor: true); |
| 2093 if (init != null) body.add(init); | 2116 if (init != null) body.add(init); |
| 2094 body.add(_visit(node.body)); | 2117 body.add(_visit(node.body)); |
| 2095 var fun = new JS.Fun(params, new JS.Block(body), returnType: returnType); | 2118 var fun = new JS.Fun(params, new JS.Block(body), returnType: returnType); |
| 2096 return annotate( | 2119 return annotate( |
| 2097 new JS.Method(name, fun, isStatic: true), node, node.element); | 2120 new JS.Method(name, fun, isStatic: true), node, node.element); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2170 @override | 2193 @override |
| 2171 JS.Statement visitRedirectingConstructorInvocation( | 2194 JS.Statement visitRedirectingConstructorInvocation( |
| 2172 RedirectingConstructorInvocation node) { | 2195 RedirectingConstructorInvocation node) { |
| 2173 var ctor = resolutionMap.staticElementForConstructorReference(node); | 2196 var ctor = resolutionMap.staticElementForConstructorReference(node); |
| 2174 var cls = ctor.enclosingElement; | 2197 var cls = ctor.enclosingElement; |
| 2175 // We can't dispatch to the constructor with `this.new` as that might hit a | 2198 // We can't dispatch to the constructor with `this.new` as that might hit a |
| 2176 // derived class constructor with the same name. | 2199 // derived class constructor with the same name. |
| 2177 return js.statement('#.prototype.#.call(this, #);', [ | 2200 return js.statement('#.prototype.#.call(this, #);', [ |
| 2178 new JS.Identifier(cls.name), | 2201 new JS.Identifier(cls.name), |
| 2179 _constructorName(ctor), | 2202 _constructorName(ctor), |
| 2180 _visit(node.argumentList) | 2203 _emitArgumentList(node.argumentList) |
| 2181 ]); | 2204 ]); |
| 2182 } | 2205 } |
| 2183 | 2206 |
| 2184 JS.Statement _superConstructorCall(ClassElement element, | 2207 JS.Statement _superConstructorCall(ClassElement element, |
| 2185 [SuperConstructorInvocation node]) { | 2208 [SuperConstructorInvocation node]) { |
| 2186 if (element.supertype == null) { | 2209 if (element.supertype == null) { |
| 2187 assert(element.type.isObject || options.unsafeForceCompile); | 2210 assert(element.type.isObject || options.unsafeForceCompile); |
| 2188 return null; | 2211 return null; |
| 2189 } | 2212 } |
| 2190 | 2213 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 2202 // we don't have a default constructor in the supertype. | 2225 // we don't have a default constructor in the supertype. |
| 2203 assert(options.unsafeForceCompile); | 2226 assert(options.unsafeForceCompile); |
| 2204 return null; | 2227 return null; |
| 2205 } | 2228 } |
| 2206 | 2229 |
| 2207 if (superCtor.name == '' && !_hasUnnamedSuperConstructor(element)) { | 2230 if (superCtor.name == '' && !_hasUnnamedSuperConstructor(element)) { |
| 2208 return null; | 2231 return null; |
| 2209 } | 2232 } |
| 2210 | 2233 |
| 2211 var name = _constructorName(superCtor); | 2234 var name = _constructorName(superCtor); |
| 2212 var args = node != null ? _visit(node.argumentList) : []; | 2235 var args = node != null ? _emitArgumentList(node.argumentList) : []; |
| 2213 return annotate(js.statement('super.#(#);', [name, args]), node); | 2236 return annotate(js.statement('super.#(#);', [name, args]), node); |
| 2214 } | 2237 } |
| 2215 | 2238 |
| 2216 bool _hasUnnamedSuperConstructor(ClassElement e) { | 2239 bool _hasUnnamedSuperConstructor(ClassElement e) { |
| 2217 var supertype = e.supertype; | 2240 var supertype = e.supertype; |
| 2218 if (supertype == null) return false; | 2241 if (supertype == null) return false; |
| 2219 if (_hasUnnamedConstructor(supertype.element)) return true; | 2242 if (_hasUnnamedConstructor(supertype.element)) return true; |
| 2220 for (var mixin in e.mixins) { | 2243 for (var mixin in e.mixins) { |
| 2221 if (_hasUnnamedConstructor(mixin.element)) return true; | 2244 if (_hasUnnamedConstructor(mixin.element)) return true; |
| 2222 } | 2245 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2262 if (element is FieldFormalParameterElement) { | 2285 if (element is FieldFormalParameterElement) { |
| 2263 fields[element.field] = _emitSimpleIdentifier(p.identifier); | 2286 fields[element.field] = _emitSimpleIdentifier(p.identifier); |
| 2264 } | 2287 } |
| 2265 } | 2288 } |
| 2266 | 2289 |
| 2267 // Run constructor field initializers such as `: foo = bar.baz` | 2290 // Run constructor field initializers such as `: foo = bar.baz` |
| 2268 for (var init in ctor.initializers) { | 2291 for (var init in ctor.initializers) { |
| 2269 if (init is ConstructorFieldInitializer) { | 2292 if (init is ConstructorFieldInitializer) { |
| 2270 var element = init.fieldName.staticElement as FieldElement; | 2293 var element = init.fieldName.staticElement as FieldElement; |
| 2271 fields[element] = _visit(init.expression); | 2294 fields[element] = _visit(init.expression); |
| 2295 } else if (init is AssertInitializer) { | |
| 2296 throw new UnimplementedError( | |
| 2297 'Assert initializers are not implemented. ' | |
| 2298 'See https://github.com/dart-lang/sdk/issues/27809'); | |
| 2272 } | 2299 } |
| 2273 } | 2300 } |
| 2274 } | 2301 } |
| 2275 | 2302 |
| 2276 for (var f in fields.keys) unsetFields.remove(f); | 2303 for (var f in fields.keys) unsetFields.remove(f); |
| 2277 | 2304 |
| 2278 // Initialize all remaining fields | 2305 // Initialize all remaining fields |
| 2279 unsetFields.forEach((element, fieldNode) { | 2306 unsetFields.forEach((element, fieldNode) { |
| 2280 JS.Expression value; | 2307 JS.Expression value; |
| 2281 if (fieldNode.initializer != null) { | 2308 if (fieldNode.initializer != null) { |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2383 } | 2410 } |
| 2384 } | 2411 } |
| 2385 | 2412 |
| 2386 JS.Fun _emitNativeFunctionBody(MethodDeclaration node) { | 2413 JS.Fun _emitNativeFunctionBody(MethodDeclaration node) { |
| 2387 String name = | 2414 String name = |
| 2388 getAnnotationName(node.element, isJSAnnotation) ?? node.name.name; | 2415 getAnnotationName(node.element, isJSAnnotation) ?? node.name.name; |
| 2389 if (node.isGetter) { | 2416 if (node.isGetter) { |
| 2390 return new JS.Fun([], js.statement('{ return this.#; }', [name])); | 2417 return new JS.Fun([], js.statement('{ return this.#; }', [name])); |
| 2391 } else if (node.isSetter) { | 2418 } else if (node.isSetter) { |
| 2392 var params = | 2419 var params = |
| 2393 visitFormalParameterList(node.parameters, destructure: false); | 2420 _emitFormalParameterList(node.parameters, destructure: false); |
| 2394 return new JS.Fun( | 2421 return new JS.Fun( |
| 2395 params, js.statement('{ this.# = #; }', [name, params.last])); | 2422 params, js.statement('{ this.# = #; }', [name, params.last])); |
| 2396 } else { | 2423 } else { |
| 2397 return js.call( | 2424 return js.call( |
| 2398 'function (...args) { return this.#.apply(this, args); }', name); | 2425 'function (...args) { return this.#.apply(this, args); }', name); |
| 2399 } | 2426 } |
| 2400 } | 2427 } |
| 2401 | 2428 |
| 2402 JS.Method _emitMethodDeclaration(InterfaceType type, MethodDeclaration node) { | 2429 JS.Method _emitMethodDeclaration(InterfaceType type, MethodDeclaration node) { |
| 2403 if (node.isAbstract) { | 2430 if (node.isAbstract) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2443 if (JS.Return.foundIn(fn)) { | 2470 if (JS.Return.foundIn(fn)) { |
| 2444 // If a return is inside body, transform `(params) { body }` to | 2471 // If a return is inside body, transform `(params) { body }` to |
| 2445 // `(params) { (() => { body })(); return value; }`. | 2472 // `(params) { (() => { body })(); return value; }`. |
| 2446 // TODO(jmesserly): we could instead generate the return differently, | 2473 // TODO(jmesserly): we could instead generate the return differently, |
| 2447 // and avoid the immediately invoked function. | 2474 // and avoid the immediately invoked function. |
| 2448 body = new JS.Call(new JS.ArrowFun([], fn.body), []).toStatement(); | 2475 body = new JS.Call(new JS.ArrowFun([], fn.body), []).toStatement(); |
| 2449 } | 2476 } |
| 2450 // Rewrite the function to include the return. | 2477 // Rewrite the function to include the return. |
| 2451 return new JS.Fun( | 2478 return new JS.Fun( |
| 2452 fn.params, new JS.Block([body, new JS.Return(fn.params.last)]), | 2479 fn.params, new JS.Block([body, new JS.Return(fn.params.last)]), |
| 2453 typeParams: fn.typeParams, | 2480 typeParams: fn.typeParams, returnType: fn.returnType) |
| 2454 returnType: fn.returnType)..sourceInformation = fn.sourceInformation; | 2481 ..sourceInformation = fn.sourceInformation; |
| 2455 } | 2482 } |
| 2456 | 2483 |
| 2457 @override | 2484 @override |
| 2458 JS.Statement visitFunctionDeclaration(FunctionDeclaration node) { | 2485 JS.Statement visitFunctionDeclaration(FunctionDeclaration node) { |
| 2459 assert(node.parent is CompilationUnit); | 2486 assert(node.parent is CompilationUnit); |
| 2460 | 2487 |
| 2461 if (_externalOrNative(node)) return null; | 2488 if (_externalOrNative(node)) return null; |
| 2462 | 2489 |
| 2463 if (node.isGetter || node.isSetter) { | 2490 if (node.isGetter || node.isSetter) { |
| 2464 PropertyAccessorElement element = node.element; | 2491 PropertyAccessorElement element = node.element; |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2649 var fn = _emitFunctionBody(node.element, node.parameters, node.body); | 2676 var fn = _emitFunctionBody(node.element, node.parameters, node.body); |
| 2650 return annotate(_makeGenericFunction(fn), node); | 2677 return annotate(_makeGenericFunction(fn), node); |
| 2651 } | 2678 } |
| 2652 | 2679 |
| 2653 JS.Fun _emitFunctionBody(ExecutableElement element, | 2680 JS.Fun _emitFunctionBody(ExecutableElement element, |
| 2654 FormalParameterList parameters, FunctionBody body) { | 2681 FormalParameterList parameters, FunctionBody body) { |
| 2655 FunctionType type = element.type; | 2682 FunctionType type = element.type; |
| 2656 | 2683 |
| 2657 // normal function (sync), vs (sync*, async, async*) | 2684 // normal function (sync), vs (sync*, async, async*) |
| 2658 var stdFn = !(element.isAsynchronous || element.isGenerator); | 2685 var stdFn = !(element.isAsynchronous || element.isGenerator); |
| 2659 var formals = visitFormalParameterList(parameters, destructure: stdFn); | 2686 var formals = _emitFormalParameterList(parameters, destructure: stdFn); |
| 2660 var code = (stdFn) | 2687 var code = (stdFn) |
| 2661 ? _visit(body) | 2688 ? _visit(body) |
| 2662 : new JS.Block( | 2689 : new JS.Block( |
| 2663 [_emitGeneratorFunctionBody(element, parameters, body).toReturn()]); | 2690 [_emitGeneratorFunctionBody(element, parameters, body).toReturn()]); |
| 2664 var typeFormals = _emitTypeFormals(type.typeFormals); | 2691 var typeFormals = _emitTypeFormals(type.typeFormals); |
| 2665 var returnType = emitTypeRef(type.returnType); | 2692 var returnType = emitTypeRef(type.returnType); |
| 2666 if (type.typeFormals.isNotEmpty) { | 2693 if (type.typeFormals.isNotEmpty) { |
| 2667 code = new JS.Block(<JS.Statement>[ | 2694 code = new JS.Block(<JS.Statement>[ |
| 2668 new JS.Block(_typeTable.discharge(type.typeFormals)), | 2695 new JS.Block(_typeTable.discharge(type.typeFormals)), |
| 2669 code | 2696 code |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2702 // In the body of a `sync*` and `async`, `yield`/`await` are both generated | 2729 // In the body of a `sync*` and `async`, `yield`/`await` are both generated |
| 2703 // simply as `yield`. | 2730 // simply as `yield`. |
| 2704 // | 2731 // |
| 2705 // `async*` uses the `dart.asyncStar` helper, and also has an extra `stream` | 2732 // `async*` uses the `dart.asyncStar` helper, and also has an extra `stream` |
| 2706 // argument to the generator, which is used for passing values to the | 2733 // argument to the generator, which is used for passing values to the |
| 2707 // _AsyncStarStreamController implementation type. | 2734 // _AsyncStarStreamController implementation type. |
| 2708 // `yield` is specially generated inside `async*`, see visitYieldStatement. | 2735 // `yield` is specially generated inside `async*`, see visitYieldStatement. |
| 2709 // `await` is generated as `yield`. | 2736 // `await` is generated as `yield`. |
| 2710 // runtime/_generators.js has an example of what the code is generated as. | 2737 // runtime/_generators.js has an example of what the code is generated as. |
| 2711 var savedController = _asyncStarController; | 2738 var savedController = _asyncStarController; |
| 2712 var jsParams = visitFormalParameterList(parameters); | 2739 var jsParams = _emitFormalParameterList(parameters); |
| 2713 if (kind == 'asyncStar') { | 2740 if (kind == 'asyncStar') { |
| 2714 _asyncStarController = new JS.TemporaryId('stream'); | 2741 _asyncStarController = new JS.TemporaryId('stream'); |
| 2715 jsParams.insert(0, _asyncStarController); | 2742 jsParams.insert(0, _asyncStarController); |
| 2716 } else { | 2743 } else { |
| 2717 _asyncStarController = null; | 2744 _asyncStarController = null; |
| 2718 } | 2745 } |
| 2719 var savedSuperAllowed = _superAllowed; | 2746 var savedSuperAllowed = _superAllowed; |
| 2720 _superAllowed = false; | 2747 _superAllowed = false; |
| 2721 // Visit the body with our async* controller set. | 2748 // Visit the body with our async* controller set. |
| 2722 var jsBody = _visit(body); | 2749 var jsBody = _visit(body); |
| 2723 _superAllowed = savedSuperAllowed; | 2750 _superAllowed = savedSuperAllowed; |
| 2724 _asyncStarController = savedController; | 2751 _asyncStarController = savedController; |
| 2725 | 2752 |
| 2726 DartType returnType = _getExpectedReturnType(element); | 2753 DartType returnType = _getExpectedReturnType(element); |
| 2727 JS.Expression gen = new JS.Fun(jsParams, jsBody, | 2754 JS.Expression gen = new JS.Fun(jsParams, jsBody, |
| 2728 isGenerator: true, returnType: emitTypeRef(returnType)); | 2755 isGenerator: true, returnType: emitTypeRef(returnType)); |
| 2729 if (JS.This.foundIn(gen)) { | 2756 if (JS.This.foundIn(gen)) { |
| 2730 gen = js.call('#.bind(this)', gen); | 2757 gen = js.call('#.bind(this)', gen); |
| 2731 } | 2758 } |
| 2732 | 2759 |
| 2733 var T = _emitType(returnType); | 2760 var T = _emitType(returnType); |
| 2734 return _callHelper('#(#)', [ | 2761 return _callHelper('#(#)', [ |
| 2735 kind, | 2762 kind, |
| 2736 [gen, T]..addAll(visitFormalParameterList(parameters, destructure: false)) | 2763 [gen, T]..addAll(_emitFormalParameterList(parameters, destructure: false)) |
| 2737 ]); | 2764 ]); |
| 2738 } | 2765 } |
| 2739 | 2766 |
| 2740 @override | 2767 @override |
| 2741 JS.Statement visitFunctionDeclarationStatement( | 2768 JS.Statement visitFunctionDeclarationStatement( |
| 2742 FunctionDeclarationStatement node) { | 2769 FunctionDeclarationStatement node) { |
| 2743 var func = node.functionDeclaration; | 2770 var func = node.functionDeclaration; |
| 2744 if (func.isGetter || func.isSetter) { | 2771 if (func.isGetter || func.isSetter) { |
| 2745 return js.comment('Unimplemented function get/set statement: $node'); | 2772 return js.comment('Unimplemented function get/set statement: $node'); |
| 2746 } | 2773 } |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3374 JS.Expression target; | 3401 JS.Expression target; |
| 3375 if (element is TemporaryVariableElement) { | 3402 if (element is TemporaryVariableElement) { |
| 3376 // If this is one of our compiler's temporary variables, use its JS form. | 3403 // If this is one of our compiler's temporary variables, use its JS form. |
| 3377 target = element.jsVariable; | 3404 target = element.jsVariable; |
| 3378 } else if (element is ParameterElement) { | 3405 } else if (element is ParameterElement) { |
| 3379 target = _emitParameter(element); | 3406 target = _emitParameter(element); |
| 3380 } else { | 3407 } else { |
| 3381 target = new JS.Identifier(element.name); | 3408 target = new JS.Identifier(element.name); |
| 3382 } | 3409 } |
| 3383 | 3410 |
| 3384 return _visit(rhs).toAssignExpression(annotate(target, node)); | 3411 return _visit<JS.Expression>(rhs) |
| 3412 .toAssignExpression(annotate(target, node)); | |
| 3385 } | 3413 } |
| 3386 | 3414 |
| 3387 /// Emits assignment to library scope element [element]. | 3415 /// Emits assignment to library scope element [element]. |
| 3388 JS.Expression _emitSetTopLevel( | 3416 JS.Expression _emitSetTopLevel( |
| 3389 Expression lhs, Element element, Expression rhs) { | 3417 Expression lhs, Element element, Expression rhs) { |
| 3390 return _visit(rhs) | 3418 return _visit<JS.Expression>(rhs) |
| 3391 .toAssignExpression(annotate(_emitTopLevelName(element), lhs)); | 3419 .toAssignExpression(annotate(_emitTopLevelName(element), lhs)); |
| 3392 } | 3420 } |
| 3393 | 3421 |
| 3394 /// Emits assignment to a static field element or property. | 3422 /// Emits assignment to a static field element or property. |
| 3395 JS.Expression _emitSetStaticProperty( | 3423 JS.Expression _emitSetStaticProperty( |
| 3396 Expression lhs, Element element, Expression rhs) { | 3424 Expression lhs, Element element, Expression rhs) { |
| 3397 // For static methods, we add the raw type name, without generics or | 3425 // For static methods, we add the raw type name, without generics or |
| 3398 // library prefix. We don't need those because static calls can't use | 3426 // library prefix. We don't need those because static calls can't use |
| 3399 // the generic type. | 3427 // the generic type. |
| 3400 ClassElement classElement = element.enclosingElement; | 3428 ClassElement classElement = element.enclosingElement; |
| 3401 var type = classElement.type; | 3429 var type = classElement.type; |
| 3402 var dynType = _emitStaticAccess(type); | 3430 var dynType = _emitStaticAccess(type); |
| 3403 var member = _emitMemberName(element.name, | 3431 var member = _emitMemberName(element.name, |
| 3404 isStatic: true, type: type, element: element); | 3432 isStatic: true, type: type, element: element); |
| 3405 return _visit(rhs).toAssignExpression( | 3433 return _visit<JS.Expression>(rhs).toAssignExpression( |
| 3406 annotate(new JS.PropertyAccess(dynType, member), lhs)); | 3434 annotate(new JS.PropertyAccess(dynType, member), lhs)); |
| 3407 } | 3435 } |
| 3408 | 3436 |
| 3409 /// Emits an assignment to the [element] property of instance referenced by | 3437 /// Emits an assignment to the [element] property of instance referenced by |
| 3410 /// [jsTarget]. | 3438 /// [jsTarget]. |
| 3411 JS.Expression _emitWriteInstanceProperty(Expression lhs, | 3439 JS.Expression _emitWriteInstanceProperty(Expression lhs, |
| 3412 JS.Expression jsTarget, Element element, JS.Expression value) { | 3440 JS.Expression jsTarget, Element element, JS.Expression value) { |
| 3413 String memberName = element.name; | 3441 String memberName = element.name; |
| 3414 var type = (element.enclosingElement as ClassElement).type; | 3442 var type = (element.enclosingElement as ClassElement).type; |
| 3415 var name = _emitMemberName(memberName, type: type, element: element); | 3443 var name = _emitMemberName(memberName, type: type, element: element); |
| 3416 return value.toAssignExpression( | 3444 return value.toAssignExpression( |
| 3417 annotate(new JS.PropertyAccess(jsTarget, name), lhs)); | 3445 annotate(new JS.PropertyAccess(jsTarget, name), lhs)); |
| 3418 } | 3446 } |
| 3419 | 3447 |
| 3420 JS.Expression _emitSetSuper(Expression lhs, SuperExpression target, | 3448 JS.Expression _emitSetSuper(Expression lhs, SuperExpression target, |
| 3421 SimpleIdentifier id, Expression rhs) { | 3449 SimpleIdentifier id, Expression rhs) { |
| 3422 // TODO(sra): Determine whether and access helper is required for the | 3450 // TODO(sra): Determine whether and access helper is required for the |
| 3423 // setter. For now fall back on the r-value path. | 3451 // setter. For now fall back on the r-value path. |
| 3424 return _visit(rhs).toAssignExpression(_visit(lhs)); | 3452 return _visit<JS.Expression>(rhs).toAssignExpression(_visit(lhs)); |
| 3425 } | 3453 } |
| 3426 | 3454 |
| 3427 JS.Expression _emitNullSafeSet(PropertyAccess node, Expression right) { | 3455 JS.Expression _emitNullSafeSet(PropertyAccess node, Expression right) { |
| 3428 // Emit `obj?.prop = expr` as: | 3456 // Emit `obj?.prop = expr` as: |
| 3429 // | 3457 // |
| 3430 // (_ => _ == null ? null : _.prop = expr)(obj). | 3458 // (_ => _ == null ? null : _.prop = expr)(obj). |
| 3431 // | 3459 // |
| 3432 // We could use a helper, e.g.: `nullSafeSet(e1, _ => _.v = e2)` | 3460 // We could use a helper, e.g.: `nullSafeSet(e1, _ => _.v = e2)` |
| 3433 // | 3461 // |
| 3434 // However with MetaLet, we get clean code in statement or void context, | 3462 // However with MetaLet, we get clean code in statement or void context, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3491 } | 3519 } |
| 3492 if (node.methodName.name == 'call') { | 3520 if (node.methodName.name == 'call') { |
| 3493 var targetType = resolutionMap.staticTypeForExpression(target); | 3521 var targetType = resolutionMap.staticTypeForExpression(target); |
| 3494 if (targetType is FunctionType) { | 3522 if (targetType is FunctionType) { |
| 3495 // Call methods on function types should be handled as regular function | 3523 // Call methods on function types should be handled as regular function |
| 3496 // invocations. | 3524 // invocations. |
| 3497 return _emitFunctionCall(node, node.target); | 3525 return _emitFunctionCall(node, node.target); |
| 3498 } | 3526 } |
| 3499 if (targetType.isDartCoreFunction || targetType.isDynamic) { | 3527 if (targetType.isDartCoreFunction || targetType.isDynamic) { |
| 3500 // TODO(vsm): Can a call method take generic type parameters? | 3528 // TODO(vsm): Can a call method take generic type parameters? |
| 3501 return _emitDynamicInvoke(node, _visit(target), | 3529 return _emitDynamicInvoke( |
| 3502 _visit(node.argumentList) as List<JS.Expression>); | 3530 node, _visit(target), _emitArgumentList(node.argumentList)); |
| 3503 } | 3531 } |
| 3504 } | 3532 } |
| 3505 | 3533 |
| 3506 return _emitMethodCall(target, node); | 3534 return _emitMethodCall(target, node); |
| 3507 } | 3535 } |
| 3508 | 3536 |
| 3509 JS.Expression _emitMethodCall(Expression target, MethodInvocation node) { | 3537 JS.Expression _emitMethodCall(Expression target, MethodInvocation node) { |
| 3510 var args = _visit(node.argumentList) as List<JS.Expression>; | 3538 var args = _emitArgumentList(node.argumentList); |
| 3511 var typeArgs = _emitInvokeTypeArguments(node); | 3539 var typeArgs = _emitInvokeTypeArguments(node); |
| 3512 | 3540 |
| 3513 if (target is SuperExpression && !_superAllowed) { | 3541 if (target is SuperExpression && !_superAllowed) { |
| 3514 return _emitSuperHelperCall(typeArgs, args, target, node); | 3542 return _emitSuperHelperCall(typeArgs, args, target, node); |
| 3515 } | 3543 } |
| 3516 | 3544 |
| 3517 return _emitMethodCallInternal(target, node, args, typeArgs); | 3545 return _emitMethodCallInternal(target, node, args, typeArgs); |
| 3518 } | 3546 } |
| 3519 | 3547 |
| 3520 JS.Expression _emitSuperHelperCall(List<JS.Expression> typeArgs, | 3548 JS.Expression _emitSuperHelperCall(List<JS.Expression> typeArgs, |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3640 } | 3668 } |
| 3641 | 3669 |
| 3642 /// Emits a function call, to a top-level function, local function, or | 3670 /// Emits a function call, to a top-level function, local function, or |
| 3643 /// an expression. | 3671 /// an expression. |
| 3644 JS.Expression _emitFunctionCall(InvocationExpression node, | 3672 JS.Expression _emitFunctionCall(InvocationExpression node, |
| 3645 [Expression function]) { | 3673 [Expression function]) { |
| 3646 if (function == null) { | 3674 if (function == null) { |
| 3647 function = node.function; | 3675 function = node.function; |
| 3648 } | 3676 } |
| 3649 var fn = _visit(function); | 3677 var fn = _visit(function); |
| 3650 var args = _visit(node.argumentList) as List<JS.Expression>; | 3678 var args = _emitArgumentList(node.argumentList); |
| 3651 if (isDynamicInvoke(function)) { | 3679 if (isDynamicInvoke(function)) { |
| 3652 return _emitDynamicInvoke(node, fn, args); | 3680 return _emitDynamicInvoke(node, fn, args); |
| 3653 } else { | 3681 } else { |
| 3654 return new JS.Call(_applyInvokeTypeArguments(fn, node), args); | 3682 return new JS.Call(_applyInvokeTypeArguments(fn, node), args); |
| 3655 } | 3683 } |
| 3656 } | 3684 } |
| 3657 | 3685 |
| 3658 JS.Expression _applyInvokeTypeArguments( | 3686 JS.Expression _applyInvokeTypeArguments( |
| 3659 JS.Expression target, InvocationExpression node) { | 3687 JS.Expression target, InvocationExpression node) { |
| 3660 var typeArgs = _emitInvokeTypeArguments(node); | 3688 var typeArgs = _emitInvokeTypeArguments(node); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3789 } | 3817 } |
| 3790 return null; | 3818 return null; |
| 3791 } | 3819 } |
| 3792 | 3820 |
| 3793 @override | 3821 @override |
| 3794 JS.Expression visitFunctionExpressionInvocation( | 3822 JS.Expression visitFunctionExpressionInvocation( |
| 3795 FunctionExpressionInvocation node) => | 3823 FunctionExpressionInvocation node) => |
| 3796 _emitFunctionCall(node); | 3824 _emitFunctionCall(node); |
| 3797 | 3825 |
| 3798 @override | 3826 @override |
| 3799 List<JS.Expression> visitArgumentList(ArgumentList node) { | 3827 visitArgumentList(ArgumentList node) { |
| 3828 assert(false); | |
|
vsm
2017/04/14 13:14:39
Should this just be in your unreachable list below
Jennifer Messerly
2017/04/14 17:03:58
yes! oops :) done
| |
| 3829 } | |
| 3830 | |
| 3831 List<JS.Expression> _emitArgumentList(ArgumentList node) { | |
| 3800 var args = <JS.Expression>[]; | 3832 var args = <JS.Expression>[]; |
| 3801 var named = <JS.Property>[]; | 3833 var named = <JS.Property>[]; |
| 3802 for (var arg in node.arguments) { | 3834 for (var arg in node.arguments) { |
| 3803 if (arg is NamedExpression) { | 3835 if (arg is NamedExpression) { |
| 3804 named.add(_visit(arg)); | 3836 named.add(_visit(arg)); |
| 3805 } else if (arg is MethodInvocation && isJsSpreadInvocation(arg)) { | 3837 } else if (arg is MethodInvocation && isJsSpreadInvocation(arg)) { |
| 3806 args.add( | 3838 args.add( |
| 3807 new JS.RestParameter(_visit(arg.argumentList.arguments.single))); | 3839 new JS.RestParameter(_visit(arg.argumentList.arguments.single))); |
| 3808 } else { | 3840 } else { |
| 3809 args.add(_visit(arg)); | 3841 args.add(_visit(arg)); |
| 3810 } | 3842 } |
| 3811 } | 3843 } |
| 3812 if (named.isNotEmpty) { | 3844 if (named.isNotEmpty) { |
| 3813 args.add(new JS.ObjectInitializer(named)); | 3845 args.add(new JS.ObjectInitializer(named)); |
| 3814 } | 3846 } |
| 3815 return args; | 3847 return args; |
| 3816 } | 3848 } |
| 3817 | 3849 |
| 3818 @override | 3850 @override |
| 3819 JS.Property visitNamedExpression(NamedExpression node) { | 3851 JS.Property visitNamedExpression(NamedExpression node) { |
| 3820 assert(node.parent is ArgumentList); | 3852 assert(node.parent is ArgumentList); |
| 3821 return new JS.Property( | 3853 return new JS.Property( |
| 3822 _propertyName(node.name.label.name), _visit(node.expression)); | 3854 _propertyName(node.name.label.name), _visit(node.expression)); |
| 3823 } | 3855 } |
| 3824 | 3856 |
| 3825 @override | 3857 List<JS.Parameter> _emitFormalParameterList(FormalParameterList node, |
| 3826 List<JS.Parameter> visitFormalParameterList(FormalParameterList node, | |
| 3827 {bool destructure: true}) { | 3858 {bool destructure: true}) { |
| 3828 if (node == null) return []; | 3859 if (node == null) return []; |
| 3829 | 3860 |
| 3830 destructure = destructure && options.destructureNamedParams; | 3861 destructure = destructure && options.destructureNamedParams; |
| 3831 | 3862 |
| 3832 var result = <JS.Parameter>[]; | 3863 var result = <JS.Parameter>[]; |
| 3833 var namedVars = <JS.DestructuredVariable>[]; | 3864 var namedVars = <JS.DestructuredVariable>[]; |
| 3834 var hasNamedArgsConflictingWithObjectProperties = false; | 3865 var hasNamedArgsConflictingWithObjectProperties = false; |
| 3835 var needsOpts = false; | 3866 var needsOpts = false; |
| 3836 | 3867 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3973 JS.Statement visitVariableDeclarationStatement( | 4004 JS.Statement visitVariableDeclarationStatement( |
| 3974 VariableDeclarationStatement node) { | 4005 VariableDeclarationStatement node) { |
| 3975 // Special case a single variable with an initializer. | 4006 // Special case a single variable with an initializer. |
| 3976 // This helps emit cleaner code for things like: | 4007 // This helps emit cleaner code for things like: |
| 3977 // var result = []..add(1)..add(2); | 4008 // var result = []..add(1)..add(2); |
| 3978 var variables = node.variables.variables; | 4009 var variables = node.variables.variables; |
| 3979 if (variables.length == 1) { | 4010 if (variables.length == 1) { |
| 3980 var v = variables[0]; | 4011 var v = variables[0]; |
| 3981 if (v.initializer != null) { | 4012 if (v.initializer != null) { |
| 3982 var name = new JS.Identifier(v.name.name); | 4013 var name = new JS.Identifier(v.name.name); |
| 3983 return _visit(v.initializer).toVariableDeclaration(name); | 4014 return _visit<JS.Expression>(v.initializer).toVariableDeclaration(name); |
| 3984 } | 4015 } |
| 3985 } | 4016 } |
| 3986 return _visit(node.variables).toStatement(); | 4017 return _visit<JS.Expression>(node.variables).toStatement(); |
| 3987 } | 4018 } |
| 3988 | 4019 |
| 3989 @override | 4020 @override |
| 3990 visitVariableDeclarationList(VariableDeclarationList node) { | 4021 visitVariableDeclarationList(VariableDeclarationList node) { |
| 3991 return new JS.VariableDeclarationList( | 4022 return new JS.VariableDeclarationList( |
| 3992 'let', _visitList(node.variables) as List<JS.VariableInitialization>); | 4023 'let', _visitList(node.variables) as List<JS.VariableInitialization>); |
| 3993 } | 4024 } |
| 3994 | 4025 |
| 3995 @override | 4026 @override |
| 3996 visitVariableDeclaration(VariableDeclaration node) { | 4027 visitVariableDeclaration(VariableDeclaration node) { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4115 hoistType: options.hoistInstanceCreation); | 4146 hoistType: options.hoistInstanceCreation); |
| 4116 if (name != null) { | 4147 if (name != null) { |
| 4117 ctor = new JS.PropertyAccess(ctor, _propertyName(name.name)); | 4148 ctor = new JS.PropertyAccess(ctor, _propertyName(name.name)); |
| 4118 } | 4149 } |
| 4119 } else { | 4150 } else { |
| 4120 ctor = _emitConstructorName(element, type, name); | 4151 ctor = _emitConstructorName(element, type, name); |
| 4121 isFactory = element.isFactory; | 4152 isFactory = element.isFactory; |
| 4122 var classElem = element.enclosingElement; | 4153 var classElem = element.enclosingElement; |
| 4123 isNative = _isJSNative(classElem); | 4154 isNative = _isJSNative(classElem); |
| 4124 } | 4155 } |
| 4125 var args = _visit(argumentList) as List<JS.Expression>; | 4156 var args = _emitArgumentList(argumentList); |
| 4126 // Native factory constructors are JS constructors - use new here. | 4157 // Native factory constructors are JS constructors - use new here. |
| 4127 return isFactory && !isNative | 4158 return isFactory && !isNative |
| 4128 ? new JS.Call(ctor, args) | 4159 ? new JS.Call(ctor, args) |
| 4129 : new JS.New(ctor, args); | 4160 : new JS.New(ctor, args); |
| 4130 } | 4161 } |
| 4131 | 4162 |
| 4132 if (element != null && _isObjectLiteral(element.enclosingElement)) { | 4163 if (element != null && _isObjectLiteral(element.enclosingElement)) { |
| 4133 return _emitObjectLiteral(argumentList); | 4164 return _emitObjectLiteral(argumentList); |
| 4134 } | 4165 } |
| 4135 if (isConst) return _emitConst(emitNew); | 4166 if (isConst) return _emitConst(emitNew); |
| 4136 return emitNew(); | 4167 return emitNew(); |
| 4137 } | 4168 } |
| 4138 | 4169 |
| 4139 bool _isObjectLiteral(ClassElement classElem) { | 4170 bool _isObjectLiteral(ClassElement classElem) { |
| 4140 return findAnnotation(classElem, isPublicJSAnnotation) != null && | 4171 return findAnnotation(classElem, isPublicJSAnnotation) != null && |
| 4141 findAnnotation(classElem, isJSAnonymousAnnotation) != null; | 4172 findAnnotation(classElem, isJSAnonymousAnnotation) != null; |
| 4142 } | 4173 } |
| 4143 | 4174 |
| 4144 bool _isJSNative(ClassElement classElem) => | 4175 bool _isJSNative(ClassElement classElem) => |
| 4145 findAnnotation(classElem, isPublicJSAnnotation) != null; | 4176 findAnnotation(classElem, isPublicJSAnnotation) != null; |
| 4146 | 4177 |
| 4147 JS.Expression _emitObjectLiteral(ArgumentList argumentList) { | 4178 JS.Expression _emitObjectLiteral(ArgumentList argumentList) { |
| 4148 var args = _visit(argumentList) as List<JS.Expression>; | 4179 var args = _emitArgumentList(argumentList); |
| 4149 if (args.isEmpty) { | 4180 if (args.isEmpty) { |
| 4150 return js.call('{}'); | 4181 return js.call('{}'); |
| 4151 } | 4182 } |
| 4152 assert(args.single is JS.ObjectInitializer); | 4183 assert(args.single is JS.ObjectInitializer); |
| 4153 return args.single; | 4184 return args.single; |
| 4154 } | 4185 } |
| 4155 | 4186 |
| 4156 @override | 4187 @override |
| 4157 visitInstanceCreationExpression(InstanceCreationExpression node) { | 4188 visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 4158 var element = resolutionMap.staticElementForConstructorReference(node); | 4189 var element = resolutionMap.staticElementForConstructorReference(node); |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4735 var operatorName = op.lexeme; | 4766 var operatorName = op.lexeme; |
| 4736 // Use the name from the Dart spec. | 4767 // Use the name from the Dart spec. |
| 4737 if (operatorName == '-') operatorName = 'unary-'; | 4768 if (operatorName == '-') operatorName = 'unary-'; |
| 4738 return _emitSend(expr, operatorName, []); | 4769 return _emitSend(expr, operatorName, []); |
| 4739 } | 4770 } |
| 4740 | 4771 |
| 4741 // Cascades can contain [IndexExpression], [MethodInvocation] and | 4772 // Cascades can contain [IndexExpression], [MethodInvocation] and |
| 4742 // [PropertyAccess]. The code generation for those is handled in their | 4773 // [PropertyAccess]. The code generation for those is handled in their |
| 4743 // respective visit methods. | 4774 // respective visit methods. |
| 4744 @override | 4775 @override |
| 4745 JS.Node visitCascadeExpression(CascadeExpression node) { | 4776 visitCascadeExpression(CascadeExpression node) { |
| 4746 var savedCascadeTemp = _cascadeTarget; | 4777 var savedCascadeTemp = _cascadeTarget; |
| 4747 | 4778 |
| 4748 var vars = <JS.MetaLetVariable, JS.Expression>{}; | 4779 var vars = <JS.MetaLetVariable, JS.Expression>{}; |
| 4749 _cascadeTarget = _bindValue(vars, '_', node.target, context: node); | 4780 _cascadeTarget = _bindValue(vars, '_', node.target, context: node); |
| 4750 var sections = _visitList(node.cascadeSections) as List<JS.Expression>; | 4781 var sections = _visitList(node.cascadeSections) as List<JS.Expression>; |
| 4751 sections.add(_visit(_cascadeTarget)); | 4782 sections.add(_visit(_cascadeTarget)); |
| 4752 var result = new JS.MetaLet(vars, sections, statelessResult: true); | 4783 var result = new JS.MetaLet(vars, sections, statelessResult: true); |
| 4753 _cascadeTarget = savedCascadeTemp; | 4784 _cascadeTarget = savedCascadeTemp; |
| 4754 return result; | 4785 return result; |
| 4755 } | 4786 } |
| 4756 | 4787 |
| 4757 @override | 4788 @override |
| 4758 visitParenthesizedExpression(ParenthesizedExpression node) => | 4789 visitParenthesizedExpression(ParenthesizedExpression node) => |
| 4759 // The printer handles precedence so we don't need to. | 4790 // The printer handles precedence so we don't need to. |
| 4760 _visit(node.expression); | 4791 _visit(node.expression); |
| 4761 | 4792 |
| 4762 @override | 4793 @override |
| 4763 visitFormalParameter(FormalParameter node) { | 4794 visitDefaultFormalParameter(DefaultFormalParameter node) { |
| 4795 return _emitParameter(node.element, declaration: true); | |
| 4796 } | |
| 4797 | |
| 4798 JS.Parameter _emitNormalFormalParameter(NormalFormalParameter node) { | |
| 4764 var id = _emitParameter(node.element, declaration: true); | 4799 var id = _emitParameter(node.element, declaration: true); |
| 4765 var isRestArg = findAnnotation(node.element, isJsRestAnnotation) != null; | 4800 var isRestArg = findAnnotation(node.element, isJsRestAnnotation) != null; |
| 4766 return isRestArg ? new JS.RestParameter(id) : id; | 4801 return isRestArg ? new JS.RestParameter(id) : id; |
| 4767 } | 4802 } |
| 4768 | 4803 |
| 4769 @override | 4804 @override |
| 4805 visitSimpleFormalParameter(SimpleFormalParameter node) => | |
| 4806 _emitNormalFormalParameter(node); | |
| 4807 | |
| 4808 @override | |
| 4809 visitFieldFormalParameter(FieldFormalParameter node) => | |
| 4810 _emitNormalFormalParameter(node); | |
| 4811 | |
| 4812 @override | |
| 4813 visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) => | |
| 4814 _emitNormalFormalParameter(node); | |
| 4815 | |
| 4816 @override | |
| 4770 JS.This visitThisExpression(ThisExpression node) => new JS.This(); | 4817 JS.This visitThisExpression(ThisExpression node) => new JS.This(); |
| 4771 | 4818 |
| 4772 @override | 4819 @override |
| 4773 JS.Super visitSuperExpression(SuperExpression node) => new JS.Super(); | 4820 JS.Super visitSuperExpression(SuperExpression node) => new JS.Super(); |
| 4774 | 4821 |
| 4775 @override | 4822 @override |
| 4776 visitPrefixedIdentifier(PrefixedIdentifier node) { | 4823 visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 4777 if (_isDeferredLoadLibrary(node.prefix, node.identifier)) { | 4824 if (_isDeferredLoadLibrary(node.prefix, node.identifier)) { |
| 4778 // We are tearing off "loadLibrary" on a library prefix. | 4825 // We are tearing off "loadLibrary" on a library prefix. |
| 4779 return _callHelper('loadLibrary'); | 4826 return _callHelper('loadLibrary'); |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5407 @override | 5454 @override |
| 5408 JS.LiteralString visitSimpleStringLiteral(SimpleStringLiteral node) => | 5455 JS.LiteralString visitSimpleStringLiteral(SimpleStringLiteral node) => |
| 5409 js.escapedString(node.value, node.isSingleQuoted ? "'" : '"'); | 5456 js.escapedString(node.value, node.isSingleQuoted ? "'" : '"'); |
| 5410 | 5457 |
| 5411 @override | 5458 @override |
| 5412 JS.Expression visitAdjacentStrings(AdjacentStrings node) => | 5459 JS.Expression visitAdjacentStrings(AdjacentStrings node) => |
| 5413 _visitListToBinary(node.strings, '+'); | 5460 _visitListToBinary(node.strings, '+'); |
| 5414 | 5461 |
| 5415 @override | 5462 @override |
| 5416 JS.Expression visitStringInterpolation(StringInterpolation node) { | 5463 JS.Expression visitStringInterpolation(StringInterpolation node) { |
| 5464 var strings = <String>[]; | |
| 5465 var interpolations = <JS.Expression>[]; | |
| 5466 | |
| 5467 var expectString = true; | |
| 5468 for (var e in node.elements) { | |
| 5469 if (e is InterpolationString) { | |
| 5470 assert(expectString); | |
| 5471 expectString = false; | |
| 5472 | |
| 5473 // Escape the string as necessary for use in the eventual `` quotes. | |
| 5474 // TODO(jmesserly): this call adds quotes, and then we strip them off. | |
| 5475 var str = js.escapedString(e.value, '`').value; | |
| 5476 strings.add(str.substring(1, str.length - 1)); | |
| 5477 } else { | |
| 5478 assert(!expectString); | |
| 5479 expectString = true; | |
| 5480 interpolations.add(_visit(e)); | |
| 5481 } | |
| 5482 } | |
| 5417 return new JS.TaggedTemplate( | 5483 return new JS.TaggedTemplate( |
| 5418 _callHelper('str'), new JS.TemplateString(_visitList(node.elements))); | 5484 _callHelper('str'), new JS.TemplateString(strings, interpolations)); |
| 5419 } | 5485 } |
| 5420 | 5486 |
| 5421 @override | 5487 @override |
| 5422 String visitInterpolationString(InterpolationString node) { | |
| 5423 // TODO(jmesserly): this call adds quotes, and then we strip them off. | |
| 5424 var str = js.escapedString(node.value, '`').value; | |
| 5425 return str.substring(1, str.length - 1); | |
| 5426 } | |
| 5427 | |
| 5428 @override | |
| 5429 visitInterpolationExpression(InterpolationExpression node) => | 5488 visitInterpolationExpression(InterpolationExpression node) => |
| 5430 _visit(node.expression); | 5489 _visit(node.expression); |
| 5431 | 5490 |
| 5432 @override | 5491 @override |
| 5433 visitBooleanLiteral(BooleanLiteral node) => js.boolean(node.value); | 5492 visitBooleanLiteral(BooleanLiteral node) => js.boolean(node.value); |
| 5434 | 5493 |
| 5435 @override | 5494 T _visit<T extends JS.Node>(AstNode node) { |
| 5436 JS.Expression visitExpression(Expression node) => | |
| 5437 _unimplementedCall('Unimplemented ${node.runtimeType}: $node'); | |
| 5438 | |
| 5439 JS.Expression _unimplementedCall(String comment) { | |
| 5440 return _callHelper('throw(#)', [js.escapedString(comment)]); | |
| 5441 } | |
| 5442 | |
| 5443 @override | |
| 5444 visitNode(AstNode node) { | |
| 5445 // TODO(jmesserly): verify this is unreachable. | |
| 5446 throw 'Unimplemented ${node.runtimeType}: $node'; | |
| 5447 } | |
| 5448 | |
| 5449 _visit(AstNode node) { | |
| 5450 if (node == null) return null; | 5495 if (node == null) return null; |
| 5451 var result = node.accept(this); | 5496 var result = node.accept(this); |
| 5452 return result is JS.Node ? annotate(result, node) : result; | 5497 return result != null ? annotate(result, node) : null; |
| 5453 } | 5498 } |
| 5454 | 5499 |
| 5455 // TODO(jmesserly): we should make sure this only returns JS AST nodes. | 5500 // TODO(jmesserly): we should make sure this only returns JS AST nodes. |
| 5456 List/*<R>*/ _visitList/*<T extends AstNode, R>*/(Iterable/*<T>*/ nodes) { | 5501 List/*<R>*/ _visitList/*<T extends AstNode, R>*/(Iterable/*<T>*/ nodes) { |
| 5457 if (nodes == null) return null; | 5502 if (nodes == null) return null; |
| 5458 var result = /*<R>*/ []; | 5503 var result = /*<R>*/ []; |
| 5459 for (var node in nodes) result.add(_visit(node) as dynamic/*=R*/); | 5504 for (var node in nodes) result.add(_visit(node) as dynamic/*=R*/); |
| 5460 return result; | 5505 return result; |
| 5461 } | 5506 } |
| 5462 | 5507 |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5603 useExtension = baseType is InterfaceType && | 5648 useExtension = baseType is InterfaceType && |
| 5604 _isSymbolizedMember(baseType, name, alwaysSymbolizeNative); | 5649 _isSymbolizedMember(baseType, name, alwaysSymbolizeNative); |
| 5605 } | 5650 } |
| 5606 | 5651 |
| 5607 return useExtension | 5652 return useExtension |
| 5608 ? js.call('#.#', [_extensionSymbolsModule, result]) | 5653 ? js.call('#.#', [_extensionSymbolsModule, result]) |
| 5609 : result; | 5654 : result; |
| 5610 } | 5655 } |
| 5611 | 5656 |
| 5612 var _forwardingCache = new HashMap<Element, Map<String, ExecutableElement>>(); | 5657 var _forwardingCache = new HashMap<Element, Map<String, ExecutableElement>>(); |
| 5658 | |
| 5613 Element _lookupForwardedMember(ClassElement element, String name) { | 5659 Element _lookupForwardedMember(ClassElement element, String name) { |
| 5614 // We only care about public methods. | 5660 // We only care about public methods. |
| 5615 if (name.startsWith('_')) return null; | 5661 if (name.startsWith('_')) return null; |
| 5616 | 5662 |
| 5617 var map = _forwardingCache.putIfAbsent(element, () => {}); | 5663 var map = _forwardingCache.putIfAbsent(element, () => {}); |
| 5618 if (map.containsKey(name)) return map[name]; | 5664 if (map.containsKey(name)) return map[name]; |
| 5619 | 5665 |
| 5620 // Note, for a public member, the library should not matter. | 5666 // Note, for a public member, the library should not matter. |
| 5621 var library = element.library; | 5667 var library = element.library; |
| 5622 var member = element.lookUpMethod(name, library) ?? | 5668 var member = element.lookUpMethod(name, library) ?? |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5830 return whitelisted.contains(name); | 5876 return whitelisted.contains(name); |
| 5831 } | 5877 } |
| 5832 } | 5878 } |
| 5833 | 5879 |
| 5834 // Dynamic calls are less risky so there is no need to whitelist at the | 5880 // Dynamic calls are less risky so there is no need to whitelist at the |
| 5835 // method level. | 5881 // method level. |
| 5836 if (isCall && _uncheckedWhitelistCalls.contains(filename)) return true; | 5882 if (isCall && _uncheckedWhitelistCalls.contains(filename)) return true; |
| 5837 | 5883 |
| 5838 return path.endsWith(".template.dart"); | 5884 return path.endsWith(".template.dart"); |
| 5839 } | 5885 } |
| 5886 | |
| 5887 _unreachable(AstNode node) { | |
| 5888 throw new UnsupportedError( | |
| 5889 'tried to generate an unreachable node: `$node`'); | |
| 5890 } | |
| 5891 | |
| 5892 /// Unused, see methods for emitting declarations. | |
| 5893 @override | |
| 5894 visitAnnotation(node) => _unreachable(node); | |
| 5895 | |
| 5896 /// Unused, see [_emitFieldInitializers]. | |
| 5897 @override | |
| 5898 visitAssertInitializer(node) => _unreachable(node); | |
| 5899 | |
| 5900 /// Not visited, but maybe they should be? | |
| 5901 /// See <https://github.com/dart-lang/sdk/issues/29347> | |
| 5902 @override | |
| 5903 visitComment(node) => _unreachable(node); | |
| 5904 | |
| 5905 /// Not visited, but maybe they should be? | |
| 5906 /// See <https://github.com/dart-lang/sdk/issues/29347> | |
| 5907 @override | |
| 5908 visitCommentReference(node) => _unreachable(node); | |
| 5909 | |
| 5910 /// Unused, handled by imports/exports. | |
| 5911 @override | |
| 5912 visitConfiguration(node) => _unreachable(node); | |
| 5913 | |
| 5914 /// Unusued, see [_emitConstructor]. | |
| 5915 @override | |
| 5916 visitConstructorDeclaration(node) => _unreachable(node); | |
| 5917 | |
| 5918 /// Unusued, see [_emitFieldInitializers]. | |
| 5919 @override | |
| 5920 visitConstructorFieldInitializer(node) => _unreachable(node); | |
| 5921 | |
| 5922 /// Unusued. Handled in [visitForEachStatement]. | |
| 5923 @override | |
| 5924 visitDeclaredIdentifier(node) => _unreachable(node); | |
| 5925 | |
| 5926 /// Unused, handled by imports/exports. | |
| 5927 @override | |
| 5928 visitDottedName(node) => _unreachable(node); | |
| 5929 | |
| 5930 /// Unused, handled by [visitEnumDeclaration]. | |
| 5931 @override | |
| 5932 visitEnumConstantDeclaration(node) => _unreachable(node); // see | |
| 5933 | |
| 5934 /// Unused, see [_emitClassHeritage]. | |
| 5935 @override | |
| 5936 visitExtendsClause(node) => _unreachable(node); | |
| 5937 | |
| 5938 /// Unused, see [_emitFormalParameterList]. | |
| 5939 @override | |
| 5940 visitFormalParameterList(node) => _unreachable(node); | |
| 5941 | |
| 5942 /// Unused, handled by imports/exports. | |
| 5943 @override | |
| 5944 visitShowCombinator(node) => _unreachable(node); | |
| 5945 | |
| 5946 /// Unused, handled by imports/exports. | |
| 5947 @override | |
| 5948 visitHideCombinator(node) => _unreachable(node); | |
| 5949 | |
| 5950 /// Unused, see [_emitClassHeritage]. | |
| 5951 @override | |
| 5952 visitImplementsClause(node) => _unreachable(node); | |
| 5953 | |
| 5954 /// Unused, handled by [visitStringInterpolation]. | |
| 5955 @override | |
| 5956 visitInterpolationString(node) => _unreachable(node); | |
| 5957 | |
| 5958 /// Unused, labels are handled by containing statements. | |
| 5959 @override | |
| 5960 visitLabel(node) => _unreachable(node); | |
| 5961 | |
| 5962 /// Unused, handled by imports/exports. | |
| 5963 @override | |
| 5964 visitLibraryIdentifier(node) => _unreachable(node); | |
| 5965 | |
| 5966 /// Unused, see [visitMapLiteral]. | |
| 5967 @override | |
| 5968 visitMapLiteralEntry(node) => _unreachable(node); | |
| 5969 | |
| 5970 /// Unused, see [_emitMethodDeclaration]. | |
| 5971 @override | |
| 5972 visitMethodDeclaration(node) => _unreachable(node); | |
| 5973 | |
| 5974 /// Unused, these are not visited. | |
| 5975 @override | |
| 5976 visitNativeClause(node) => _unreachable(node); | |
| 5977 | |
| 5978 /// Unused, these are not visited. | |
| 5979 @override | |
| 5980 visitNativeFunctionBody(node) => _unreachable(node); | |
| 5981 | |
| 5982 /// Unused, handled by [_emitConstructor]. | |
| 5983 @override | |
| 5984 visitSuperConstructorInvocation(node) => _unreachable(node); | |
| 5985 | |
| 5986 /// Unused, this can be handled when emitting the module if needed. | |
| 5987 @override | |
| 5988 visitScriptTag(node) => _unreachable(node); | |
| 5989 | |
| 5990 /// Unused, see [_emitType]. | |
| 5991 @override | |
| 5992 visitTypeArgumentList(node) => _unreachable(node); | |
| 5993 | |
| 5994 /// Unused, see [_emitType]. | |
| 5995 @override | |
| 5996 visitTypeParameter(node) => _unreachable(node); | |
| 5997 | |
| 5998 /// Unused, see [_emitType]. | |
| 5999 @override | |
| 6000 visitGenericFunctionType(node) => _unreachable(node); | |
| 6001 | |
| 6002 /// Unused, see [_emitType]. | |
| 6003 @override | |
| 6004 visitTypeParameterList(node) => _unreachable(node); | |
| 6005 | |
| 6006 /// Unused, see [_emitClassHeritage]. | |
| 6007 @override | |
| 6008 visitWithClause(node) => _unreachable(node); | |
| 5840 } | 6009 } |
| 5841 | 6010 |
| 5842 /// Choose a canonical name from the [library] element. | 6011 /// Choose a canonical name from the [library] element. |
| 5843 /// | 6012 /// |
| 5844 /// This never uses the library's name (the identifier in the `library` | 6013 /// This never uses the library's name (the identifier in the `library` |
| 5845 /// declaration) as it doesn't have any meaningful rules enforced. | 6014 /// declaration) as it doesn't have any meaningful rules enforced. |
| 5846 String jsLibraryName(String libraryRoot, LibraryElement library) { | 6015 String jsLibraryName(String libraryRoot, LibraryElement library) { |
| 5847 var uri = library.source.uri; | 6016 var uri = library.source.uri; |
| 5848 if (uri.scheme == 'dart') { | 6017 if (uri.scheme == 'dart') { |
| 5849 return uri.path; | 6018 return uri.path; |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5950 if (targetIdentifier.staticElement is! PrefixElement) return false; | 6119 if (targetIdentifier.staticElement is! PrefixElement) return false; |
| 5951 var prefix = targetIdentifier.staticElement as PrefixElement; | 6120 var prefix = targetIdentifier.staticElement as PrefixElement; |
| 5952 | 6121 |
| 5953 // The library the prefix is referring to must come from a deferred import. | 6122 // The library the prefix is referring to must come from a deferred import. |
| 5954 var containingLibrary = resolutionMap | 6123 var containingLibrary = resolutionMap |
| 5955 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) | 6124 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) |
| 5956 .library; | 6125 .library; |
| 5957 var imports = containingLibrary.getImportsWithPrefix(prefix); | 6126 var imports = containingLibrary.getImportsWithPrefix(prefix); |
| 5958 return imports.length == 1 && imports[0].isDeferred; | 6127 return imports.length == 1 && imports[0].isDeferred; |
| 5959 } | 6128 } |
| OLD | NEW |