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

Side by Side Diff: pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart

Issue 2907643003: Correctly infer the return context while compiling a factory constructor. (Closed)
Patch Set: Created 3 years, 6 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) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// This file declares a "shadow hierarchy" of concrete classes which extend 5 /// This file declares a "shadow hierarchy" of concrete classes which extend
6 /// the kernel class hierarchy, adding methods and fields needed by the 6 /// the kernel class hierarchy, adding methods and fields needed by the
7 /// BodyBuilder. 7 /// BodyBuilder.
8 /// 8 ///
9 /// Instances of these classes may be created using the factory methods in 9 /// Instances of these classes may be created using the factory methods in
10 /// `ast_factory.dart`. 10 /// `ast_factory.dart`.
(...skipping 10 matching lines...) Expand all
21 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart'; 21 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
22 import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart' ; 22 import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart' ;
23 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart'; 23 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart';
24 import 'package:front_end/src/fasta/type_inference/type_promotion.dart'; 24 import 'package:front_end/src/fasta/type_inference/type_promotion.dart';
25 import 'package:front_end/src/fasta/type_inference/type_schema.dart'; 25 import 'package:front_end/src/fasta/type_inference/type_schema.dart';
26 import 'package:front_end/src/fasta/type_inference/type_schema_elimination.dart' ; 26 import 'package:front_end/src/fasta/type_inference/type_schema_elimination.dart' ;
27 import 'package:kernel/ast.dart'; 27 import 'package:kernel/ast.dart';
28 import 'package:kernel/frontend/accessors.dart'; 28 import 'package:kernel/frontend/accessors.dart';
29 import 'package:kernel/type_algebra.dart'; 29 import 'package:kernel/type_algebra.dart';
30 30
31 /// Computes the return type of a factory constructor.
32 ///
33 /// Note that we can't just use `constructor.function.functionType.returnType`,
34 /// because that's `dynamic` for factory constructors. TODO(paulberry):
35 /// investigate whether this can be changed.
36 InterfaceType computeFactoryConstructorReturnType(Procedure constructor) {
37 var returnType = constructor.enclosingClass.thisType;
38 if (constructor.enclosingClass.typeParameters.isNotEmpty) {
39 // target.enclosingClass.typeParameters is not the same as
40 // target.function.functionType.typeParameters, so we have to substitute.
41 returnType = Substitution
42 .fromPairs(
43 constructor.enclosingClass.typeParameters,
44 constructor.function.functionType.typeParameters
45 .map((p) => new TypeParameterType(p))
46 .toList())
47 .substituteType(returnType);
48 }
49 return returnType;
50 }
51
31 List<DartType> getExplicitTypeArguments(Arguments arguments) { 52 List<DartType> getExplicitTypeArguments(Arguments arguments) {
32 if (arguments is KernelArguments) { 53 if (arguments is KernelArguments) {
33 return arguments._hasExplicitTypeArguments ? arguments.types : null; 54 return arguments._hasExplicitTypeArguments ? arguments.types : null;
34 } else { 55 } else {
35 // This code path should only be taken in situations where there are no 56 // This code path should only be taken in situations where there are no
36 // type arguments at all, e.g. calling a user-definable operator. 57 // type arguments at all, e.g. calling a user-definable operator.
37 assert(arguments.types.isEmpty); 58 assert(arguments.types.isEmpty);
38 return null; 59 return null;
39 } 60 }
40 } 61 }
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 KernelFactoryConstructorInvocation(Procedure target, Arguments arguments, 370 KernelFactoryConstructorInvocation(Procedure target, Arguments arguments,
350 {bool isConst: false}) 371 {bool isConst: false})
351 : super(target, arguments, isConst: isConst); 372 : super(target, arguments, isConst: isConst);
352 373
353 @override 374 @override
354 DartType _inferExpression( 375 DartType _inferExpression(
355 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { 376 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) {
356 typeNeeded = 377 typeNeeded =
357 inferrer.listener.constructorInvocationEnter(this, typeContext) || 378 inferrer.listener.constructorInvocationEnter(this, typeContext) ||
358 typeNeeded; 379 typeNeeded;
359 var returnType = target.enclosingClass.thisType; 380 InterfaceType returnType = computeFactoryConstructorReturnType(target);
360 if (target.enclosingClass.typeParameters.isNotEmpty) {
361 // target.enclosingClass.typeParameters is not the same as
362 // target.function.functionType.typeParameters, so we have to substitute.
363 // TODO(paulberrry): it would be easier if we could just use
364 // target.function.functionType.returnType, but that's `dynamic` for
365 // factory constructors. Investigate whether this can be changed.
366 returnType = Substitution
367 .fromPairs(
368 target.enclosingClass.typeParameters,
369 target.function.functionType.typeParameters
370 .map((p) => new TypeParameterType(p))
371 .toList())
372 .substituteType(returnType);
373 }
374 var inferredType = inferrer.inferInvocation(typeContext, typeNeeded, 381 var inferredType = inferrer.inferInvocation(typeContext, typeNeeded,
375 fileOffset, target.function.functionType, returnType, arguments); 382 fileOffset, target.function.functionType, returnType, arguments);
376 inferrer.listener.constructorInvocationExit(this, inferredType); 383 inferrer.listener.constructorInvocationExit(this, inferredType);
377 return inferredType; 384 return inferredType;
378 } 385 }
379 } 386 }
380 387
381 /// Concrete shadow object representing a field in kernel form. 388 /// Concrete shadow object representing a field in kernel form.
382 class KernelField extends Field { 389 class KernelField extends Field {
383 bool _implicitlyTyped = true; 390 bool _implicitlyTyped = true;
(...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 closureContext.isAsync 1409 closureContext.isAsync
1403 ? inferrer.coreTypes.streamClass 1410 ? inferrer.coreTypes.streamClass
1404 : inferrer.coreTypes.iterableClass); 1411 : inferrer.coreTypes.iterableClass);
1405 } 1412 }
1406 var inferredType = inferrer.inferExpression( 1413 var inferredType = inferrer.inferExpression(
1407 expression, typeContext, closureContext != null); 1414 expression, typeContext, closureContext != null);
1408 closureContext.handleYield(inferrer, isYieldStar, inferredType); 1415 closureContext.handleYield(inferrer, isYieldStar, inferredType);
1409 inferrer.listener.yieldStatementExit(this); 1416 inferrer.listener.yieldStatementExit(this);
1410 } 1417 }
1411 } 1418 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/kernel/body_builder.dart ('k') | pkg/front_end/test/fasta/strong.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698