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

Side by Side Diff: pkg/dev_compiler/lib/src/compiler/code_generator.dart

Issue 2611423002: Fix type error in js_dart2js.dart caught by DDC. (Closed)
Patch Set: Fix noSuchMethod handling of methods that are also extension methods. Fix noSuchMethod handling of … Created 3 years, 11 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
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 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 1487 matching lines...) Expand 10 before | Expand all | Expand 10 after
1498 } else if (property.isSetter) { 1498 } else if (property.isSetter) {
1499 addProperty('isSetter', js.boolean(true)); 1499 addProperty('isSetter', js.boolean(true));
1500 1500
1501 fnArgs.add(args); 1501 fnArgs.add(args);
1502 positionalArgs = new JS.ArrayInitializer([args]); 1502 positionalArgs = new JS.ArrayInitializer([args]);
1503 } 1503 }
1504 } 1504 }
1505 1505
1506 var fnBody = js.call('this.noSuchMethod(new #.InvocationImpl(#, #, #))', [ 1506 var fnBody = js.call('this.noSuchMethod(new #.InvocationImpl(#, #, #))', [
1507 _runtimeModule, 1507 _runtimeModule,
1508 _declareMemberName(method), 1508 _declareMemberName(method, useDisplayName: true),
1509 positionalArgs, 1509 positionalArgs,
1510 new JS.ObjectInitializer(invocationProps) 1510 new JS.ObjectInitializer(invocationProps)
1511 ]); 1511 ]);
1512 1512
1513 if (!method.returnType.isDynamic) { 1513 if (!method.returnType.isDynamic) {
1514 fnBody = js.call('#._check(#)', [_emitType(method.returnType), fnBody]); 1514 fnBody = js.call('#._check(#)', [_emitType(method.returnType), fnBody]);
1515 } 1515 }
1516 1516
1517 var fn = new JS.Fun(fnArgs, js.statement('{ return #; }', [fnBody]), 1517 var fn = new JS.Fun(fnArgs, js.statement('{ return #; }', [fnBody]),
1518 typeParams: _emitTypeFormals(method.type.typeFormals)); 1518 typeParams: _emitTypeFormals(method.type.typeFormals));
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
1932 } 1932 }
1933 } 1933 }
1934 if (dartxNames.isNotEmpty) { 1934 if (dartxNames.isNotEmpty) {
1935 body.add(_callHelperStatement('defineExtensionNames(#)', 1935 body.add(_callHelperStatement('defineExtensionNames(#)',
1936 [new JS.ArrayInitializer(dartxNames, multiline: true)])); 1936 [new JS.ArrayInitializer(dartxNames, multiline: true)]));
1937 } 1937 }
1938 } 1938 }
1939 } 1939 }
1940 1940
1941 List<ExecutableElement> _extensionsToImplement(ClassElement element) { 1941 List<ExecutableElement> _extensionsToImplement(ClassElement element) {
1942 var members = <ExecutableElement>[]; 1942 if (_extensionTypes.isNativeClass(element)) return [];
1943 if (_extensionTypes.isNativeClass(element)) return members;
1944 1943
1945 // Collect all extension types we implement. 1944 // Collect all extension types we implement.
1946 var type = element.type; 1945 var type = element.type;
1947 var types = _extensionTypes.collectNativeInterfaces(element); 1946 var types = _extensionTypes.collectNativeInterfaces(element);
1948 if (types.isEmpty) return members; 1947 if (types.isEmpty) return [];
1949 1948
1949 var members = new Set<ExecutableElement>();
1950 // Collect all possible extension method names. 1950 // Collect all possible extension method names.
1951 var extensionMembers = new HashSet<String>(); 1951 var extensionMembers = new HashSet<String>();
1952 for (var t in types) { 1952 for (var t in types) {
1953 for (var m in [t.methods, t.accessors].expand((e) => e)) { 1953 for (var m in [t.methods, t.accessors].expand((e) => e)) {
1954 if (!m.isStatic && m.isPublic) extensionMembers.add(m.name); 1954 if (!m.isStatic && m.isPublic) extensionMembers.add(m.name);
1955 } 1955 }
1956 } 1956 }
1957 1957
1958 // Collect all of extension methods this type implements. 1958 // Collect all of extension methods this type implements.
1959 for (var m in [type.methods, type.accessors].expand((e) => e)) { 1959 for (var m in [type.methods, type.accessors].expand((e) => e)) {
1960 if (!m.isStatic && !m.isAbstract && extensionMembers.contains(m.name)) { 1960 if (!m.isStatic && !m.isAbstract && extensionMembers.contains(m.name)) {
1961 members.add(m); 1961 members.add(m);
1962 } 1962 }
1963 } 1963 }
1964 return members; 1964 members.addAll(_collectMockMethods(type)
1965 .where((m) => extensionMembers.contains(m.name)));
1966 return members.toList();
1965 } 1967 }
1966 1968
1967 /// Generates the implicit default constructor for class C of the form 1969 /// Generates the implicit default constructor for class C of the form
1968 /// `C() : super() {}`. 1970 /// `C() : super() {}`.
1969 JS.Method _emitImplicitConstructor( 1971 JS.Method _emitImplicitConstructor(
1970 ClassDeclaration node, 1972 ClassDeclaration node,
1971 List<FieldDeclaration> fields, 1973 List<FieldDeclaration> fields,
1972 Map<FieldElement, JS.TemporaryId> virtualFields) { 1974 Map<FieldElement, JS.TemporaryId> virtualFields) {
1973 // If we don't have a method body, skip this. 1975 // If we don't have a method body, skip this.
1974 var superCall = _superConstructorCall(node.element); 1976 var superCall = _superConstructorCall(node.element);
(...skipping 3481 matching lines...) Expand 10 before | Expand all | Expand 10 after
5456 } 5458 }
5457 JS.Expression result = _visit(node); 5459 JS.Expression result = _visit(node);
5458 if (isNullable(node)) result = _callHelper('test(#)', result); 5460 if (isNullable(node)) result = _callHelper('test(#)', result);
5459 return result; 5461 return result;
5460 } 5462 }
5461 5463
5462 /// Like [_emitMemberName], but for declaration sites. 5464 /// Like [_emitMemberName], but for declaration sites.
5463 /// 5465 ///
5464 /// Unlike call sites, we always have an element available, so we can use it 5466 /// Unlike call sites, we always have an element available, so we can use it
5465 /// directly rather than computing the relevant options for [_emitMemberName]. 5467 /// directly rather than computing the relevant options for [_emitMemberName].
5466 JS.Expression _declareMemberName(ExecutableElement e, {bool useExtension}) { 5468 JS.Expression _declareMemberName(ExecutableElement e,
5467 String name; 5469 {bool useExtension, useDisplayName = false}) {
5468 if (e is PropertyAccessorElement) { 5470 var name = (e is PropertyAccessorElement) ? e.variable.name : e.name;
5469 name = e.variable.name;
5470 } else {
5471 name = e.name;
5472 }
5473 return _emitMemberName(name, 5471 return _emitMemberName(name,
5474 isStatic: e.isStatic, 5472 isStatic: e.isStatic,
5475 useExtension: 5473 useExtension:
5476 useExtension ?? _extensionTypes.isNativeClass(e.enclosingElement)); 5474 useExtension ?? _extensionTypes.isNativeClass(e.enclosingElement),
5475 useDisplayName: useDisplayName);
5477 } 5476 }
5478 5477
5479 /// This handles member renaming for private names and operators. 5478 /// This handles member renaming for private names and operators.
5480 /// 5479 ///
5481 /// Private names are generated using ES6 symbols: 5480 /// Private names are generated using ES6 symbols:
5482 /// 5481 ///
5483 /// // At the top of the module: 5482 /// // At the top of the module:
5484 /// let _x = Symbol('_x'); 5483 /// let _x = Symbol('_x');
5485 /// let _y = Symbol('_y'); 5484 /// let _y = Symbol('_y');
5486 /// ... 5485 /// ...
(...skipping 26 matching lines...) Expand all
5513 /// 5512 ///
5514 /// Unary minus looks like: `x._negate()`. 5513 /// Unary minus looks like: `x._negate()`.
5515 /// 5514 ///
5516 /// Equality is a bit special, it is generated via the Dart `equals` runtime 5515 /// Equality is a bit special, it is generated via the Dart `equals` runtime
5517 /// helper, that checks for null. The user defined method is called '=='. 5516 /// helper, that checks for null. The user defined method is called '=='.
5518 /// 5517 ///
5519 JS.Expression _emitMemberName(String name, 5518 JS.Expression _emitMemberName(String name,
5520 {DartType type, 5519 {DartType type,
5521 bool isStatic: false, 5520 bool isStatic: false,
5522 bool useExtension, 5521 bool useExtension,
5522 bool useDisplayName: false,
5523 Element element}) { 5523 Element element}) {
5524 // Static members skip the rename steps and may require JS interop renames. 5524 // Static members skip the rename steps and may require JS interop renames.
5525 if (isStatic) { 5525 if (isStatic) {
5526 return _emitJSInteropStaticMemberName(element) ?? _propertyName(name); 5526 return _emitJSInteropStaticMemberName(element) ?? _propertyName(name);
5527 } 5527 }
5528 5528
5529 if (name.startsWith('_')) { 5529 if (name.startsWith('_')) {
5530 return _emitPrivateNameSymbol(currentLibrary, name); 5530 return _emitPrivateNameSymbol(currentLibrary, name);
5531 } 5531 }
5532 5532
5533 // When generating synthetic names, we use _ as the prefix, since Dart names 5533 // When generating synthetic names, we use _ as the prefix, since Dart names
5534 // won't have this (eliminated above), nor will static names reach here. 5534 // won't have this (eliminated above), nor will static names reach here.
5535 switch (name) { 5535 if (!useDisplayName) {
5536 case '[]': 5536 switch (name) {
5537 name = '_get'; 5537 case '[]':
5538 break; 5538 name = '_get';
5539 case '[]=': 5539 break;
5540 name = '_set'; 5540 case '[]=':
5541 break; 5541 name = '_set';
5542 case 'unary-': 5542 break;
5543 name = '_negate'; 5543 case 'unary-':
5544 break; 5544 name = '_negate';
5545 case 'constructor': 5545 break;
5546 case 'prototype': 5546 case 'constructor':
5547 name = '_$name'; 5547 case 'prototype':
5548 break; 5548 name = '_$name';
5549 break;
5550 }
5549 } 5551 }
5550 5552
5551 var result = _propertyName(name); 5553 var result = _propertyName(name);
5552 5554
5553 if (useExtension == null) { 5555 if (useExtension == null) {
5554 // Dart "extension" methods. Used for JS Array, Boolean, Number, String. 5556 // Dart "extension" methods. Used for JS Array, Boolean, Number, String.
5555 var baseType = type; 5557 var baseType = type;
5556 while (baseType is TypeParameterType) { 5558 while (baseType is TypeParameterType) {
5557 baseType = (baseType.element as TypeParameterElement).bound; 5559 baseType = (baseType.element as TypeParameterElement).bound;
5558 } 5560 }
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
5815 if (targetIdentifier.staticElement is! PrefixElement) return false; 5817 if (targetIdentifier.staticElement is! PrefixElement) return false;
5816 var prefix = targetIdentifier.staticElement as PrefixElement; 5818 var prefix = targetIdentifier.staticElement as PrefixElement;
5817 5819
5818 // The library the prefix is referring to must come from a deferred import. 5820 // The library the prefix is referring to must come from a deferred import.
5819 var containingLibrary = resolutionMap 5821 var containingLibrary = resolutionMap
5820 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) 5822 .elementDeclaredByCompilationUnit(target.root as CompilationUnit)
5821 .library; 5823 .library;
5822 var imports = containingLibrary.getImportsWithPrefix(prefix); 5824 var imports = containingLibrary.getImportsWithPrefix(prefix);
5823 return imports.length == 1 && imports[0].isDeferred; 5825 return imports.length == 1 && imports[0].isDeferred;
5824 } 5826 }
OLDNEW
« no previous file with comments | « pkg/dev_compiler/lib/js/legacy/dart_sdk.js ('k') | pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698