| OLD | NEW |
| 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 import 'package:front_end/src/base/instrumentation.dart'; | 5 import 'package:front_end/src/base/instrumentation.dart'; |
| 6 import 'package:front_end/src/dependency_walker.dart' as dependencyWalker; | 6 import 'package:front_end/src/dependency_walker.dart' as dependencyWalker; |
| 7 import 'package:front_end/src/fasta/errors.dart'; | 7 import 'package:front_end/src/fasta/errors.dart'; |
| 8 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; | 8 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; |
| 9 import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart'
; | 9 import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart'
; |
| 10 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart'; | 10 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart'; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 /// | 46 /// |
| 47 /// Otherwise `null`. | 47 /// Otherwise `null`. |
| 48 AccessorNode currentDependency; | 48 AccessorNode currentDependency; |
| 49 | 49 |
| 50 final overrides = <Member>[]; | 50 final overrides = <Member>[]; |
| 51 | 51 |
| 52 final crossOverrides = <Member>[]; | 52 final crossOverrides = <Member>[]; |
| 53 | 53 |
| 54 AccessorNode(this._typeInferenceEngine, this.member); | 54 AccessorNode(this._typeInferenceEngine, this.member); |
| 55 | 55 |
| 56 get candidateOverrides => overrides.isNotEmpty ? overrides : crossOverrides; | 56 List<Member> get candidateOverrides { |
| 57 if (isTrivialSetter) { |
| 58 return const []; |
| 59 } else if (overrides.isNotEmpty) { |
| 60 return overrides; |
| 61 } else { |
| 62 return crossOverrides; |
| 63 } |
| 64 } |
| 57 | 65 |
| 58 @override | 66 @override |
| 59 bool get isEvaluated => state == InferenceState.Inferred; | 67 bool get isEvaluated => state == InferenceState.Inferred; |
| 60 | 68 |
| 69 /// Indicates whether this accessor is a setter for which the only type we |
| 70 /// have to infer is its return type. |
| 71 bool get isTrivialSetter { |
| 72 var member = this.member; |
| 73 if (member is KernelProcedure && |
| 74 member.isSetter && |
| 75 member.function != null) { |
| 76 var parameters = member.function.positionalParameters; |
| 77 return parameters.length > 0 && |
| 78 !KernelVariableDeclaration.isImplicitlyTyped(parameters[0]); |
| 79 } |
| 80 return false; |
| 81 } |
| 82 |
| 61 @override | 83 @override |
| 62 List<AccessorNode> computeDependencies() { | 84 List<AccessorNode> computeDependencies() { |
| 63 return _typeInferenceEngine.computeAccessorDependencies(this); | 85 return _typeInferenceEngine.computeAccessorDependencies(this); |
| 64 } | 86 } |
| 65 | 87 |
| 66 @override | 88 @override |
| 67 String toString() => member.toString(); | 89 String toString() => member.toString(); |
| 68 } | 90 } |
| 69 | 91 |
| 70 /// Enum tracking the type inference state of an accessor or method. | 92 /// Enum tracking the type inference state of an accessor or method. |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 return const DynamicType(); | 299 return const DynamicType(); |
| 278 } | 300 } |
| 279 } | 301 } |
| 280 | 302 |
| 281 /// Performs type inference on the given [accessorNode]. | 303 /// Performs type inference on the given [accessorNode]. |
| 282 void inferAccessor(AccessorNode accessorNode) { | 304 void inferAccessor(AccessorNode accessorNode) { |
| 283 assert(accessorNode.state == InferenceState.NotInferredYet); | 305 assert(accessorNode.state == InferenceState.NotInferredYet); |
| 284 accessorNode.state = InferenceState.Inferring; | 306 accessorNode.state = InferenceState.Inferring; |
| 285 var member = accessorNode.member; | 307 var member = accessorNode.member; |
| 286 if (strongMode) { | 308 if (strongMode) { |
| 287 var inferredType = tryInferAccessorByInheritance(accessorNode); | |
| 288 var typeInferrer = getMemberTypeInferrer(member); | 309 var typeInferrer = getMemberTypeInferrer(member); |
| 289 if (inferredType == null) { | 310 if (member is KernelProcedure && member.isSetter) { |
| 290 if (member is KernelField) { | 311 KernelProcedure.inferSetterReturnType(member, this, typeInferrer.uri); |
| 291 typeInferrer.isImmediatelyEvident = true; | 312 } |
| 292 inferredType = accessorNode.isImmediatelyEvident | 313 if (!accessorNode.isTrivialSetter) { |
| 293 ? typeInferrer.inferDeclarationType( | 314 var inferredType = tryInferAccessorByInheritance(accessorNode); |
| 294 typeInferrer.inferFieldTopLevel(member, null, true)) | 315 if (inferredType == null) { |
| 295 : const DynamicType(); | 316 if (member is KernelField) { |
| 296 if (!typeInferrer.isImmediatelyEvident) { | 317 typeInferrer.isImmediatelyEvident = true; |
| 318 inferredType = accessorNode.isImmediatelyEvident |
| 319 ? typeInferrer.inferDeclarationType( |
| 320 typeInferrer.inferFieldTopLevel(member, null, true)) |
| 321 : const DynamicType(); |
| 322 if (!typeInferrer.isImmediatelyEvident) { |
| 323 inferredType = const DynamicType(); |
| 324 } |
| 325 } else { |
| 297 inferredType = const DynamicType(); | 326 inferredType = const DynamicType(); |
| 298 } | 327 } |
| 299 } else { | |
| 300 inferredType = const DynamicType(); | |
| 301 } | 328 } |
| 329 if (accessorNode.state == InferenceState.Inferred) { |
| 330 // A circularity must have been detected; at the time it was detected, |
| 331 // inference for this node was completed. |
| 332 return; |
| 333 } |
| 334 member.setInferredType(this, typeInferrer.uri, inferredType); |
| 302 } | 335 } |
| 303 if (accessorNode.state == InferenceState.Inferred) { | |
| 304 // A circularity must have been detected; at the time it was detected, | |
| 305 // inference for this node was completed. | |
| 306 return; | |
| 307 } | |
| 308 member.setInferredType(this, typeInferrer.uri, inferredType); | |
| 309 } | 336 } |
| 310 accessorNode.state = InferenceState.Inferred; | 337 accessorNode.state = InferenceState.Inferred; |
| 311 // TODO(paulberry): if type != null, then check that the type of the | 338 // TODO(paulberry): if type != null, then check that the type of the |
| 312 // initializer is assignable to it. | 339 // initializer is assignable to it. |
| 313 // TODO(paulberry): the following is a hack so that outlines don't contain | 340 // TODO(paulberry): the following is a hack so that outlines don't contain |
| 314 // initializers. But it means that we rebuild the initializers when doing | 341 // initializers. But it means that we rebuild the initializers when doing |
| 315 // a full compile. There should be a better way. | 342 // a full compile. There should be a better way. |
| 316 if (member is KernelField) { | 343 if (member is KernelField) { |
| 317 member.initializer = null; | 344 member.initializer = null; |
| 318 } | 345 } |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 } | 628 } |
| 602 | 629 |
| 603 @override | 630 @override |
| 604 void evaluateScc(List<AccessorNode> scc) { | 631 void evaluateScc(List<AccessorNode> scc) { |
| 605 // Mark every accessor as part of a circularity. | 632 // Mark every accessor as part of a circularity. |
| 606 for (var f in scc) { | 633 for (var f in scc) { |
| 607 f._typeInferenceEngine.inferAccessorCircular(f); | 634 f._typeInferenceEngine.inferAccessorCircular(f); |
| 608 } | 635 } |
| 609 } | 636 } |
| 610 } | 637 } |
| OLD | NEW |