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 1512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1523 addProperty('isSetter', js.boolean(true)); | 1523 addProperty('isSetter', js.boolean(true)); |
1524 | 1524 |
1525 fnArgs.add(args); | 1525 fnArgs.add(args); |
1526 positionalArgs = new JS.ArrayInitializer([args]); | 1526 positionalArgs = new JS.ArrayInitializer([args]); |
1527 } | 1527 } |
1528 } | 1528 } |
1529 | 1529 |
1530 var fnBody = | 1530 var fnBody = |
1531 js.call('this.noSuchMethod(new #.InvocationImpl.new(#, #, #))', [ | 1531 js.call('this.noSuchMethod(new #.InvocationImpl.new(#, #, #))', [ |
1532 _runtimeModule, | 1532 _runtimeModule, |
1533 _declareMemberName(method, useDisplayName: false), | 1533 _declareMemberName(method), |
1534 positionalArgs, | 1534 positionalArgs, |
1535 new JS.ObjectInitializer(invocationProps) | 1535 new JS.ObjectInitializer(invocationProps) |
1536 ]); | 1536 ]); |
1537 | 1537 |
1538 if (!method.returnType.isDynamic) { | 1538 if (!method.returnType.isDynamic) { |
1539 fnBody = js.call('#._check(#)', [_emitType(method.returnType), fnBody]); | 1539 fnBody = js.call('#._check(#)', [_emitType(method.returnType), fnBody]); |
1540 } | 1540 } |
1541 | 1541 |
1542 var fn = _makeGenericFunction(new JS.Fun( | 1542 var fn = _makeGenericFunction(new JS.Fun( |
1543 fnArgs, js.statement('{ return #; }', [fnBody]), | 1543 fnArgs, js.statement('{ return #; }', [fnBody]), |
(...skipping 3782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5326 } | 5326 } |
5327 JS.Expression result = _visit(node); | 5327 JS.Expression result = _visit(node); |
5328 if (isNullable(node)) result = _callHelper('test(#)', result); | 5328 if (isNullable(node)) result = _callHelper('test(#)', result); |
5329 return result; | 5329 return result; |
5330 } | 5330 } |
5331 | 5331 |
5332 /// Like [_emitMemberName], but for declaration sites. | 5332 /// Like [_emitMemberName], but for declaration sites. |
5333 /// | 5333 /// |
5334 /// Unlike call sites, we always have an element available, so we can use it | 5334 /// Unlike call sites, we always have an element available, so we can use it |
5335 /// directly rather than computing the relevant options for [_emitMemberName]. | 5335 /// directly rather than computing the relevant options for [_emitMemberName]. |
5336 JS.Expression _declareMemberName(ExecutableElement e, | 5336 JS.Expression _declareMemberName(ExecutableElement e, {bool useExtension}) { |
5337 {bool useExtension, useDisplayName = false}) { | |
5338 var name = (e is PropertyAccessorElement) ? e.variable.name : e.name; | 5337 var name = (e is PropertyAccessorElement) ? e.variable.name : e.name; |
5339 return _emitMemberName(name, | 5338 return _emitMemberName(name, |
5340 isStatic: e.isStatic, | 5339 isStatic: e.isStatic, |
5341 useExtension: | 5340 useExtension: |
5342 useExtension ?? _extensionTypes.isNativeClass(e.enclosingElement), | 5341 useExtension ?? _extensionTypes.isNativeClass(e.enclosingElement)); |
5343 useDisplayName: useDisplayName); | |
5344 } | 5342 } |
5345 | 5343 |
5346 /// This handles member renaming for private names and operators. | 5344 /// This handles member renaming for private names and operators. |
5347 /// | 5345 /// |
5348 /// Private names are generated using ES6 symbols: | 5346 /// Private names are generated using ES6 symbols: |
5349 /// | 5347 /// |
5350 /// // At the top of the module: | 5348 /// // At the top of the module: |
5351 /// let _x = Symbol('_x'); | 5349 /// let _x = Symbol('_x'); |
5352 /// let _y = Symbol('_y'); | 5350 /// let _y = Symbol('_y'); |
5353 /// ... | 5351 /// ... |
(...skipping 26 matching lines...) Expand all Loading... |
5380 /// | 5378 /// |
5381 /// Unary minus looks like: `x._negate()`. | 5379 /// Unary minus looks like: `x._negate()`. |
5382 /// | 5380 /// |
5383 /// Equality is a bit special, it is generated via the Dart `equals` runtime | 5381 /// Equality is a bit special, it is generated via the Dart `equals` runtime |
5384 /// helper, that checks for null. The user defined method is called '=='. | 5382 /// helper, that checks for null. The user defined method is called '=='. |
5385 /// | 5383 /// |
5386 JS.Expression _emitMemberName(String name, | 5384 JS.Expression _emitMemberName(String name, |
5387 {DartType type, | 5385 {DartType type, |
5388 bool isStatic: false, | 5386 bool isStatic: false, |
5389 bool useExtension, | 5387 bool useExtension, |
5390 bool useDisplayName: false, | |
5391 bool alwaysSymbolizeNative: false, | 5388 bool alwaysSymbolizeNative: false, |
5392 Element element}) { | 5389 Element element}) { |
5393 // Static members skip the rename steps and may require JS interop renames. | 5390 // Static members skip the rename steps and may require JS interop renames. |
5394 if (isStatic) { | 5391 if (isStatic) { |
5395 return _propertyName(_emitJSInteropStaticMemberName(element) ?? name); | 5392 return _propertyName(_emitJSInteropStaticMemberName(element) ?? name); |
5396 } | 5393 } |
5397 | 5394 |
5398 if (name.startsWith('_')) { | 5395 if (name.startsWith('_')) { |
5399 return _emitPrivateNameSymbol(currentLibrary, name); | 5396 return _emitPrivateNameSymbol(currentLibrary, name); |
5400 } | 5397 } |
5401 | 5398 |
5402 // When generating synthetic names, we use _ as the prefix, since Dart names | 5399 // When generating synthetic names, we use _ as the prefix, since Dart names |
5403 // won't have this (eliminated above), nor will static names reach here. | 5400 // won't have this (eliminated above), nor will static names reach here. |
5404 if (!useDisplayName) { | 5401 switch (name) { |
5405 switch (name) { | 5402 case '[]': |
5406 case '[]': | 5403 name = '_get'; |
5407 name = '_get'; | 5404 break; |
5408 break; | 5405 case '[]=': |
5409 case '[]=': | 5406 name = '_set'; |
5410 name = '_set'; | 5407 break; |
5411 break; | 5408 case 'unary-': |
5412 case 'unary-': | 5409 name = '_negate'; |
5413 name = '_negate'; | 5410 break; |
5414 break; | 5411 case 'constructor': |
5415 case 'constructor': | 5412 case 'prototype': |
5416 case 'prototype': | 5413 name = '_$name'; |
5417 name = '_$name'; | 5414 break; |
5418 break; | |
5419 } | |
5420 } | 5415 } |
5421 | 5416 |
5422 var result = _propertyName(name); | 5417 var result = _propertyName(name); |
5423 | 5418 |
5424 if (useExtension == null) { | 5419 if (useExtension == null) { |
5425 // Dart "extension" methods. Used for JS Array, Boolean, Number, String. | 5420 // Dart "extension" methods. Used for JS Array, Boolean, Number, String. |
5426 var baseType = type; | 5421 var baseType = type; |
5427 while (baseType is TypeParameterType) { | 5422 while (baseType is TypeParameterType) { |
5428 baseType = (baseType.element as TypeParameterElement).bound; | 5423 baseType = (baseType.element as TypeParameterElement).bound; |
5429 } | 5424 } |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5836 if (targetIdentifier.staticElement is! PrefixElement) return false; | 5831 if (targetIdentifier.staticElement is! PrefixElement) return false; |
5837 var prefix = targetIdentifier.staticElement as PrefixElement; | 5832 var prefix = targetIdentifier.staticElement as PrefixElement; |
5838 | 5833 |
5839 // The library the prefix is referring to must come from a deferred import. | 5834 // The library the prefix is referring to must come from a deferred import. |
5840 var containingLibrary = resolutionMap | 5835 var containingLibrary = resolutionMap |
5841 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) | 5836 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) |
5842 .library; | 5837 .library; |
5843 var imports = containingLibrary.getImportsWithPrefix(prefix); | 5838 var imports = containingLibrary.getImportsWithPrefix(prefix); |
5844 return imports.length == 1 && imports[0].isDeferred; | 5839 return imports.length == 1 && imports[0].isDeferred; |
5845 } | 5840 } |
OLD | NEW |