| // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file |
| // 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:analyzer/src/error/codes.dart'; |
| import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| |
| import '../dart/resolution/context_collection_resolution.dart'; |
| |
| main() { |
| defineReflectiveSuite(() { |
| defineReflectiveTests(UndefinedSetterTest); |
| }); |
| } |
| |
| @reflectiveTest |
| class UndefinedSetterTest extends PubPackageResolutionTest { |
| test_functionAlias_typeInstantiated() async { |
| await assertErrorsInCode( |
| ''' |
| typedef Fn<T> = void Function(T); |
| |
| void bar() { |
| Fn<int>.foo = 7; |
| } |
| |
| extension E on Type { |
| set foo(int value) {} |
| } |
| ''', |
| [error(CompileTimeErrorCode.undefinedSetterOnFunctionType, 58, 3)], |
| ); |
| } |
| |
| test_functionAlias_typeInstantiated_parenthesized() async { |
| await assertNoErrorsInCode(''' |
| typedef Fn<T> = void Function(T); |
| |
| void bar() { |
| (Fn<int>).foo = 7; |
| } |
| |
| extension E on Type { |
| set foo(int value) {} |
| } |
| '''); |
| } |
| |
| test_importWithPrefix_defined() async { |
| newFile('$testPackageLibPath/lib.dart', r''' |
| library lib; |
| set y(int value) {}'''); |
| await assertNoErrorsInCode(r''' |
| import 'lib.dart' as x; |
| main() { |
| x.y = 0; |
| } |
| '''); |
| } |
| |
| test_instance_undefined() async { |
| await assertErrorsInCode( |
| r''' |
| class T {} |
| f(T e1) { e1.m = 0; } |
| ''', |
| [ |
| error( |
| CompileTimeErrorCode.undefinedSetter, |
| 24, |
| 1, |
| messageContains: ["the type 'T'"], |
| ), |
| ], |
| ); |
| } |
| |
| test_instance_undefined_mixin() async { |
| await assertErrorsInCode( |
| r''' |
| mixin M { |
| f() { this.m = 0; } |
| } |
| ''', |
| [error(CompileTimeErrorCode.undefinedSetter, 23, 1)], |
| ); |
| } |
| |
| test_inSubtype() async { |
| await assertErrorsInCode( |
| r''' |
| class A {} |
| class B extends A { |
| set b(x) {} |
| } |
| f(var a) { |
| if (a is A) { |
| a.b = 0; |
| } |
| } |
| ''', |
| [error(CompileTimeErrorCode.undefinedSetter, 80, 1)], |
| ); |
| } |
| |
| test_inType() async { |
| await assertErrorsInCode( |
| r''' |
| class A {} |
| f(var a) { |
| if(a is A) { |
| a.m = 0; |
| } |
| } |
| ''', |
| [error(CompileTimeErrorCode.undefinedSetter, 43, 1)], |
| ); |
| } |
| |
| test_new_cascade() async { |
| await assertErrorsInCode( |
| ''' |
| class C {} |
| |
| f(C? c) { |
| c..new = 1; |
| } |
| ''', |
| [error(CompileTimeErrorCode.undefinedSetter, 27, 3)], |
| ); |
| } |
| |
| test_new_dynamic() async { |
| await assertErrorsInCode( |
| ''' |
| f(dynamic d) { |
| d.new = 1; |
| } |
| ''', |
| [error(CompileTimeErrorCode.undefinedSetter, 19, 3)], |
| ); |
| } |
| |
| test_new_instance() async { |
| await assertErrorsInCode( |
| ''' |
| class C {} |
| |
| f(C c) { |
| c.new = 1; |
| } |
| ''', |
| [error(CompileTimeErrorCode.undefinedSetter, 25, 3)], |
| ); |
| } |
| |
| test_new_interfaceType() async { |
| await assertErrorsInCode( |
| ''' |
| class C {} |
| |
| f() { |
| C.new = 1; |
| } |
| ''', |
| [error(CompileTimeErrorCode.undefinedSetter, 22, 3)], |
| ); |
| } |
| |
| test_new_nullAware() async { |
| await assertErrorsInCode( |
| ''' |
| class C {} |
| |
| f(C? c) { |
| c?.new = 1; |
| } |
| ''', |
| [error(CompileTimeErrorCode.undefinedSetter, 27, 3)], |
| ); |
| } |
| |
| test_new_typeVariable() async { |
| await assertErrorsInCode( |
| ''' |
| f<T>(T t) { |
| t.new = 1; |
| } |
| ''', |
| [error(CompileTimeErrorCode.undefinedSetter, 16, 3)], |
| ); |
| } |
| |
| test_set_abstract_field_valid() async { |
| await assertNoErrorsInCode(''' |
| abstract class A { |
| abstract int x; |
| } |
| void f(A a, int x) { |
| a.x = x; |
| } |
| '''); |
| } |
| |
| test_set_external_field_valid() async { |
| await assertNoErrorsInCode(''' |
| class A { |
| external int x; |
| } |
| void f(A a, int x) { |
| a.x = x; |
| } |
| '''); |
| } |
| |
| test_set_external_static_field_valid() async { |
| await assertNoErrorsInCode(''' |
| class A { |
| external static int x; |
| } |
| void f(int x) { |
| A.x = x; |
| } |
| '''); |
| } |
| |
| test_static_conditionalAccess_defined() async { |
| await assertErrorsInCode( |
| ''' |
| class A { |
| static var x; |
| } |
| f() { A?.x = 1; } |
| ''', |
| [error(StaticWarningCode.invalidNullAwareOperator, 35, 2)], |
| ); |
| } |
| |
| test_static_definedInSuperclass() async { |
| await assertErrorsInCode( |
| ''' |
| class S { |
| static set s(int i) {} |
| } |
| class C extends S {} |
| f(var p) { |
| f(C.s = 1); |
| }''', |
| [ |
| error( |
| CompileTimeErrorCode.undefinedSetter, |
| 75, |
| 1, |
| messageContains: ["type 'C'"], |
| ), |
| ], |
| ); |
| } |
| |
| test_static_extension_instanceAccess() async { |
| await assertErrorsInCode( |
| ''' |
| class C {} |
| |
| extension E on C { |
| static set a(int v) {} |
| } |
| |
| f(C c) { |
| c.a = 2; |
| } |
| ''', |
| [error(CompileTimeErrorCode.undefinedSetter, 72, 1)], |
| ); |
| |
| assertResolvedNodeText(findNode.assignment('a ='), r''' |
| AssignmentExpression |
| leftHandSide: PrefixedIdentifier |
| prefix: SimpleIdentifier |
| token: c |
| element: <testLibrary>::@function::f::@formalParameter::c |
| staticType: C |
| period: . |
| identifier: SimpleIdentifier |
| token: a |
| element: <null> |
| staticType: null |
| element: <null> |
| staticType: null |
| operator: = |
| rightHandSide: IntegerLiteral |
| literal: 2 |
| correspondingParameter: <null> |
| staticType: int |
| readElement2: <null> |
| readType: null |
| writeElement2: <null> |
| writeType: InvalidType |
| element: <null> |
| staticType: int |
| '''); |
| } |
| |
| test_static_undefined() async { |
| await assertErrorsInCode( |
| r''' |
| class A {} |
| f() { A.B = 0;} |
| ''', |
| [error(CompileTimeErrorCode.undefinedSetter, 19, 1)], |
| ); |
| } |
| |
| test_typeLiteral_cascadeTarget() async { |
| await assertErrorsInCode( |
| r''' |
| class T { |
| static void set foo(_) {} |
| } |
| main() { |
| T..foo = 42; |
| } |
| ''', |
| [error(CompileTimeErrorCode.undefinedSetter, 54, 3)], |
| ); |
| } |
| |
| test_withExtension() async { |
| await assertErrorsInCode( |
| r''' |
| class C {} |
| |
| extension E on C {} |
| |
| f(C c) { |
| c.a = 1; |
| } |
| ''', |
| [error(CompileTimeErrorCode.undefinedSetter, 46, 1)], |
| ); |
| } |
| } |