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:
Konstantin Shcheglov 2017-12-03 00:13:42 +00:00 committed by commit-bot@chromium.org
parent ade92a9641
commit 21277a4df8
7 changed files with 268 additions and 55 deletions

View file

@ -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);

View file

@ -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.

View file

@ -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);

View file

@ -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 {

View file

@ -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;

View file

@ -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;

View file

@ -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