mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:58:29 +00:00
Apply resolution to 'this' and 'super'.
R=brianwilkerson@google.com, paulberry@google.com Bug: Change-Id: I905ea53aa1c39d789824e8c7061135a41b8f8cac Reviewed-on: https://dart-review.googlesource.com/25663 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
ade92a9641
commit
21277a4df8
|
@ -736,9 +736,9 @@ class LibraryAnalyzer {
|
|||
member.fields.variables[0].initializer?.accept(applier);
|
||||
applier.checkDone();
|
||||
} else if (member is MethodDeclaration) {
|
||||
// TODO(scheglov) Pass in the actual context element.
|
||||
ExecutableElementImpl context = member.element;
|
||||
var resolution = resolutions.next();
|
||||
var applier = _createResolutionApplier(null, resolution);
|
||||
var applier = _createResolutionApplier(context, resolution);
|
||||
member.body.accept(applier);
|
||||
applier.checkDone();
|
||||
} else {
|
||||
|
@ -974,6 +974,9 @@ class _ResolutionApplierContext implements TypeContext {
|
|||
final TypeProvider typeProvider;
|
||||
final CollectedResolution resolution;
|
||||
|
||||
@override
|
||||
ClassElement enclosingClassElement;
|
||||
|
||||
List<ElementImpl> contextStack = [];
|
||||
ElementImpl context;
|
||||
|
||||
|
@ -988,6 +991,15 @@ class _ResolutionApplierContext implements TypeContext {
|
|||
|
||||
_ResolutionApplierContext(
|
||||
this.resynthesizer, this.typeProvider, this.resolution, this.context) {
|
||||
for (Element element = context;
|
||||
element != null;
|
||||
element = element.enclosingElement) {
|
||||
if (element is ClassElement) {
|
||||
enclosingClassElement = element;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert local declarations into elements.
|
||||
for (var declaredNode in resolution.kernelDeclarations) {
|
||||
translateKernelDeclaration(declaredNode);
|
||||
|
|
|
@ -352,6 +352,16 @@ class ResolutionApplier extends GeneralizingAstVisitor {
|
|||
node.staticType = _getTypeFor(node.endToken.next);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitSuperExpression(SuperExpression node) {
|
||||
node.staticType = _typeContext.enclosingClassElement?.type;
|
||||
}
|
||||
|
||||
@override
|
||||
void visitThisExpression(ThisExpression node) {
|
||||
node.staticType = _typeContext.enclosingClassElement?.type;
|
||||
}
|
||||
|
||||
@override
|
||||
void visitTypeAnnotation(TypeAnnotation node) {
|
||||
applyToTypeAnnotation(_getTypeFor(node), node);
|
||||
|
@ -573,6 +583,9 @@ class ResolutionApplier extends GeneralizingAstVisitor {
|
|||
|
||||
/// Context for translating types.
|
||||
abstract class TypeContext {
|
||||
/// The enclosing [ClassElement], or `null` if not in a class.
|
||||
ClassElement get enclosingClassElement;
|
||||
|
||||
DartType get typeType;
|
||||
|
||||
/// Attach the variable [element] to the current executable.
|
||||
|
|
|
@ -415,6 +415,9 @@ class ResolutionStorer extends TypeInferenceListener {
|
|||
super.genericExpressionExit("staticInvocation", expression, inferredType);
|
||||
}
|
||||
|
||||
@override
|
||||
void thisExpressionExit(ThisExpression expression, DartType inferredType) {}
|
||||
|
||||
void typeLiteralExit(TypeLiteral expression, DartType inferredType) {
|
||||
_recordReference(expression.type, expression.fileOffset);
|
||||
super.typeLiteralExit(expression, inferredType);
|
||||
|
|
|
@ -2039,6 +2039,237 @@ void main() {
|
|||
}
|
||||
}
|
||||
|
||||
test_super() async {
|
||||
String content = r'''
|
||||
class A {
|
||||
void method(int p) {}
|
||||
int get getter => 0;
|
||||
void set setter(int p) {}
|
||||
int operator+(int p) => 0;
|
||||
}
|
||||
class B extends A {
|
||||
void test() {
|
||||
method(1);
|
||||
super.method(2);
|
||||
getter;
|
||||
super.getter;
|
||||
setter = 3;
|
||||
super.setter = 4;
|
||||
this + 5;
|
||||
}
|
||||
}
|
||||
''';
|
||||
addTestFile(content);
|
||||
AnalysisResult result = await driver.getResult(testFile);
|
||||
var typeProvider = result.unit.element.context.typeProvider;
|
||||
|
||||
ClassDeclaration aNode = result.unit.declarations[0];
|
||||
ClassDeclaration bNode = result.unit.declarations[1];
|
||||
|
||||
MethodElement methodElement = aNode.members[0].element;
|
||||
PropertyAccessorElement getterElement = aNode.members[1].element;
|
||||
PropertyAccessorElement setterElement = aNode.members[2].element;
|
||||
MethodElement operatorElement = aNode.members[3].element;
|
||||
|
||||
MethodDeclaration testNode = bNode.members[0];
|
||||
BlockFunctionBody testBody = testNode.body;
|
||||
List<Statement> testStatements = testBody.block.statements;
|
||||
|
||||
// method(1);
|
||||
{
|
||||
ExpressionStatement statement = testStatements[0];
|
||||
MethodInvocation invocation = statement.expression;
|
||||
|
||||
expect(invocation.target, isNull);
|
||||
|
||||
expect(invocation.methodName.staticElement, same(methodElement));
|
||||
}
|
||||
|
||||
// super.method(2);
|
||||
{
|
||||
ExpressionStatement statement = testStatements[1];
|
||||
MethodInvocation invocation = statement.expression;
|
||||
|
||||
SuperExpression target = invocation.target;
|
||||
expect(target.staticType, bNode.element.type); // raw
|
||||
|
||||
expect(invocation.methodName.staticElement, same(methodElement));
|
||||
}
|
||||
|
||||
// getter;
|
||||
{
|
||||
ExpressionStatement statement = testStatements[2];
|
||||
SimpleIdentifier identifier = statement.expression;
|
||||
|
||||
expect(identifier.staticElement, same(getterElement));
|
||||
expect(identifier.staticType, same(typeProvider.intType));
|
||||
}
|
||||
|
||||
// super.getter;
|
||||
{
|
||||
ExpressionStatement statement = testStatements[3];
|
||||
PropertyAccess propertyAccess = statement.expression;
|
||||
expect(propertyAccess.staticType, same(typeProvider.intType));
|
||||
|
||||
SuperExpression target = propertyAccess.target;
|
||||
expect(target.staticType, bNode.element.type); // raw
|
||||
|
||||
expect(propertyAccess.propertyName.staticElement, same(getterElement));
|
||||
expect(
|
||||
propertyAccess.propertyName.staticType, same(typeProvider.intType));
|
||||
}
|
||||
|
||||
// setter = 3;
|
||||
{
|
||||
ExpressionStatement statement = testStatements[4];
|
||||
AssignmentExpression assignment = statement.expression;
|
||||
|
||||
SimpleIdentifier identifier = assignment.leftHandSide;
|
||||
expect(identifier.staticElement, same(setterElement));
|
||||
expect(identifier.staticType, same(typeProvider.intType));
|
||||
}
|
||||
|
||||
// this.setter = 4;
|
||||
{
|
||||
ExpressionStatement statement = testStatements[5];
|
||||
AssignmentExpression assignment = statement.expression;
|
||||
|
||||
PropertyAccess propertyAccess = assignment.leftHandSide;
|
||||
|
||||
SuperExpression target = propertyAccess.target;
|
||||
expect(target.staticType, bNode.element.type); // raw
|
||||
|
||||
expect(propertyAccess.propertyName.staticElement, same(setterElement));
|
||||
expect(
|
||||
propertyAccess.propertyName.staticType, same(typeProvider.intType));
|
||||
}
|
||||
|
||||
// super + 5;
|
||||
{
|
||||
ExpressionStatement statement = testStatements[6];
|
||||
BinaryExpression binary = statement.expression;
|
||||
|
||||
ThisExpression target = binary.leftOperand;
|
||||
expect(target.staticType, bNode.element.type); // raw
|
||||
|
||||
expect(binary.staticElement, same(operatorElement));
|
||||
expect(binary.staticType, typeProvider.intType);
|
||||
}
|
||||
}
|
||||
|
||||
test_this() async {
|
||||
String content = r'''
|
||||
class A {
|
||||
void method(int p) {}
|
||||
int get getter => 0;
|
||||
void set setter(int p) {}
|
||||
int operator+(int p) => 0;
|
||||
void test() {
|
||||
method(1);
|
||||
this.method(2);
|
||||
getter;
|
||||
this.getter;
|
||||
setter = 3;
|
||||
this.setter = 4;
|
||||
this + 5;
|
||||
}
|
||||
}
|
||||
''';
|
||||
addTestFile(content);
|
||||
AnalysisResult result = await driver.getResult(testFile);
|
||||
var typeProvider = result.unit.element.context.typeProvider;
|
||||
|
||||
ClassDeclaration aNode = result.unit.declarations[0];
|
||||
|
||||
MethodElement methodElement = aNode.members[0].element;
|
||||
PropertyAccessorElement getterElement = aNode.members[1].element;
|
||||
PropertyAccessorElement setterElement = aNode.members[2].element;
|
||||
MethodElement operatorElement = aNode.members[3].element;
|
||||
|
||||
MethodDeclaration testNode = aNode.members[4];
|
||||
BlockFunctionBody testBody = testNode.body;
|
||||
List<Statement> testStatements = testBody.block.statements;
|
||||
|
||||
// method(1);
|
||||
{
|
||||
ExpressionStatement statement = testStatements[0];
|
||||
MethodInvocation invocation = statement.expression;
|
||||
|
||||
expect(invocation.target, isNull);
|
||||
|
||||
expect(invocation.methodName.staticElement, same(methodElement));
|
||||
}
|
||||
|
||||
// this.method(2);
|
||||
{
|
||||
ExpressionStatement statement = testStatements[1];
|
||||
MethodInvocation invocation = statement.expression;
|
||||
|
||||
ThisExpression target = invocation.target;
|
||||
expect(target.staticType, aNode.element.type); // raw
|
||||
|
||||
expect(invocation.methodName.staticElement, same(methodElement));
|
||||
}
|
||||
|
||||
// getter;
|
||||
{
|
||||
ExpressionStatement statement = testStatements[2];
|
||||
SimpleIdentifier identifier = statement.expression;
|
||||
|
||||
expect(identifier.staticElement, same(getterElement));
|
||||
expect(identifier.staticType, typeProvider.intType);
|
||||
}
|
||||
|
||||
// this.getter;
|
||||
{
|
||||
ExpressionStatement statement = testStatements[3];
|
||||
PropertyAccess propertyAccess = statement.expression;
|
||||
expect(propertyAccess.staticType, typeProvider.intType);
|
||||
|
||||
ThisExpression target = propertyAccess.target;
|
||||
expect(target.staticType, aNode.element.type); // raw
|
||||
|
||||
expect(propertyAccess.propertyName.staticElement, same(getterElement));
|
||||
expect(propertyAccess.propertyName.staticType, typeProvider.intType);
|
||||
}
|
||||
|
||||
// setter = 3;
|
||||
{
|
||||
ExpressionStatement statement = testStatements[4];
|
||||
AssignmentExpression assignment = statement.expression;
|
||||
|
||||
SimpleIdentifier identifier = assignment.leftHandSide;
|
||||
expect(identifier.staticElement, same(setterElement));
|
||||
expect(identifier.staticType, typeProvider.intType);
|
||||
}
|
||||
|
||||
// this.setter = 4;
|
||||
{
|
||||
ExpressionStatement statement = testStatements[5];
|
||||
AssignmentExpression assignment = statement.expression;
|
||||
|
||||
PropertyAccess propertyAccess = assignment.leftHandSide;
|
||||
|
||||
ThisExpression target = propertyAccess.target;
|
||||
expect(target.staticType, aNode.element.type); // raw
|
||||
|
||||
expect(propertyAccess.propertyName.staticElement, same(setterElement));
|
||||
expect(propertyAccess.propertyName.staticType, typeProvider.intType);
|
||||
}
|
||||
|
||||
// this + 5;
|
||||
{
|
||||
ExpressionStatement statement = testStatements[6];
|
||||
BinaryExpression binary = statement.expression;
|
||||
|
||||
ThisExpression target = binary.leftOperand;
|
||||
expect(target.staticType, aNode.element.type); // raw
|
||||
|
||||
expect(binary.staticElement, same(operatorElement));
|
||||
expect(binary.staticType, typeProvider.intType);
|
||||
}
|
||||
}
|
||||
|
||||
test_top_executables_class() async {
|
||||
String content = r'''
|
||||
class C {
|
||||
|
|
|
@ -319,6 +319,9 @@ class _KernelWrapperOfType implements kernel.DartType {
|
|||
|
||||
/// Test implementation of [TypeContext].
|
||||
class _TestTypeContext implements TypeContext {
|
||||
@override
|
||||
ClassElement get enclosingClassElement => null;
|
||||
|
||||
@override
|
||||
DartType get typeType => null;
|
||||
|
||||
|
|
|
@ -313,6 +313,9 @@ class AnalyzerDietListener extends DietListener {
|
|||
|
||||
/// Test implementation of [TypeContext].
|
||||
class _TestTypeContext implements TypeContext {
|
||||
@override
|
||||
ast.ClassElement get enclosingClassElement => null;
|
||||
|
||||
@override
|
||||
ast.DartType get typeType => null;
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ bad_setter_abstract: Crash
|
|||
call: Crash
|
||||
cascade: Crash
|
||||
classes: Crash
|
||||
covariant_generic: Crash
|
||||
default_values: Crash
|
||||
duplicated_named_args_3: Crash
|
||||
escape: Crash
|
||||
|
@ -26,7 +25,6 @@ functions: Crash
|
|||
illegal_named_function_expression: Crash
|
||||
illegal_named_function_expression_scope: Crash
|
||||
implicit_scope_test: Crash
|
||||
implicit_this: Crash
|
||||
inference/abstract_class_instantiation: Crash
|
||||
inference/assert_initializer: Crash
|
||||
inference/block_bodied_lambdas_async_star: Crash
|
||||
|
@ -40,8 +38,6 @@ inference/call_corner_cases: Crash
|
|||
inference/complex_predecrement: Crash
|
||||
inference/constructors_infer_from_arguments: Crash
|
||||
inference/constructors_infer_from_arguments_redirecting: Crash
|
||||
inference/constructors_inference_f_bounded: Crash
|
||||
inference/constructors_reverse_type_parameters: Crash
|
||||
inference/constructors_too_many_positional_arguments: Crash
|
||||
inference/downwards_inference_annotations: Crash
|
||||
inference/downwards_inference_annotations_class_members: Crash
|
||||
|
@ -108,10 +104,6 @@ inference/generic_methods_iterable_and_future: Crash
|
|||
inference/generic_methods_nested_generic_instantiation: Crash
|
||||
inference/greatest_closure_multiple_params: Crash
|
||||
inference/infer_assign_to_index_full: Crash
|
||||
inference/infer_assign_to_index_super: Crash
|
||||
inference/infer_assign_to_index_this: Crash
|
||||
inference/infer_assign_to_property_super: Crash
|
||||
inference/infer_assign_to_property_super_upwards: Crash
|
||||
inference/infer_assign_to_static: Crash
|
||||
inference/infer_assign_to_static_upwards: Crash
|
||||
inference/infer_correctly_on_multiple_variables_declared_together: Crash
|
||||
|
@ -135,9 +127,7 @@ inference/infer_statics_transitively_2_a: Crash
|
|||
inference/infer_statics_transitively_a: Crash
|
||||
inference/infer_statics_with_method_invocations: Crash
|
||||
inference/infer_statics_with_method_invocations_a: Crash
|
||||
inference/infer_type_on_var_from_field: Crash
|
||||
inference/infer_typed_map_literal: Crash
|
||||
inference/infer_types_on_generic_instantiations_4: Crash
|
||||
inference/infer_types_on_loop_indices_for_each_loop: Crash
|
||||
inference/infer_types_on_loop_indices_for_each_loop_async: Crash
|
||||
inference/inferred_initializing_formal_checks_default_value: Crash
|
||||
|
@ -161,31 +151,16 @@ inference/null_literal_should_not_infer_as_bottom: Crash
|
|||
inference/parameter_defaults_downwards: Crash
|
||||
inference/parameter_defaults_upwards: Crash
|
||||
inference/promote_from_logical_rhs: Crash
|
||||
inference/refine_binary_expression_type_type_parameter_t_double: Crash
|
||||
inference/refine_binary_expression_type_type_parameter_t_int: Crash
|
||||
inference/refine_binary_expression_type_type_parameter_t_t: Crash
|
||||
inference/static_method_tear_off: Crash
|
||||
inference/string_literal: Crash
|
||||
inference/super_index_set: Crash
|
||||
inference/super_index_set_substitution: Crash
|
||||
inference/super_initializer: Crash
|
||||
inference/super_initializer_substitution: Crash
|
||||
inference/super_method_invocation: Crash
|
||||
inference/super_method_invocation_substitution: Crash
|
||||
inference/super_property_get: Crash
|
||||
inference/super_property_get_substitution: Crash
|
||||
inference/super_property_get_invoke_function_typed: Crash
|
||||
inference/super_property_get_invoke_implicit_call: Crash
|
||||
inference/super_property_get_tearoff: Crash
|
||||
inference/super_property_set_substitution: Crash
|
||||
inference/switch_continue: Crash
|
||||
inference/this_reference: Crash
|
||||
inference/top_level_return_and_yield: Fail
|
||||
inference/try_catch: Crash
|
||||
inference/try_catch_finally: Crash
|
||||
inference/try_catch_promotion: Crash
|
||||
inference/type_promotion_not_and_not: Crash
|
||||
inference/unresolved_super: Crash
|
||||
inference/unsafe_block_closure_inference_closure_call: Crash
|
||||
inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1: Crash
|
||||
inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2: Crash
|
||||
|
@ -201,21 +176,13 @@ inference_new/indexed_assign_combiner: Crash
|
|||
inference_new/infer_assign_to_index: Crash
|
||||
inference_new/infer_assign_to_index_full: Crash
|
||||
inference_new/infer_assign_to_index_set_vs_get: Crash
|
||||
inference_new/infer_assign_to_index_super: Crash
|
||||
inference_new/infer_assign_to_index_super_upwards: Crash
|
||||
inference_new/infer_assign_to_index_this: Crash
|
||||
inference_new/infer_assign_to_index_this_upwards: Crash
|
||||
inference_new/infer_assign_to_index_upwards: Crash
|
||||
inference_new/infer_assign_to_property_super: Crash
|
||||
inference_new/infer_assign_to_property_super_upwards: Crash
|
||||
inference_new/infer_assign_to_ref: Crash
|
||||
inference_new/infer_assign_to_static: Crash
|
||||
inference_new/infer_assign_to_static_upwards: Crash
|
||||
inference_new/infer_logical: Crash
|
||||
inference_new/invalid_assignment_during_toplevel_inference: Crash
|
||||
inference_new/static_assign_combiner: Crash
|
||||
inference_new/super_index_get: Crash
|
||||
inference_new/super_index_get_substitution: Crash
|
||||
inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2: Crash
|
||||
inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2: Crash
|
||||
invocations: Crash
|
||||
|
@ -241,21 +208,17 @@ rasta/generic_factory: Crash
|
|||
rasta/issue_000001: Crash
|
||||
rasta/issue_000002: Crash
|
||||
rasta/issue_000004: Crash
|
||||
rasta/issue_000012: Crash
|
||||
rasta/issue_000025: Crash
|
||||
rasta/issue_000031: Crash
|
||||
rasta/issue_000036: Crash
|
||||
rasta/issue_000039: Crash
|
||||
rasta/issue_000041: Crash
|
||||
rasta/issue_000039: VerificationError
|
||||
rasta/issue_000042: Crash
|
||||
rasta/issue_000044: Crash
|
||||
rasta/issue_000045: Crash
|
||||
rasta/issue_000053: Crash
|
||||
rasta/issue_000067: Crash
|
||||
rasta/issue_000068: Crash
|
||||
rasta/issue_000069: Crash
|
||||
rasta/issue_000070: Crash
|
||||
rasta/issue_000080: Crash
|
||||
rasta/issue_000081: Crash
|
||||
rasta/malformed_const_constructor: Crash
|
||||
rasta/malformed_function: Crash
|
||||
|
@ -267,7 +230,6 @@ rasta/static: Crash
|
|||
rasta/super: Crash
|
||||
rasta/super_initializer: Crash
|
||||
rasta/super_mixin: Crash
|
||||
rasta/super_operator: Crash
|
||||
rasta/supports_reflection: VerificationError
|
||||
rasta/this_invoke: Crash
|
||||
rasta/try_label: Crash
|
||||
|
@ -295,18 +257,7 @@ regress/issue_31186: Crash
|
|||
regress/issue_31187: Crash
|
||||
regress/issue_31198: Crash
|
||||
reorder_super: Crash
|
||||
runtime_checks/call_kinds: Crash
|
||||
runtime_checks/call_kinds_get: Crash
|
||||
runtime_checks/call_kinds_set: Crash
|
||||
runtime_checks/contravariant_generic_return: Crash
|
||||
runtime_checks/contravariant_generic_return_null_aware: Crash
|
||||
runtime_checks/contravariant_generic_return_tear_off: Crash
|
||||
runtime_checks/contravariant_getter: Crash
|
||||
runtime_checks/contravariant_getter_return: Crash
|
||||
runtime_checks/contravariant_getter_return_null_aware: Crash
|
||||
runtime_checks/covariant_generic_method_type_parameter: Crash
|
||||
runtime_checks/covariant_generic_parameter_in_interface: Crash
|
||||
runtime_checks/covariant_setter: Crash
|
||||
runtime_checks/forwarding_stub_with_default_values: Crash
|
||||
runtime_checks/implicit_downcast_assert_initializer: Crash
|
||||
runtime_checks/implicit_downcast_assert_statement: Crash
|
||||
|
@ -316,7 +267,6 @@ runtime_checks/implicit_downcast_for_condition: Crash
|
|||
runtime_checks/implicit_downcast_if: Crash
|
||||
runtime_checks/implicit_downcast_not: Crash
|
||||
runtime_checks/implicit_downcast_while: Crash
|
||||
runtime_checks_new/call_through_this: Crash
|
||||
runtime_checks_new/contravariant_combiner: Crash
|
||||
runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: Crash
|
||||
runtime_checks_new/contravariant_index_assign: Crash
|
||||
|
@ -334,6 +284,4 @@ top_level_accessors: Crash
|
|||
type_variable_as_super: Crash
|
||||
type_variable_prefix: Crash
|
||||
uninitialized_fields: Crash
|
||||
unused_methods: Crash
|
||||
void_methods: Crash
|
||||
warn_unresolved_sends: Crash
|
||||
|
|
Loading…
Reference in a new issue