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

Unified Diff: pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart

Issue 2999403003: Properly annotate the checks needed when invoking function-typed objects. (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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.strong.expect » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index ad1dc41bf01b76302e11d9ede58eb08958bfef3a..4e7db482776d8a7cc4fe9680529eb45e1f4414ed 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -39,6 +39,7 @@ import 'package:kernel/ast.dart'
SuperMethodInvocation,
SuperPropertyGet,
SuperPropertySet,
+ ThisExpression,
TypeParameter,
TypeParameterType,
VariableDeclaration,
@@ -869,24 +870,49 @@ abstract class TypeInferrerImpl extends TypeInferrer {
if (interfaceMember is Procedure) {
isOverloadedArithmeticOperator = typeSchemaEnvironment
.isOverloadedArithmeticOperatorAndType(interfaceMember, receiverType);
- if (instrumentation != null) {
+ }
+ if (instrumentation != null) {
+ int offset = arguments.fileOffset == -1
+ ? expression.fileOffset
+ : arguments.fileOffset;
+ if (receiver is ThisExpression) {
+ // Calls to `this` are always typed.
+ } else if (interfaceMember == null &&
+ !(receiverType is FunctionType && methodName.name == 'call')) {
+ // Dynamic invocation
+ instrumentation.record(Uri.parse(uri), offset, 'checkCall',
+ new InstrumentationValueLiteral('dynamic'));
+ } else {
var semiTypedArguments = <String>[];
- var function = interfaceMember.function;
- var positionalParameters = function.positionalParameters;
- for (int i = 0; i < positionalParameters.length; i++) {
- if (_isFormalSemiSafe(positionalParameters[i])) {
- semiTypedArguments.add(i.toString());
+ var function = interfaceMember?.function;
+ int i = 0;
+ _forEachArgument(arguments, (name, expression) {
+ bool isSemiTyped;
+ if (function == null) {
+ // Invocation of a function-typed object; everything is semi-typed.
+ isSemiTyped = true;
+ } else {
+ var formal = name != null
+ ? _getNamedFormal(function, name)
+ : _getPositionalFormal(function, i);
+ if (formal != null) {
+ isSemiTyped = _isFormalSemiSafe(formal);
+ } else {
+ // No matching formal parameter. An error should have already been
+ // reported, so the code won't compile. Thus, it doesn't really
+ // matter how we annotate the parameter.
+ isSemiTyped = false;
+ }
}
- }
- for (var formal in function.namedParameters) {
- if (_isFormalSemiSafe(formal)) {
- semiTypedArguments.add(formal.name);
+ if (isSemiTyped) {
+ semiTypedArguments.add(name ?? i.toString());
}
- }
+ if (name == null) i++;
+ });
if (semiTypedArguments.isNotEmpty) {
instrumentation.record(
Uri.parse(uri),
- arguments.fileOffset,
+ offset,
'checkCall',
new InstrumentationValueLiteral(
'interface(semiTyped:${semiTypedArguments.join(',')})'));
@@ -1083,6 +1109,25 @@ abstract class TypeInferrerImpl extends TypeInferrer {
}
}
+ /// Given a [FunctionNode], gets the named parameter identified by [name], or
+ /// `null` if there is no parameter with the given name.
+ VariableDeclaration _getNamedFormal(FunctionNode function, String name) {
+ for (var formal in function.namedParameters) {
+ if (formal.name == name) return formal;
+ }
+ return null;
+ }
+
+ /// Given a [FunctionNode], gets the [i]th positional formal parameter, or
+ /// `null` if there is no parameter with that index.
+ VariableDeclaration _getPositionalFormal(FunctionNode function, int i) {
+ if (i < function.positionalParameters.length) {
+ return function.positionalParameters[i];
+ } else {
+ return null;
+ }
+ }
+
/// Determines if the given formal parameter is semi-safe.
///
/// Eventually this information will be stored in the kernel representation,
« no previous file with comments | « no previous file | pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.strong.expect » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698