Skip to content

Commit

Permalink
[dart2js] Support new method invocation encoding in static type visitor
Browse files Browse the repository at this point in the history
This is the first part of using the new encodings of MethodInvocation,
PropertyGet and PropertySet in dart2js. In this CL the new visitors
are implemented in static_type.dart. This change is done by refactoring
the existing implementation into helpers and new registration methods
that can be used by both the old and the new encoding but lends itself
to take advance of the new encoding. The new encoding is not enabled
until all of dart2js has been migrated to the new encoding. The
refactoring is intentionally not changing the outcome of the
static_type.dart to make it easier to detect accidental regressions
introduced by the migration.

Change-Id: I93d2033969c33d4c7a5957ad7a6c0b1cdf47fe6f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/184220
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
  • Loading branch information
johnniwinther authored and commit-bot@chromium.org committed Feb 22, 2021
1 parent 348c704 commit 9a74bce
Show file tree
Hide file tree
Showing 5 changed files with 597 additions and 206 deletions.
151 changes: 93 additions & 58 deletions pkg/compiler/lib/src/ir/impact.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:front_end/src/api_unstable/dart2js.dart'
show operatorFromString;

import 'package:kernel/ast.dart' as ir;
import 'package:kernel/class_hierarchy.dart' as ir;
import 'package:kernel/type_environment.dart' as ir;
Expand Down Expand Up @@ -255,13 +252,19 @@ abstract class ImpactBuilderBase extends StaticTypeVisitor
}

@override
void handleStaticGet(ir.StaticGet node, ir.DartType resultType) {
ir.Member target = node.target;
if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) {
registerStaticTearOff(target, getDeferredImport(node));
} else {
registerStaticGet(target, getDeferredImport(node));
}
void handleStaticGet(
ir.Expression node, ir.Member target, ir.DartType resultType) {
assert(!(target is ir.Procedure && target.kind == ir.ProcedureKind.Method),
"Static tear off registered as static get: $node");
registerStaticGet(target, getDeferredImport(node));
}

@override
void handleStaticTearOff(
ir.Expression node, ir.Member target, ir.DartType resultType) {
assert(target is ir.Procedure && target.kind == ir.ProcedureKind.Method,
"Static get registered as static tear off: $node");
registerStaticTearOff(target, getDeferredImport(node));
}

@override
Expand Down Expand Up @@ -520,71 +523,103 @@ abstract class ImpactBuilderBase extends StaticTypeVisitor
}

