blob: 30bf4bc766163824cdb3042a8803d317a6b86b9a [file] [log] [blame]
// Copyright (c) 2024, 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/dart/analysis/results.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../dart/resolution/node_text_expectations.dart';
import '../element_text.dart';
import '../elements_base.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(SinceSdkVersionElementTest_keepLinking);
defineReflectiveTests(SinceSdkVersionElementTest_fromBytes);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
abstract class SinceSdkVersionElementTest extends ElementsBaseTest {
@override
List<MockSdkLibrary> additionalMockSdkLibraries = [];
test_sinceSdkVersion_class_constructor_inherits() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15')
class A {
A.named();
}
class B {
B.named();
}
''');
configuration
..forSinceSdkVersion()
..withConstructors = true;
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
classes
#F1 class A @47
element: dart:foo::@class::A
constructors
#F2 named @55
element: dart:foo::@class::A::@constructor::named
typeName: A
typeNameOffset: 53
periodOffset: 54
#F3 class B @73
element: dart:foo::@class::B
constructors
#F4 named @81
element: dart:foo::@class::B::@constructor::named
typeName: B
typeNameOffset: 79
periodOffset: 80
classes
class A
reference: dart:foo::@class::A
firstFragment: #F1
sinceSdkVersion: 2.15.0
constructors
named
reference: dart:foo::@class::A::@constructor::named
firstFragment: #F2
sinceSdkVersion: 2.15.0
class B
reference: dart:foo::@class::B
firstFragment: #F3
constructors
named
reference: dart:foo::@class::B::@constructor::named
firstFragment: #F4
''');
}
test_sinceSdkVersion_class_field_inherits() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15')
class A {
int foo = 0;
}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
classes
#F1 class A @47
element: dart:foo::@class::A
fields
#F2 hasInitializer foo @57
element: dart:foo::@class::A::@field::foo
getter2: #F3
setter2: #F4
getters
#F3 synthetic foo
element: dart:foo::@class::A::@getter::foo
returnType: int
variable: #F2
setters
#F4 synthetic foo
element: dart:foo::@class::A::@setter::foo
formalParameters
#F5 _foo
element: dart:foo::@class::A::@setter::foo::@formalParameter::_foo
classes
class A
reference: dart:foo::@class::A
firstFragment: #F1
sinceSdkVersion: 2.15.0
fields
hasInitializer foo
reference: dart:foo::@class::A::@field::foo
firstFragment: #F2
sinceSdkVersion: 2.15.0
type: int
getter: dart:foo::@class::A::@getter::foo
setter: dart:foo::@class::A::@setter::foo
getters
synthetic foo
reference: dart:foo::@class::A::@getter::foo
firstFragment: #F3
sinceSdkVersion: 2.15.0
returnType: int
variable: dart:foo::@class::A::@field::foo
setters
synthetic foo
reference: dart:foo::@class::A::@setter::foo
firstFragment: #F4
sinceSdkVersion: 2.15.0
formalParameters
requiredPositional _foo
firstFragment: #F5
type: int
returnType: void
''');
}
test_sinceSdkVersion_class_getter_inherits() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15')
class A {
int get foo => 0;
}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
classes
#F1 class A @47
element: dart:foo::@class::A
fields
#F2 synthetic foo
element: dart:foo::@class::A::@field::foo
getter2: #F3
getters
#F3 foo @61
element: dart:foo::@class::A::@getter::foo
returnType: int
variable: #F2
classes
class A
reference: dart:foo::@class::A
firstFragment: #F1
sinceSdkVersion: 2.15.0
fields
synthetic foo
reference: dart:foo::@class::A::@field::foo
firstFragment: #F2
sinceSdkVersion: 2.15.0
type: int
getter: dart:foo::@class::A::@getter::foo
getters
foo
reference: dart:foo::@class::A::@getter::foo
firstFragment: #F3
sinceSdkVersion: 2.15.0
returnType: int
variable: dart:foo::@class::A::@field::foo
''');
}
test_sinceSdkVersion_class_method_inherits() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15')
class A {
void foo() {}
}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
classes
#F1 class A @47
element: dart:foo::@class::A
methods
#F2 foo @58
element: dart:foo::@class::A::@method::foo
classes
class A
reference: dart:foo::@class::A
firstFragment: #F1
sinceSdkVersion: 2.15.0
methods
foo
reference: dart:foo::@class::A::@method::foo
firstFragment: #F2
sinceSdkVersion: 2.15.0
returnType: void
''');
}
test_sinceSdkVersion_class_method_max_greater() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15')
class A {
@Since('2.16')
void foo() {}
}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
classes
#F1 class A @47
element: dart:foo::@class::A
methods
#F2 foo @75
element: dart:foo::@class::A::@method::foo
classes
class A
reference: dart:foo::@class::A
firstFragment: #F1
sinceSdkVersion: 2.15.0
methods
foo
reference: dart:foo::@class::A::@method::foo
firstFragment: #F2
sinceSdkVersion: 2.16.0
returnType: void
''');
}
test_sinceSdkVersion_class_method_max_less() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15')
class A {
@Since('2.14')
void foo() {}
}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
classes
#F1 class A @47
element: dart:foo::@class::A
methods
#F2 foo @75
element: dart:foo::@class::A::@method::foo
classes
class A
reference: dart:foo::@class::A
firstFragment: #F1
sinceSdkVersion: 2.15.0
methods
foo
reference: dart:foo::@class::A::@method::foo
firstFragment: #F2
sinceSdkVersion: 2.15.0
returnType: void
''');
}
test_sinceSdkVersion_class_setter_inherits() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15')
class A {
set foo(int _) {}
}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
classes
#F1 class A @47
element: dart:foo::@class::A
fields
#F2 synthetic foo
element: dart:foo::@class::A::@field::foo
setter2: #F3
setters
#F3 foo @57
element: dart:foo::@class::A::@setter::foo
formalParameters
#F4 _ @65
element: dart:foo::@class::A::@setter::foo::@formalParameter::_
classes
class A
reference: dart:foo::@class::A
firstFragment: #F1
sinceSdkVersion: 2.15.0
fields
synthetic foo
reference: dart:foo::@class::A::@field::foo
firstFragment: #F2
sinceSdkVersion: 2.15.0
type: int
setter: dart:foo::@class::A::@setter::foo
setters
foo
reference: dart:foo::@class::A::@setter::foo
firstFragment: #F3
sinceSdkVersion: 2.15.0
formalParameters
requiredPositional _
firstFragment: #F4
type: int
returnType: void
''');
}
test_sinceSdkVersion_enum_constant() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
enum E {
v1,
@Since('2.15')
v2
}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
enums
#F1 enum E @31
element: dart:foo::@enum::E
fields
#F2 hasInitializer v1 @37
element: dart:foo::@enum::E::@field::v1
initializer: expression_0
InstanceCreationExpression
constructorName: ConstructorName
type: NamedType
name: E @-1
element2: dart:foo::@enum::E
type: E
element: dart:foo::@enum::E::@constructor::new
argumentList: ArgumentList
leftParenthesis: ( @0
rightParenthesis: ) @0
staticType: E
getter2: #F3
#F4 hasInitializer v2 @60
element: dart:foo::@enum::E::@field::v2
initializer: expression_1
InstanceCreationExpression
constructorName: ConstructorName
type: NamedType
name: E @-1
element2: dart:foo::@enum::E
type: E
element: dart:foo::@enum::E::@constructor::new
argumentList: ArgumentList
leftParenthesis: ( @0
rightParenthesis: ) @0
staticType: E
getter2: #F5
#F6 synthetic values
element: dart:foo::@enum::E::@field::values
initializer: expression_2
ListLiteral
leftBracket: [ @0
elements
SimpleIdentifier
token: v1 @-1
element: dart:foo::@enum::E::@getter::v1
staticType: E
SimpleIdentifier
token: v2 @-1
element: dart:foo::@enum::E::@getter::v2
staticType: E
rightBracket: ] @0
staticType: List<E>
getter2: #F7
getters
#F3 synthetic v1
element: dart:foo::@enum::E::@getter::v1
returnType: E
variable: #F2
#F5 synthetic v2
element: dart:foo::@enum::E::@getter::v2
returnType: E
variable: #F4
#F7 synthetic values
element: dart:foo::@enum::E::@getter::values
returnType: List<E>
variable: #F6
enums
enum E
reference: dart:foo::@enum::E
firstFragment: #F1
supertype: Enum
fields
static const enumConstant hasInitializer v1
reference: dart:foo::@enum::E::@field::v1
firstFragment: #F2
type: E
constantInitializer
fragment: #F2
expression: expression_0
getter: dart:foo::@enum::E::@getter::v1
static const enumConstant hasInitializer v2
reference: dart:foo::@enum::E::@field::v2
firstFragment: #F4
sinceSdkVersion: 2.15.0
type: E
constantInitializer
fragment: #F4
expression: expression_1
getter: dart:foo::@enum::E::@getter::v2
synthetic static const values
reference: dart:foo::@enum::E::@field::values
firstFragment: #F6
type: List<E>
constantInitializer
fragment: #F6
expression: expression_2
getter: dart:foo::@enum::E::@getter::values
getters
synthetic static v1
reference: dart:foo::@enum::E::@getter::v1
firstFragment: #F3
returnType: E
variable: dart:foo::@enum::E::@field::v1
synthetic static v2
reference: dart:foo::@enum::E::@getter::v2
firstFragment: #F5
sinceSdkVersion: 2.15.0
returnType: E
variable: dart:foo::@enum::E::@field::v2
synthetic static values
reference: dart:foo::@enum::E::@getter::values
firstFragment: #F7
returnType: List<E>
variable: dart:foo::@enum::E::@field::values
''');
}
test_sinceSdkVersion_enum_method_inherits() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15')
enum E {
v;
void foo() {}
}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
enums
#F1 enum E @46
element: dart:foo::@enum::E
fields
#F2 hasInitializer v @52
element: dart:foo::@enum::E::@field::v
initializer: expression_0
InstanceCreationExpression
constructorName: ConstructorName
type: NamedType
name: E @-1
element2: dart:foo::@enum::E
type: E
element: dart:foo::@enum::E::@constructor::new
argumentList: ArgumentList
leftParenthesis: ( @0
rightParenthesis: ) @0
staticType: E
getter2: #F3
#F4 synthetic values
element: dart:foo::@enum::E::@field::values
initializer: expression_1
ListLiteral
leftBracket: [ @0
elements
SimpleIdentifier
token: v @-1
element: dart:foo::@enum::E::@getter::v
staticType: E
rightBracket: ] @0
staticType: List<E>
getter2: #F5
getters
#F3 synthetic v
element: dart:foo::@enum::E::@getter::v
returnType: E
variable: #F2
#F5 synthetic values
element: dart:foo::@enum::E::@getter::values
returnType: List<E>
variable: #F4
methods
#F6 foo @62
element: dart:foo::@enum::E::@method::foo
enums
enum E
reference: dart:foo::@enum::E
firstFragment: #F1
sinceSdkVersion: 2.15.0
supertype: Enum
fields
static const enumConstant hasInitializer v
reference: dart:foo::@enum::E::@field::v
firstFragment: #F2
sinceSdkVersion: 2.15.0
type: E
constantInitializer
fragment: #F2
expression: expression_0
getter: dart:foo::@enum::E::@getter::v
synthetic static const values
reference: dart:foo::@enum::E::@field::values
firstFragment: #F4
sinceSdkVersion: 2.15.0
type: List<E>
constantInitializer
fragment: #F4
expression: expression_1
getter: dart:foo::@enum::E::@getter::values
getters
synthetic static v
reference: dart:foo::@enum::E::@getter::v
firstFragment: #F3
sinceSdkVersion: 2.15.0
returnType: E
variable: dart:foo::@enum::E::@field::v
synthetic static values
reference: dart:foo::@enum::E::@getter::values
firstFragment: #F5
sinceSdkVersion: 2.15.0
returnType: List<E>
variable: dart:foo::@enum::E::@field::values
methods
foo
reference: dart:foo::@enum::E::@method::foo
firstFragment: #F6
sinceSdkVersion: 2.15.0
returnType: void
''');
}
test_sinceSdkVersion_extension_method_inherits() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15')
extension E on int {
void foo() {}
}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
extensions
#F1 extension E @51
element: dart:foo::@extension::E
methods
#F2 foo @69
element: dart:foo::@extension::E::@method::foo
extensions
extension E
reference: dart:foo::@extension::E
firstFragment: #F1
sinceSdkVersion: 2.15.0
extendedType: int
methods
foo
reference: dart:foo::@extension::E::@method::foo
firstFragment: #F2
sinceSdkVersion: 2.15.0
returnType: void
''');
}
test_sinceSdkVersion_mixin_method_inherits() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15')
mixin M {
void foo() {}
}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
mixins
#F1 mixin M @47
element: dart:foo::@mixin::M
methods
#F2 foo @58
element: dart:foo::@mixin::M::@method::foo
mixins
mixin M
reference: dart:foo::@mixin::M
firstFragment: #F1
sinceSdkVersion: 2.15.0
superclassConstraints
Object
methods
foo
reference: dart:foo::@mixin::M::@method::foo
firstFragment: #F2
sinceSdkVersion: 2.15.0
returnType: void
''');
}
test_sinceSdkVersion_unit_function() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15')
void foo() {}
void bar() {}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
functions
#F1 foo @46
element: dart:foo::@function::foo
#F2 bar @61
element: dart:foo::@function::bar
functions
foo
reference: dart:foo::@function::foo
firstFragment: #F1
sinceSdkVersion: 2.15.0
returnType: void
bar
reference: dart:foo::@function::bar
firstFragment: #F2
returnType: void
''');
}
test_sinceSdkVersion_unit_function_format_extended() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15.3-dev.7')
void foo() {}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
functions
#F1 foo @54
element: dart:foo::@function::foo
functions
foo
reference: dart:foo::@function::foo
firstFragment: #F1
sinceSdkVersion: 2.15.3-dev.7
returnType: void
''');
}
test_sinceSdkVersion_unit_function_format_full() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15.3')
void foo() {}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
functions
#F1 foo @48
element: dart:foo::@function::foo
functions
foo
reference: dart:foo::@function::foo
firstFragment: #F1
sinceSdkVersion: 2.15.3
returnType: void
''');
}
test_sinceSdkVersion_unit_function_format_invalid() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('42')
void foo() {}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
functions
#F1 foo @44
element: dart:foo::@function::foo
functions
foo
reference: dart:foo::@function::foo
firstFragment: #F1
returnType: void
''');
}
test_sinceSdkVersion_unit_function_inherits() async {
var library = await _buildDartFooLibrary(r'''
@Since('2.15')
library;
import 'dart:_internal';
void foo() {}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
sinceSdkVersion: 2.15.0
fragments
#F0 dart:foo
element: dart:foo
functions
#F1 foo @56
element: dart:foo::@function::foo
functions
foo
reference: dart:foo::@function::foo
firstFragment: #F1
sinceSdkVersion: 2.15.0
returnType: void
''');
}
test_sinceSdkVersion_unit_function_parameters_optionalNamed() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
void f(int p1, {
@Since('2.15')
int? p2,
}) {}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
functions
#F1 f @31
element: dart:foo::@function::f
formalParameters
#F2 p1 @37
element: dart:foo::@function::f::@formalParameter::p1
#F3 default p2 @67
element: dart:foo::@function::f::@formalParameter::p2
functions
f
reference: dart:foo::@function::f
firstFragment: #F1
formalParameters
requiredPositional p1
firstFragment: #F2
type: int
optionalNamed p2
firstFragment: #F3
type: int?
sinceSdkVersion: 2.15.0
returnType: void
''');
}
test_sinceSdkVersion_unit_function_parameters_optionalPositional() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
void f(int p1, [
@Since('2.15')
int? p2,
]) {}
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
functions
#F1 f @31
element: dart:foo::@function::f
formalParameters
#F2 p1 @37
element: dart:foo::@function::f::@formalParameter::p1
#F3 default p2 @67
element: dart:foo::@function::f::@formalParameter::p2
functions
f
reference: dart:foo::@function::f
firstFragment: #F1
formalParameters
requiredPositional p1
firstFragment: #F2
type: int
optionalPositional p2
firstFragment: #F3
type: int?
sinceSdkVersion: 2.15.0
returnType: void
''');
}
test_sinceSdkVersion_unit_typeAlias() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15')
typedef A = List<int>;
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
typeAliases
#F1 A @49
element: dart:foo::@typeAlias::A
typeAliases
A
reference: dart:foo::@typeAlias::A
firstFragment: #F1
sinceSdkVersion: 2.15.0
aliasedType: List<int>
''');
}
test_sinceSdkVersion_unit_variable() async {
var library = await _buildDartFooLibrary(r'''
import 'dart:_internal';
@Since('2.15')
final foo = 0;
''');
configuration.forSinceSdkVersion();
checkElementText(library, r'''
library
reference: dart:foo
fragments
#F0 dart:foo
element: dart:foo
topLevelVariables
#F1 hasInitializer foo @47
element: dart:foo::@topLevelVariable::foo
getter: #F2
getters
#F2 synthetic foo
element: dart:foo::@getter::foo
returnType: int
variable: #F1
topLevelVariables
final hasInitializer foo
reference: dart:foo::@topLevelVariable::foo
firstFragment: #F1
sinceSdkVersion: 2.15.0
type: int
getter: dart:foo::@getter::foo
getters
synthetic static foo
reference: dart:foo::@getter::foo
firstFragment: #F2
sinceSdkVersion: 2.15.0
returnType: int
variable: dart:foo::@topLevelVariable::foo
''');
}
Future<LibraryElementImpl> _buildDartFooLibrary(String content) async {
additionalMockSdkLibraries.add(
MockSdkLibrary('foo', [MockSdkLibraryUnit('foo/foo.dart', content)]),
);
return await _libraryByUriFromTest('dart:foo');
}
/// Returns the library for [uriStr] from the context of [testFile].
Future<LibraryElementImpl> _libraryByUriFromTest(String uriStr) async {
var analysisContext = contextFor(testFile);
var analysisSession = analysisContext.currentSession;
var libraryResult = await analysisSession.getLibraryByUri(uriStr);
libraryResult as LibraryElementResult;
return libraryResult.element2 as LibraryElementImpl;
}
}
@reflectiveTest
class SinceSdkVersionElementTest_fromBytes extends SinceSdkVersionElementTest {
@override
bool get keepLinkingLibraries => false;
}
@reflectiveTest
class SinceSdkVersionElementTest_keepLinking
extends SinceSdkVersionElementTest {
@override
bool get keepLinkingLibraries => true;
}
extension on ElementTextConfiguration {
void forSinceSdkVersion() {
withConstantInitializers = false;
withConstructors = false;
withImports = false;
withMetadata = false;
}
}