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

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

Issue 2995813002: fix #30423, covariant parameter tearoff type should be Object (Closed)
Patch Set: Created 3 years, 4 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';
11 import 'package:analyzer/dart/ast/standard_ast_factory.dart'; 11 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
12 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; 12 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
13 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; 13 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType;
14 import 'package:analyzer/dart/element/element.dart'; 14 import 'package:analyzer/dart/element/element.dart';
15 import 'package:analyzer/dart/element/type.dart'; 15 import 'package:analyzer/dart/element/type.dart';
16 import 'package:analyzer/src/dart/ast/token.dart' show StringToken; 16 import 'package:analyzer/src/dart/ast/token.dart' show StringToken;
17 import 'package:analyzer/src/dart/element/element.dart' 17 import 'package:analyzer/src/dart/element/element.dart';
18 show FieldElementImpl, LocalVariableElementImpl; 18 import 'package:analyzer/src/dart/element/type.dart';
19 import 'package:analyzer/src/dart/element/type.dart' show DynamicTypeImpl;
20 import 'package:analyzer/src/dart/sdk/sdk.dart'; 19 import 'package:analyzer/src/dart/sdk/sdk.dart';
21 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; 20 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
22 import 'package:analyzer/src/generated/resolver.dart' 21 import 'package:analyzer/src/generated/resolver.dart'
23 show TypeProvider, NamespaceBuilder; 22 show TypeProvider, NamespaceBuilder;
24 import 'package:analyzer/src/generated/type_system.dart' 23 import 'package:analyzer/src/generated/type_system.dart'
25 show StrongTypeSystemImpl; 24 show StrongTypeSystemImpl;
26 import 'package:analyzer/src/summary/idl.dart' show UnlinkedUnit; 25 import 'package:analyzer/src/summary/idl.dart' show UnlinkedUnit;
27 import 'package:analyzer/src/summary/link.dart' as summary_link; 26 import 'package:analyzer/src/summary/link.dart' as summary_link;
28 import 'package:analyzer/src/summary/package_bundle_reader.dart'; 27 import 'package:analyzer/src/summary/package_bundle_reader.dart';
29 import 'package:analyzer/src/summary/summarize_ast.dart' 28 import 'package:analyzer/src/summary/summarize_ast.dart'
(...skipping 1984 matching lines...) Expand 10 before | Expand all | Expand 10 after
2014 elementToType = (ExecutableElement element) => element.type; 2013 elementToType = (ExecutableElement element) => element.type;
2015 getOverride = classElem.lookUpInheritedConcreteGetter; 2014 getOverride = classElem.lookUpInheritedConcreteGetter;
2016 lookup = classElem.type.lookUpInheritedGetter; 2015 lookup = classElem.type.lookUpInheritedGetter;
2017 tMember = node.isStatic ? tStaticGetters : tInstanceGetters; 2016 tMember = node.isStatic ? tStaticGetters : tInstanceGetters;
2018 } else if (node.isSetter) { 2017 } else if (node.isSetter) {
2019 elementToType = (ExecutableElement element) => element.type; 2018 elementToType = (ExecutableElement element) => element.type;
2020 getOverride = classElem.lookUpInheritedConcreteSetter; 2019 getOverride = classElem.lookUpInheritedConcreteSetter;
2021 lookup = classElem.type.lookUpInheritedSetter; 2020 lookup = classElem.type.lookUpInheritedSetter;
2022 tMember = node.isStatic ? tStaticSetters : tInstanceSetters; 2021 tMember = node.isStatic ? tStaticSetters : tInstanceSetters;
2023 } else { 2022 } else {
2024 // Method 2023 // Swap in "Object" for parameter types that are covariant, either via
2025 // Swap in "Object" for parameter types that are covariant overrides. 2024 // the `covariant` keyword or because of covariant generics.
2026 var objectType = context.typeProvider.objectType; 2025 elementToType = _getMemberRuntimeType;
2027 elementToType =
2028 (MethodElement element) => element.getReifiedType(objectType);
2029 getOverride = classElem.lookUpInheritedConcreteMethod; 2026 getOverride = classElem.lookUpInheritedConcreteMethod;
2030 lookup = classElem.type.lookUpInheritedMethod; 2027 lookup = classElem.type.lookUpInheritedMethod;
2031 tMember = node.isStatic ? tStaticMethods : tInstanceMethods; 2028 tMember = node.isStatic ? tStaticMethods : tInstanceMethods;
2032 } 2029 }
2033 2030
2034 DartType reifiedType = elementToType(element); 2031 DartType reifiedType = elementToType(element);
2035 // Don't add redundant signatures for inherited methods whose signature 2032 // Don't add redundant signatures for inherited methods whose signature
2036 // did not change. If we are not overriding, or if the thing we are 2033 // did not change. If we are not overriding, or if the thing we are
2037 // overriding has a different reified type from ourselves, we must 2034 // overriding has a different reified type from ourselves, we must
2038 // emit a signature on this class. Otherwise we will inherit the 2035 // emit a signature on this class. Otherwise we will inherit the
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
2184 return self.call.apply(self, args); 2181 return self.call.apply(self, args);
2185 } 2182 }
2186 self.__proto__ = this.__proto__; 2183 self.__proto__ = this.__proto__;
2187 callableClass.call(self, #); 2184 callableClass.call(self, #);
2188 return self; 2185 return self;
2189 } 2186 }
2190 # 2187 #
2191 }''', [params, params, body]); 2188 }''', [params, params, body]);
2192 } 2189 }
2193 2190
2191 FunctionType _getMemberRuntimeType(ExecutableElement element) {
2192 // Check whether we have any covariant parameters.
2193 // Usually we don't, so we can use the same type.
2194 if (!element.parameters.any(_isCovariant)) return element.type;
2195
2196 var parameters = element.parameters
2197 .map((p) => new ParameterElementImpl.synthetic(p.name,
2198 _isCovariant(p) ? objectClass.type : p.type, p.parameterKind))
2199 .toList();
2200
2201 var function = new FunctionElementImpl("", -1)
2202 ..isSynthetic = true
2203 ..returnType = element.returnType
2204 ..shareTypeParameters(element.typeParameters)
2205 ..parameters = parameters;
2206 return function.type = new FunctionTypeImpl(function);
2207 }
2208
2194 JS.Expression _constructorName(ConstructorElement ctor) { 2209 JS.Expression _constructorName(ConstructorElement ctor) {
2195 var name = ctor.name; 2210 var name = ctor.name;
2196 if (name == '') { 2211 if (name == '') {
2197 // Default constructors (factory or not) use `new` as their name. 2212 // Default constructors (factory or not) use `new` as their name.
2198 return _propertyName('new'); 2213 return _propertyName('new');
2199 } 2214 }
2200 return _emitMemberName(name, isStatic: true); 2215 return _emitMemberName(name, isStatic: true);
2201 } 2216 }
2202 2217
2203 JS.Block _emitConstructorBody(ConstructorDeclaration node, 2218 JS.Block _emitConstructorBody(ConstructorDeclaration node,
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
2379 /// Emits argument initializers, which handles optional/named args, as well 2394 /// Emits argument initializers, which handles optional/named args, as well
2380 /// as generic type checks needed due to our covariance. 2395 /// as generic type checks needed due to our covariance.
2381 JS.Statement _emitArgumentInitializers(node, {bool constructor: false}) { 2396 JS.Statement _emitArgumentInitializers(node, {bool constructor: false}) {
2382 // Constructor argument initializers are emitted earlier in the code, rather 2397 // Constructor argument initializers are emitted earlier in the code, rather
2383 // than always when we visit the function body, so we control it explicitly. 2398 // than always when we visit the function body, so we control it explicitly.
2384 if (node is ConstructorDeclaration != constructor) return null; 2399 if (node is ConstructorDeclaration != constructor) return null;
2385 2400
2386 var parameters = _parametersOf(node); 2401 var parameters = _parametersOf(node);
2387 if (parameters == null) return null; 2402 if (parameters == null) return null;
2388 2403
2389 var covariantParams = _classProperties?.covariantParameters;
2390
2391 var body = <JS.Statement>[]; 2404 var body = <JS.Statement>[];
2392 for (var param in parameters.parameters) { 2405 for (var param in parameters.parameters) {
2393 var jsParam = _emitSimpleIdentifier(param.identifier); 2406 var jsParam = _emitSimpleIdentifier(param.identifier);
2394 2407
2395 if (!options.destructureNamedParams) { 2408 if (!options.destructureNamedParams) {
2396 if (param.kind == ParameterKind.NAMED) { 2409 if (param.kind == ParameterKind.NAMED) {
2397 // Parameters will be passed using their real names, not the (possibly 2410 // Parameters will be passed using their real names, not the (possibly
2398 // renamed) local variable. 2411 // renamed) local variable.
2399 var paramName = js.string(param.identifier.name, "'"); 2412 var paramName = js.string(param.identifier.name, "'");
2400 2413
2401 // TODO(ochafik): Fix `'prop' in obj` to please Closure's renaming. 2414 // TODO(ochafik): Fix `'prop' in obj` to please Closure's renaming.
2402 body.add(js.statement('let # = # && # in # ? #.# : #;', [ 2415 body.add(js.statement('let # = # && # in # ? #.# : #;', [
2403 jsParam, 2416 jsParam,
2404 namedArgumentTemp, 2417 namedArgumentTemp,
2405 paramName, 2418 paramName,
2406 namedArgumentTemp, 2419 namedArgumentTemp,
2407 namedArgumentTemp, 2420 namedArgumentTemp,
2408 paramName, 2421 paramName,
2409 _defaultParamValue(param), 2422 _defaultParamValue(param),
2410 ])); 2423 ]));
2411 } else if (param.kind == ParameterKind.POSITIONAL) { 2424 } else if (param.kind == ParameterKind.POSITIONAL) {
2412 body.add(js.statement('if (# === void 0) # = #;', 2425 body.add(js.statement('if (# === void 0) # = #;',
2413 [jsParam, jsParam, _defaultParamValue(param)])); 2426 [jsParam, jsParam, _defaultParamValue(param)]));
2414 } 2427 }
2415 } 2428 }
2416 2429
2417 var paramElement = resolutionMap.elementDeclaredByFormalParameter(param); 2430 var paramElement = resolutionMap.elementDeclaredByFormalParameter(param);
2418 if (paramElement.isCovariant || 2431 if (_isCovariant(paramElement)) {
2419 covariantParams != null && covariantParams.contains(paramElement)) {
2420 var castType = _emitType(paramElement.type); 2432 var castType = _emitType(paramElement.type);
2421 body.add(js.statement('#._check(#);', [castType, jsParam])); 2433 body.add(js.statement('#._check(#);', [castType, jsParam]));
2422 } 2434 }
2423 } 2435 }
2424 return body.isEmpty ? null : _statement(body); 2436 return body.isEmpty ? null : _statement(body);
2425 } 2437 }
2426 2438
2439 bool _isCovariant(ParameterElement p) {
2440 if (p.isCovariant) return true;
2441 var covariantParams = _classProperties?.covariantParameters;
2442 return covariantParams != null && covariantParams.contains(p);
2443 }
2444
2427 JS.Expression _defaultParamValue(FormalParameter param) { 2445 JS.Expression _defaultParamValue(FormalParameter param) {
2428 if (param is DefaultFormalParameter && param.defaultValue != null) { 2446 if (param is DefaultFormalParameter && param.defaultValue != null) {
2429 return _visit(param.defaultValue); 2447 return _visit(param.defaultValue);
2430 } else { 2448 } else {
2431 return new JS.LiteralNull(); 2449 return new JS.LiteralNull();
2432 } 2450 }
2433 } 2451 }
2434 2452
2435 JS.Fun _emitNativeFunctionBody(MethodDeclaration node) { 2453 JS.Fun _emitNativeFunctionBody(MethodDeclaration node) {
2436 String name = 2454 String name =
(...skipping 3537 matching lines...) Expand 10 before | Expand all | Expand 10 after
5974 if (targetIdentifier.staticElement is! PrefixElement) return false; 5992 if (targetIdentifier.staticElement is! PrefixElement) return false;
5975 var prefix = targetIdentifier.staticElement as PrefixElement; 5993 var prefix = targetIdentifier.staticElement as PrefixElement;
5976 5994
5977 // The library the prefix is referring to must come from a deferred import. 5995 // The library the prefix is referring to must come from a deferred import.
5978 var containingLibrary = resolutionMap 5996 var containingLibrary = resolutionMap
5979 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) 5997 .elementDeclaredByCompilationUnit(target.root as CompilationUnit)
5980 .library; 5998 .library;
5981 var imports = containingLibrary.getImportsWithPrefix(prefix); 5999 var imports = containingLibrary.getImportsWithPrefix(prefix);
5982 return imports.length == 1 && imports[0].isDeferred; 6000 return imports.length == 1 && imports[0].isDeferred;
5983 } 6001 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698