blob: 4db5768827abaefecb7965531f3c932c621d7201 [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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
classes
class A @47
reference: dart:foo::<fragment>::@class::A
enclosingElement: dart:foo::<fragment>
sinceSdkVersion: 2.15.0
constructors
named @55
reference: dart:foo::<fragment>::@class::A::@constructor::named
enclosingElement: dart:foo::<fragment>::@class::A
sinceSdkVersion: 2.15.0
periodOffset: 54
nameEnd: 60
class B @73
reference: dart:foo::<fragment>::@class::B
enclosingElement: dart:foo::<fragment>
constructors
named @81
reference: dart:foo::<fragment>::@class::B::@constructor::named
enclosingElement: dart:foo::<fragment>::@class::B
periodOffset: 80
nameEnd: 86
''');
}
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
classes
class A @47
reference: dart:foo::<fragment>::@class::A
enclosingElement: dart:foo::<fragment>
sinceSdkVersion: 2.15.0
fields
foo @57
reference: dart:foo::<fragment>::@class::A::@field::foo
enclosingElement: dart:foo::<fragment>::@class::A
sinceSdkVersion: 2.15.0
type: int
shouldUseTypeForInitializerInference: true
accessors
synthetic get foo @-1
reference: dart:foo::<fragment>::@class::A::@getter::foo
enclosingElement: dart:foo::<fragment>::@class::A
sinceSdkVersion: 2.15.0
returnType: int
synthetic set foo= @-1
reference: dart:foo::<fragment>::@class::A::@setter::foo
enclosingElement: dart:foo::<fragment>::@class::A
sinceSdkVersion: 2.15.0
parameters
requiredPositional _foo @-1
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
classes
class A @47
reference: dart:foo::<fragment>::@class::A
enclosingElement: dart:foo::<fragment>
sinceSdkVersion: 2.15.0
fields
synthetic foo @-1
reference: dart:foo::<fragment>::@class::A::@field::foo
enclosingElement: dart:foo::<fragment>::@class::A
type: int
accessors
get foo @61
reference: dart:foo::<fragment>::@class::A::@getter::foo
enclosingElement: dart:foo::<fragment>::@class::A
sinceSdkVersion: 2.15.0
returnType: int
''');
}
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
classes
class A @47
reference: dart:foo::<fragment>::@class::A
enclosingElement: dart:foo::<fragment>
sinceSdkVersion: 2.15.0
methods
foo @58
reference: dart:foo::<fragment>::@class::A::@method::foo
enclosingElement: dart:foo::<fragment>::@class::A
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
classes
class A @47
reference: dart:foo::<fragment>::@class::A
enclosingElement: dart:foo::<fragment>
sinceSdkVersion: 2.15.0
methods
foo @75
reference: dart:foo::<fragment>::@class::A::@method::foo
enclosingElement: dart:foo::<fragment>::@class::A
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
classes
class A @47
reference: dart:foo::<fragment>::@class::A
enclosingElement: dart:foo::<fragment>
sinceSdkVersion: 2.15.0
methods
foo @75
reference: dart:foo::<fragment>::@class::A::@method::foo
enclosingElement: dart:foo::<fragment>::@class::A
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
classes
class A @47
reference: dart:foo::<fragment>::@class::A
enclosingElement: dart:foo::<fragment>
sinceSdkVersion: 2.15.0
fields
synthetic foo @-1
reference: dart:foo::<fragment>::@class::A::@field::foo
enclosingElement: dart:foo::<fragment>::@class::A
type: int
accessors
set foo= @57
reference: dart:foo::<fragment>::@class::A::@setter::foo
enclosingElement: dart:foo::<fragment>::@class::A
sinceSdkVersion: 2.15.0
parameters
requiredPositional _ @65
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
enums
enum E @31
reference: dart:foo::<fragment>::@enum::E
enclosingElement: dart:foo::<fragment>
supertype: Enum
fields
static const enumConstant v1 @37
reference: dart:foo::<fragment>::@enum::E::@field::v1
enclosingElement: dart:foo::<fragment>::@enum::E
type: E
shouldUseTypeForInitializerInference: false
static const enumConstant v2 @60
reference: dart:foo::<fragment>::@enum::E::@field::v2
enclosingElement: dart:foo::<fragment>::@enum::E
sinceSdkVersion: 2.15.0
type: E
shouldUseTypeForInitializerInference: false
synthetic static const values @-1
reference: dart:foo::<fragment>::@enum::E::@field::values
enclosingElement: dart:foo::<fragment>::@enum::E
type: List<E>
accessors
synthetic static get v1 @-1
reference: dart:foo::<fragment>::@enum::E::@getter::v1
enclosingElement: dart:foo::<fragment>::@enum::E
returnType: E
synthetic static get v2 @-1
reference: dart:foo::<fragment>::@enum::E::@getter::v2
enclosingElement: dart:foo::<fragment>::@enum::E
sinceSdkVersion: 2.15.0
returnType: E
synthetic static get values @-1
reference: dart:foo::<fragment>::@enum::E::@getter::values
enclosingElement: dart:foo::<fragment>::@enum::E
returnType: List<E>
''');
}
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
enums
enum E @46
reference: dart:foo::<fragment>::@enum::E
enclosingElement: dart:foo::<fragment>
sinceSdkVersion: 2.15.0
supertype: Enum
fields
static const enumConstant v @52
reference: dart:foo::<fragment>::@enum::E::@field::v
enclosingElement: dart:foo::<fragment>::@enum::E
sinceSdkVersion: 2.15.0
type: E
shouldUseTypeForInitializerInference: false
synthetic static const values @-1
reference: dart:foo::<fragment>::@enum::E::@field::values
enclosingElement: dart:foo::<fragment>::@enum::E
type: List<E>
accessors
synthetic static get v @-1
reference: dart:foo::<fragment>::@enum::E::@getter::v
enclosingElement: dart:foo::<fragment>::@enum::E
sinceSdkVersion: 2.15.0
returnType: E
synthetic static get values @-1
reference: dart:foo::<fragment>::@enum::E::@getter::values
enclosingElement: dart:foo::<fragment>::@enum::E
returnType: List<E>
methods
foo @62
reference: dart:foo::<fragment>::@enum::E::@method::foo
enclosingElement: dart:foo::<fragment>::@enum::E
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
extensions
E @51
reference: dart:foo::<fragment>::@extension::E
enclosingElement: dart:foo::<fragment>
sinceSdkVersion: 2.15.0
extendedType: int
methods
foo @69
reference: dart:foo::<fragment>::@extension::E::@method::foo
enclosingElement: dart:foo::<fragment>::@extension::E
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
mixins
mixin M @47
reference: dart:foo::<fragment>::@mixin::M
enclosingElement: dart:foo::<fragment>
sinceSdkVersion: 2.15.0
superclassConstraints
Object
methods
foo @58
reference: dart:foo::<fragment>::@mixin::M::@method::foo
enclosingElement: dart:foo::<fragment>::@mixin::M
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
functions
foo @46
reference: dart:foo::<fragment>::@function::foo
enclosingElement: dart:foo::<fragment>
sinceSdkVersion: 2.15.0
returnType: void
bar @61
reference: dart:foo::<fragment>::@function::bar
enclosingElement: dart:foo::<fragment>
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
functions
foo @54
reference: dart:foo::<fragment>::@function::foo
enclosingElement: dart:foo::<fragment>
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
functions
foo @48
reference: dart:foo::<fragment>::@function::foo
enclosingElement: dart:foo::<fragment>
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
functions
foo @44
reference: dart:foo::<fragment>::@function::foo
enclosingElement: dart:foo::<fragment>
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
functions
foo @56
reference: dart:foo::<fragment>::@function::foo
enclosingElement: dart:foo::<fragment>
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
functions
f @31
reference: dart:foo::<fragment>::@function::f
enclosingElement: dart:foo::<fragment>
parameters
requiredPositional p1 @37
type: int
optionalNamed default p2 @67
reference: dart:foo::<fragment>::@function::f::@parameter::p2
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
functions
f @31
reference: dart:foo::<fragment>::@function::f
enclosingElement: dart:foo::<fragment>
parameters
requiredPositional p1 @37
type: int
optionalPositional default p2 @67
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
typeAliases
A @49
reference: dart:foo::<fragment>::@typeAlias::A
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
definingUnit: dart:foo::<fragment>
units
dart:foo::<fragment>
enclosingElement: dart:foo
topLevelVariables
static final foo @47
reference: dart:foo::<fragment>::@topLevelVariable::foo
enclosingElement: dart:foo::<fragment>
sinceSdkVersion: 2.15.0
type: int
shouldUseTypeForInitializerInference: false
accessors
synthetic static get foo @-1
reference: dart:foo::<fragment>::@getter::foo
enclosingElement: dart:foo::<fragment>
sinceSdkVersion: 2.15.0
returnType: int
''');
}
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.element 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;
}
}