@override
void handleMethodInvocation(
ir.MethodInvocation node,
void handleDynamicInvocation(
ir.InvocationExpression node,
ir.DartType receiverType,
ArgumentTypes argumentTypes,
ir.DartType returnType) {
int positionArguments = node.arguments.positional.length;
List<String> namedArguments = _getNamedArguments(node.arguments);
List<ir.DartType> typeArguments = node.arguments.types;
ClassRelation relation = computeClassRelationFromType(receiverType);
registerDynamicInvocation(receiverType, relation, node.name,
positionArguments, namedArguments, typeArguments);
}

@override
void handleFunctionInvocation(
ir.InvocationExpression node,
ir.DartType receiverType,
ArgumentTypes argumentTypes,
ir.DartType returnType) {
int positionArguments = node.arguments.positional.length;
List<String> namedArguments = _getNamedArguments(node.arguments);
List<ir.DartType> typeArguments = node.arguments.types;
ir.Expression receiver = node.receiver;
if (receiver is ir.VariableGet &&
receiver.variable.isFinal &&
receiver.variable.parent is ir.FunctionDeclaration) {
registerLocalFunctionInvocation(receiver.variable.parent,
registerFunctionInvocation(
receiverType, positionArguments, namedArguments, typeArguments);
}

@override
void handleInstanceInvocation(
ir.InvocationExpression node,
ir.DartType receiverType,
ir.Member interfaceTarget,
ArgumentTypes argumentTypes) {
int positionArguments = node.arguments.positional.length;
List<String> namedArguments = _getNamedArguments(node.arguments);
List<ir.DartType> typeArguments = node.arguments.types;
ClassRelation relation = computeClassRelationFromType(receiverType);

if (interfaceTarget is ir.Field ||
interfaceTarget is ir.Procedure &&
interfaceTarget.kind == ir.ProcedureKind.Getter) {
registerInstanceInvocation(receiverType, relation, interfaceTarget,
positionArguments, namedArguments, typeArguments);
registerFunctionInvocation(interfaceTarget.getterType, positionArguments,
namedArguments, typeArguments);
} else {
ClassRelation relation = computeClassRelationFromType(receiverType);

ir.Member interfaceTarget = node.interfaceTarget;
if (interfaceTarget == null) {
registerDynamicInvocation(receiverType, relation, node.name,
positionArguments, namedArguments, typeArguments);
// TODO(johnniwinther): Avoid treating a known function call as a
// dynamic call when CFE provides a way to distinguish the two.
if (operatorFromString(node.name.text) == null &&
receiverType is ir.DynamicType) {
// We might implicitly call a getter that returns a function.
registerFunctionInvocation(const ir.DynamicType(), positionArguments,
namedArguments, typeArguments);
}
} else {
if (interfaceTarget is ir.Field ||
interfaceTarget is ir.Procedure &&
interfaceTarget.kind == ir.ProcedureKind.Getter) {
registerInstanceInvocation(receiverType, relation, interfaceTarget,
positionArguments, namedArguments, typeArguments);
registerFunctionInvocation(interfaceTarget.getterType,
positionArguments, namedArguments, typeArguments);
} else {
registerInstanceInvocation(receiverType, relation, interfaceTarget,
positionArguments, namedArguments, typeArguments);
}
}
registerInstanceInvocation(receiverType, relation, interfaceTarget,
positionArguments, namedArguments, typeArguments);
}
}

@override
void handlePropertyGet(
ir.PropertyGet node, ir.DartType receiverType, ir.DartType resultType) {
void handleLocalFunctionInvocation(
ir.InvocationExpression node,
ir.FunctionDeclaration function,
ArgumentTypes argumentTypes,
ir.DartType returnType) {
int positionArguments = node.arguments.positional.length;
List<String> namedArguments = _getNamedArguments(node.arguments);
List<ir.DartType> typeArguments = node.arguments.types;
registerLocalFunctionInvocation(
function, positionArguments, namedArguments, typeArguments);
}

@override
void handleEqualsCall(ir.Expression left, ir.DartType leftType,
ir.Expression right, ir.DartType rightType, ir.Member interfaceTarget) {
ClassRelation relation = computeClassRelationFromType(leftType);
registerInstanceInvocation(leftType, relation, interfaceTarget, 1,
const <String>[], const <ir.DartType>[]);
}

@override
void handleDynamicGet(ir.Expression node, ir.DartType receiverType,
ir.Name name, ir.DartType resultType) {
ClassRelation relation = computeClassRelationFromType(receiverType);
if (node.interfaceTarget != null) {
registerInstanceGet(receiverType, relation, node.interfaceTarget);
} else {
registerDynamicGet(receiverType, relation, node.name);
}
registerDynamicGet(receiverType, relation, name);
}

@override
void handlePropertySet(
ir.PropertySet node, ir.DartType receiverType, ir.DartType valueType) {
void handleInstanceGet(ir.Expression node, ir.DartType receiverType,
ir.Member interfaceTarget, ir.DartType resultType) {
ClassRelation relation = computeClassRelationFromType(receiverType);
if (node.interfaceTarget != null) {
registerInstanceSet(receiverType, relation, node.interfaceTarget);
} else {
registerDynamicSet(receiverType, relation, node.name);
}
registerInstanceGet(receiverType, relation, interfaceTarget);
}

@override
void handleDynamicSet(ir.Expression node, ir.DartType receiverType,
ir.Name name, ir.DartType valueType) {
ClassRelation relation = computeClassRelationFromType(receiverType);
registerDynamicSet(receiverType, relation, name);
}

@override
void handleInstanceSet(ir.Expression node, ir.DartType receiverType,
ir.Member interfaceTarget, ir.DartType valueType) {
ClassRelation relation = computeClassRelationFromType(receiverType);
registerInstanceSet(receiverType, relation, interfaceTarget);
}

@override
Expand Down
Loading

0 comments on commit 9a74bce

Please sign in to comment.