blob: 369d0feca32d2b2fd9e50576ad57f6138c51058a [file] [log] [blame]
// Copyright (c) 2015, 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 'dart:async';
import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'element_text.dart';
import 'test_strategies.dart';
/**
* Abstract base class for resynthesizing and comparing elements.
*
* The return type separator: →
*/
abstract class AbstractResynthesizeTest with ResourceProviderMixin {
DeclaredVariables declaredVariables = new DeclaredVariables();
SourceFactory sourceFactory;
MockSdk sdk;
String testFile;
Source testSource;
Set<Source> otherLibrarySources = new Set<Source>();
/**
* Tests may set this to `true` to indicate that a missing file at the time of
* summary resynthesis shouldn't trigger an error.
*/
bool allowMissingFiles = false;
AbstractResynthesizeTest() {
sdk = new MockSdk(resourceProvider: resourceProvider);
sourceFactory = SourceFactory(
[
DartUriResolver(sdk),
ResourceUriResolver(resourceProvider),
],
null,
resourceProvider,
);
testFile = convertPath('/test.dart');
}
void addLibrary(String uri) {
var source = sourceFactory.forUri(uri);
otherLibrarySources.add(source);
}
Source addLibrarySource(String filePath, String contents) {
var source = addSource(filePath, contents);
otherLibrarySources.add(source);
return source;
}
Source addSource(String path, String contents) {
var file = newFile(path, content: contents);
var source = file.createSource();
return source;
}
Source addTestSource(String code, [Uri uri]) {
testSource = addSource(testFile, code);
return testSource;
}
}
/// Mixin containing test cases exercising summary resynthesis. Intended to be
/// applied to a class implementing [ResynthesizeTestStrategy], along with the
/// mixin [ResynthesizeTestHelpers].
mixin ResynthesizeTestCases implements ResynthesizeTestHelpers {
FeatureSet get disableNnbd => FeatureSet.forTesting(sdkVersion: '2.2.2');
FeatureSet get enableExtensionMethods =>
FeatureSet.forTesting(additionalFeatures: [Feature.extension_methods]);
FeatureSet get enableNnbd =>
FeatureSet.forTesting(additionalFeatures: [Feature.non_nullable]);
test_class_abstract() async {
var library = await checkLibrary('abstract class C {}');
checkElementText(library, r'''
abstract class C {
}
''');
}
test_class_alias() async {
var library = await checkLibrary('''
class C = D with E, F, G;
class D {}
class E {}
class F {}
class G {}
''');
checkElementText(library, r'''
class alias C extends D with E, F, G {
synthetic C() = D;
}
class D {
}
class E {
}
class F {
}
class G {
}
''');
}
test_class_alias_abstract() async {
var library = await checkLibrary('''
abstract class C = D with E;
class D {}
class E {}
''');
checkElementText(library, r'''
abstract class alias C extends D with E {
synthetic C() = D;
}
class D {
}
class E {
}
''');
}
test_class_alias_documented() async {
var library = await checkLibrary('''
/**
* Docs
*/
class C = D with E;
class D {}
class E {}
''');
checkElementText(library, r'''
/**
* Docs
*/
class alias C extends D with E {
synthetic C() = D;
}
class D {
}
class E {
}
''');
}
test_class_alias_documented_tripleSlash() async {
var library = await checkLibrary('''
/// aaa
/// b
/// cc
class C = D with E;
class D {}
class E {}
''');
checkElementText(library, r'''
/// aaa
/// b
/// cc
class alias C extends D with E {
synthetic C() = D;
}
class D {
}
class E {
}
''');
}
test_class_alias_documented_withLeadingNonDocumentation() async {
var library = await checkLibrary('''
// Extra comment so doc comment offset != 0
/**
* Docs
*/
class C = D with E;
class D {}
class E {}''');
checkElementText(library, r'''
/**
* Docs
*/
class alias C extends D with E {
synthetic C() = D;
}
class D {
}
class E {
}
''');
}
test_class_alias_generic() async {
var library = await checkLibrary('''
class Z = A with B<int>, C<double>;
class A {}
class B<B1> {}
class C<C1> {}
''');
checkElementText(library, r'''
class alias Z extends A with B<int>, C<double> {
synthetic Z() = A;
}
class A {
}
class B<B1> {
}
class C<C1> {
}
''');
}
test_class_alias_notSimplyBounded_self() async {
var library = await checkLibrary('''
class C<T extends C> = D with E;
class D {}
class E {}
''');
checkElementText(library, r'''
notSimplyBounded class alias C<T extends C<dynamic>> extends D with E {
synthetic C() = D;
}
class D {
}
class E {
}
''');
}
test_class_alias_notSimplyBounded_simple_no_type_parameter_bound() async {
// If no bounds are specified, then the class is simply bounded by syntax
// alone, so there is no reason to assign it a slot.
var library = await checkLibrary('''
class C<T> = D with E;
class D {}
class E {}
''');
checkElementText(library, r'''
class alias C<T> extends D with E {
synthetic C() = D;
}
class D {
}
class E {
}
''');
}
test_class_alias_notSimplyBounded_simple_non_generic() async {
// If no type parameters are specified, then the class is simply bounded, so
// there is no reason to assign it a slot.
var library = await checkLibrary('''
class C = D with E;
class D {}
class E {}
''');
checkElementText(library, r'''
class alias C extends D with E {
synthetic C() = D;
}
class D {
}
class E {
}
''');
}
test_class_alias_with_forwarding_constructors() async {
addLibrarySource('/a.dart', '''
class Base {
Base._priv();
Base();
Base.noArgs();
Base.requiredArg(x);
Base.positionalArg([bool x = true]);
Base.namedArg({int x = 42});
factory Base.fact() => null;
factory Base.fact2() = Base.noArgs;
}
''');
var library = await checkLibrary('''
import "a.dart";
class M {}
class MixinApp = Base with M;
''');
checkElementText(library, r'''
import 'a.dart';
class M {
}
class alias MixinApp extends Base with M {
synthetic MixinApp() = Base;
synthetic MixinApp.noArgs() = Base.noArgs;
synthetic MixinApp.requiredArg(dynamic x) = Base.requiredArg;
synthetic MixinApp.positionalArg([bool x = true]) = Base.positionalArg;
synthetic MixinApp.namedArg({int x: 42}) = Base.namedArg;
synthetic MixinApp.fact() = Base.fact;
synthetic MixinApp.fact2() = Base.fact2;
}
''');
}
test_class_alias_with_forwarding_constructors_type_substitution() async {
var library = await checkLibrary('''
class Base<T> {
Base.ctor(T t, List<T> l);
}
class M {}
class MixinApp = Base with M;
''');
checkElementText(library, r'''
class Base<T> {
Base.ctor(T t, List<T> l);
}
class M {
}
class alias MixinApp extends Base<dynamic> with M {
synthetic MixinApp.ctor(dynamic t, List<dynamic> l) = Base<T>.ctor;
}
''');
}
test_class_alias_with_forwarding_constructors_type_substitution_complex() async {
var library = await checkLibrary('''
class Base<T> {
Base.ctor(T t, List<T> l);
}
class M {}
class MixinApp<U> = Base<List<U>> with M;
''');
checkElementText(library, r'''
class Base<T> {
Base.ctor(T t, List<T> l);
}
class M {
}
class alias MixinApp<U> extends Base<List<U>> with M {
synthetic MixinApp.ctor(List<U> t, List<List<U>> l) = Base<T>.ctor;
}
''');
}
test_class_alias_with_mixin_members() async {
var library = await checkLibrary('''
class C = D with E;
class D {}
class E {
int get a => null;
void set b(int i) {}
void f() {}
int x;
}''');
checkElementText(library, r'''
class alias C extends D with E {
synthetic C() = D;
}
class D {
}
class E {
int x;
int get a {}
void set b(int i) {}
void f() {}
}
''');
}
test_class_constructor_const() async {
var library = await checkLibrary('class C { const C(); }');
checkElementText(library, r'''
class C {
const C();
}
''');
}
test_class_constructor_const_external() async {
var library = await checkLibrary('class C { external const C(); }');
checkElementText(library, r'''
class C {
external const C();
}
''');
}
test_class_constructor_explicit_named() async {
var library = await checkLibrary('class C { C.foo(); }');
checkElementText(library, r'''
class C {
C.foo();
}
''');
}
test_class_constructor_explicit_type_params() async {
var library = await checkLibrary('class C<T, U> { C(); }');
checkElementText(library, r'''
class C<T, U> {
C();
}
''');
}
test_class_constructor_explicit_unnamed() async {
var library = await checkLibrary('class C { C(); }');
checkElementText(library, r'''
class C {
C();
}
''');
}
test_class_constructor_external() async {
var library = await checkLibrary('class C { external C(); }');
checkElementText(library, r'''
class C {
external C();
}
''');
}
test_class_constructor_factory() async {
var library = await checkLibrary('class C { factory C() => null; }');
checkElementText(library, r'''
class C {
factory C();
}
''');
}
test_class_constructor_field_formal_dynamic_dynamic() async {
var library =
await checkLibrary('class C { dynamic x; C(dynamic this.x); }');
checkElementText(library, r'''
class C {
dynamic x;
C(dynamic this.x);
}
''');
}
test_class_constructor_field_formal_dynamic_typed() async {
var library = await checkLibrary('class C { dynamic x; C(int this.x); }');
checkElementText(library, r'''
class C {
dynamic x;
C(int this.x);
}
''');
}
test_class_constructor_field_formal_dynamic_untyped() async {
var library = await checkLibrary('class C { dynamic x; C(this.x); }');
checkElementText(library, r'''
class C {
dynamic x;
C(dynamic this.x);
}
''');
}
test_class_constructor_field_formal_functionTyped_noReturnType() async {
var library = await checkLibrary(r'''
class C {
var x;
C(this.x(double b));
}
''');
checkElementText(library, r'''
class C {
dynamic x;
C(dynamic Function(double) this.x/*(double b)*/);
}
''');
}
test_class_constructor_field_formal_functionTyped_withReturnType() async {
var library = await checkLibrary(r'''
class C {
var x;
C(int this.x(double b));
}
''');
checkElementText(library, r'''
class C {
dynamic x;
C(int Function(double) this.x/*(double b)*/);
}
''');
}
test_class_constructor_field_formal_functionTyped_withReturnType_generic() async {
var library = await checkLibrary(r'''
class C {
Function() f;
C(List<U> this.f<T, U>(T t));
}
''');
checkElementText(library, r'''
class C {
dynamic Function() f;
C(List<U> Function<T, U>(T) this.f/*(T t)*/);
}
''');
}
test_class_constructor_field_formal_multiple_matching_fields() async {
// This is a compile-time error but it should still analyze consistently.
var library = await checkLibrary('class C { C(this.x); int x; String x; }',
allowErrors: true);
checkElementText(library, r'''
class C {
int x;
String x;
C(int this.x);
}
''');
}
test_class_constructor_field_formal_no_matching_field() async {
// This is a compile-time error but it should still analyze consistently.
var library =
await checkLibrary('class C { C(this.x); }', allowErrors: true);
checkElementText(library, r'''
class C {
C(dynamic this.x);
}
''');
}
test_class_constructor_field_formal_typed_dynamic() async {
var library = await checkLibrary('class C { num x; C(dynamic this.x); }',
allowErrors: true);
checkElementText(library, r'''
class C {
num x;
C(dynamic this.x);
}
''');
}
test_class_constructor_field_formal_typed_typed() async {
var library = await checkLibrary('class C { num x; C(int this.x); }');
checkElementText(library, r'''
class C {
num x;
C(int this.x);
}
''');
}
test_class_constructor_field_formal_typed_untyped() async {
var library = await checkLibrary('class C { num x; C(this.x); }');
checkElementText(library, r'''
class C {
num x;
C(num this.x);
}
''');
}
test_class_constructor_field_formal_untyped_dynamic() async {
var library = await checkLibrary('class C { var x; C(dynamic this.x); }');
checkElementText(library, r'''
class C {
dynamic x;
C(dynamic this.x);
}
''');
}
test_class_constructor_field_formal_untyped_typed() async {
var library = await checkLibrary('class C { var x; C(int this.x); }');
checkElementText(library, r'''
class C {
dynamic x;
C(int this.x);
}
''');
}
test_class_constructor_field_formal_untyped_untyped() async {
var library = await checkLibrary('class C { var x; C(this.x); }');
checkElementText(library, r'''
class C {
dynamic x;
C(dynamic this.x);
}
''');
}
test_class_constructor_fieldFormal_named_noDefault() async {
var library = await checkLibrary('class C { int x; C({this.x}); }');
checkElementText(library, r'''
class C {
int x;
C({int this.x});
}
''');
}
test_class_constructor_fieldFormal_named_withDefault() async {
var library = await checkLibrary('class C { int x; C({this.x: 42}); }');
checkElementText(library, r'''
class C {
int x;
C({int this.x: 42});
}
''');
}
test_class_constructor_fieldFormal_optional_noDefault() async {
var library = await checkLibrary('class C { int x; C([this.x]); }');
checkElementText(library, r'''
class C {
int x;
C([int this.x]);
}
''');
}
test_class_constructor_fieldFormal_optional_withDefault() async {
var library = await checkLibrary('class C { int x; C([this.x = 42]); }');
checkElementText(library, r'''
class C {
int x;
C([int this.x = 42]);
}
''');
}
test_class_constructor_implicit() async {
var library = await checkLibrary('class C {}');
checkElementText(library, r'''
class C {
}
''');
}
test_class_constructor_implicit_type_params() async {
var library = await checkLibrary('class C<T, U> {}');
checkElementText(library, r'''
class C<T, U> {
}
''');
}
test_class_constructor_params() async {
var library = await checkLibrary('class C { C(x, int y); }');
checkElementText(library, r'''
class C {
C(dynamic x, int y);
}
''');
}
test_class_constructors() async {
var library = await checkLibrary('class C { C.foo(); C.bar(); }');
checkElementText(library, r'''
class C {
C.foo();
C.bar();
}
''');
}
test_class_documented() async {
var library = await checkLibrary('''
/**
* Docs
*/
class C {}''');
checkElementText(library, r'''
/**
* Docs
*/
class C {
}
''');
}
test_class_documented_mix() async {
var library = await checkLibrary('''
/**
* aaa
*/
/**
* bbb
*/
class A {}
/**
* aaa
*/
/// bbb
/// ccc
class B {}
/// aaa
/// bbb
/**
* ccc
*/
class C {}
/// aaa
/// bbb
/**
* ccc
*/
/// ddd
class D {}
/**
* aaa
*/
// bbb
class E {}
''');
checkElementText(library, r'''
/**
* bbb
*/
class A {
}
/// bbb
/// ccc
class B {
}
/**
* ccc
*/
class C {
}
/// ddd
class D {
}
/**
* aaa
*/
class E {
}
''');
}
test_class_documented_tripleSlash() async {
var library = await checkLibrary('''
/// aaa
/// bbbb
/// cc
class C {}''');
checkElementText(library, r'''
/// aaa
/// bbbb
/// cc
class C {
}
''');
}
test_class_documented_with_references() async {
var library = await checkLibrary('''
/**
* Docs referring to [D] and [E]
*/
class C {}
class D {}
class E {}''');
checkElementText(library, r'''
/**
* Docs referring to [D] and [E]
*/
class C {
}
class D {
}
class E {
}
''');
}
test_class_documented_with_windows_line_endings() async {
var library = await checkLibrary('/**\r\n * Docs\r\n */\r\nclass C {}');
checkElementText(library, r'''
/**
* Docs
*/
class C {
}
''');
}
test_class_documented_withLeadingNotDocumentation() async {
var library = await checkLibrary('''
// Extra comment so doc comment offset != 0
/**
* Docs
*/
class C {}''');
checkElementText(library, r'''
/**
* Docs
*/
class C {
}
''');
}
test_class_documented_withMetadata() async {
var library = await checkLibrary('''
/// Comment 1
/// Comment 2
@Annotation()
class BeforeMeta {}
/// Comment 1
/// Comment 2
@Annotation.named()
class BeforeMetaNamed {}
@Annotation()
/// Comment 1
/// Comment 2
class AfterMeta {}
/// Comment 1
@Annotation()
/// Comment 2
class AroundMeta {}
/// Doc comment.
@Annotation()
// Not doc comment.
class DocBeforeMetaNotDocAfter {}
class Annotation {
const Annotation();
const Annotation.named();
}
''');
checkElementText(
library,
r'''
/// Comment 1
/// Comment 2
@Annotation()
class BeforeMeta {
}
/// Comment 1
/// Comment 2
@Annotation.named()
class BeforeMetaNamed {
}
/// Comment 1
/// Comment 2
@Annotation()
class AfterMeta {
}
/// Comment 2
@Annotation()
class AroundMeta {
}
/// Doc comment.
@Annotation()
class DocBeforeMetaNotDocAfter {
}
class Annotation {
const Annotation();
const Annotation.named();
}
''',
withConstElements: false);
}
test_class_field_const() async {
var library = await checkLibrary('class C { static const int i = 0; }');
checkElementText(library, r'''
class C {
static const int i = 0;
}
''');
}
test_class_field_const_late() async {
featureSet = enableNnbd;
var library =
await checkLibrary('class C { static late const int i = 0; }');
checkElementText(library, r'''
class C {
static late const int i = 0;
}
''');
}
test_class_field_implicit_type() async {
var library = await checkLibrary('class C { var x; }');
checkElementText(library, r'''
class C {
dynamic x;
}
''');
}
test_class_field_implicit_type_late() async {
featureSet = enableNnbd;
var library = await checkLibrary('class C { late var x; }');
checkElementText(library, r'''
class C {
late dynamic x;
}
''');
}
test_class_field_static() async {
var library = await checkLibrary('class C { static int i; }');
checkElementText(library, r'''
class C {
static int i;
}
''');
}
test_class_field_static_late() async {
featureSet = enableNnbd;
var library = await checkLibrary('class C { static late int i; }');
checkElementText(library, r'''
class C {
static late int i;
}
''');
}
test_class_fields() async {
var library = await checkLibrary('class C { int i; int j; }');
checkElementText(library, r'''
class C {
int i;
int j;
}
''');
}
test_class_fields_late() async {
featureSet = enableNnbd;
var library = await checkLibrary('class C { int i; late int j; }');
checkElementText(library, r'''
class C {
int i;
late int j;
}
''');
}
test_class_getter_abstract() async {
var library = await checkLibrary('abstract class C { int get x; }');
checkElementText(library, r'''
abstract class C {
int get x;
}
''');
}
test_class_getter_external() async {
var library = await checkLibrary('class C { external int get x; }');
checkElementText(library, r'''
class C {
external int get x;
}
''');
}
test_class_getter_implicit_return_type() async {
var library = await checkLibrary('class C { get x => null; }');
checkElementText(library, r'''
class C {
dynamic get x {}
}
''');
}
test_class_getter_native() async {
var library = await checkLibrary('''
class C {
int get x() native;
}
''');
checkElementText(library, r'''
class C {
external int get x;
}
''');
}
test_class_getter_static() async {
var library = await checkLibrary('class C { static int get x => null; }');
checkElementText(library, r'''
class C {
static int get x {}
}
''');
}
test_class_getters() async {
var library =
await checkLibrary('class C { int get x => null; get y => null; }');
checkElementText(library, r'''
class C {
int get x {}
dynamic get y {}
}
''');
}
test_class_implicitField_getterFirst() async {
var library = await checkLibrary('''
class C {
int get x => 0;
void set x(int value) {}
}
''');
checkElementText(library, r'''
class C {
int get x {}
void set x(int value) {}
}
''');
}
test_class_implicitField_setterFirst() async {
var library = await checkLibrary('''
class C {
void set x(int value) {}
int get x => 0;
}
''');
checkElementText(library, r'''
class C {
void set x(int value) {}
int get x {}
}
''');
}
test_class_interfaces() async {
var library = await checkLibrary('''
class C implements D, E {}
class D {}
class E {}
''');
checkElementText(library, r'''
class C implements D, E {
}
class D {
}
class E {
}
''');
}
test_class_interfaces_unresolved() async {
var library = await checkLibrary(
'class C implements X, Y, Z {} class X {} class Z {}',
allowErrors: true);
checkElementText(library, r'''
class C implements X, Z {
}
class X {
}
class Z {
}
''');
}
test_class_method_abstract() async {
var library = await checkLibrary('abstract class C { f(); }');
checkElementText(library, r'''
abstract class C {
dynamic f();
}
''');
}
test_class_method_external() async {
var library = await checkLibrary('class C { external f(); }');
checkElementText(library, r'''
class C {
external dynamic f() {}
}
''');
}
test_class_method_namedAsSupertype() async {
var library = await checkLibrary(r'''
class A {}
class B extends A {
void A() {}
}
''');
checkElementText(library, r'''
class A {
}
class B extends A {
void A() {}
}
''');
}
test_class_method_native() async {
var library = await checkLibrary('''
class C {
int m() native;
}
''');
checkElementText(library, r'''
class C {
external int m() {}
}
''');
}
test_class_method_params() async {
var library = await checkLibrary('class C { f(x, y) {} }');
checkElementText(library, r'''
class C {
dynamic f(dynamic x, dynamic y) {}
}
''');
}
test_class_method_static() async {
var library = await checkLibrary('class C { static f() {} }');
checkElementText(library, r'''
class C {
static dynamic f() {}
}
''');
}
test_class_methods() async {
var library = await checkLibrary('class C { f() {} g() {} }');
checkElementText(library, r'''
class C {
dynamic f() {}
dynamic g() {}
}
''');
}
test_class_mixins() async {
var library = await checkLibrary('''
class C extends D with E, F, G {}
class D {}
class E {}
class F {}
class G {}
''');
checkElementText(library, r'''
class C extends D with E, F, G {
synthetic C();
}
class D {
}
class E {
}
class F {
}
class G {
}
''');
}
test_class_mixins_generic() async {
var library = await checkLibrary('''
class Z extends A with B<int>, C<double> {}
class A {}
class B<B1> {}
class C<C1> {}
''');
checkElementText(library, r'''
class Z extends A with B<int>, C<double> {
synthetic Z();
}
class A {
}
class B<B1> {
}
class C<C1> {
}
''');
}
test_class_mixins_unresolved() async {
var library = await checkLibrary(
'class C extends Object with X, Y, Z {} class X {} class Z {}',
allowErrors: true);
checkElementText(library, r'''
class C extends Object with X, Z {
synthetic C();
}
class X {
}
class Z {
}
''');
}
test_class_notSimplyBounded_circularity_via_typedef() async {
// C's type parameter T is not simply bounded because its bound, F, expands
// to `dynamic F(C)`, which refers to C.
var library = await checkLibrary('''
class C<T extends F> {}
typedef F(C value);
''');
checkElementText(library, r'''
notSimplyBounded typedef F = dynamic Function(C<dynamic> value);
notSimplyBounded class C<T extends dynamic Function(C<dynamic>)> {
}
''');
}
test_class_notSimplyBounded_circularity_with_type_params() async {
// C's type parameter T is simply bounded because even though it refers to
// C, it specifies a bound.
var library = await checkLibrary('''
class C<T extends C<dynamic>> {}
''');
checkElementText(library, r'''
class C<T extends C<dynamic>> {
}
''');
}
test_class_notSimplyBounded_complex_by_cycle() async {
var library = await checkLibrary('''
class C<T extends D> {}
class D<T extends C> {}
''');
checkElementText(library, r'''
notSimplyBounded class C<T extends D<dynamic>> {
}
notSimplyBounded class D<T extends C<dynamic>> {
}
''');
}
test_class_notSimplyBounded_complex_by_reference_to_cycle() async {
var library = await checkLibrary('''
class C<T extends D> {}
class D<T extends D> {}
''');
checkElementText(library, r'''
notSimplyBounded class C<T extends D<dynamic>> {
}
notSimplyBounded class D<T extends D<dynamic>> {
}
''');
}
test_class_notSimplyBounded_complex_by_use_of_parameter() async {
var library = await checkLibrary('''
class C<T extends D<T>> {}
class D<T> {}
''');
checkElementText(library, r'''
notSimplyBounded class C<T extends D<T>> {
}
class D<T> {
}
''');
}
test_class_notSimplyBounded_dependency_with_type_params() async {
// C's type parameter T is simply bounded because even though it refers to
// non-simply-bounded type D, it specifies a bound.
var library = await checkLibrary('''
class C<T extends D<dynamic>> {}
class D<T extends D<T>> {}
''');
checkElementText(library, r'''
class C<T extends D<dynamic>> {
}
notSimplyBounded class D<T extends D<T>> {
}
''');
}
test_class_notSimplyBounded_function_typed_bound_complex_via_parameter_type() async {
var library = await checkLibrary('''
class C<T extends void Function(T)> {}
''');
checkElementText(library, r'''
notSimplyBounded class C<T extends void Function(T)> {
}
''');
}
test_class_notSimplyBounded_function_typed_bound_complex_via_return_type() async {
var library = await checkLibrary('''
class C<T extends T Function()> {}
''');
checkElementText(library, r'''
notSimplyBounded class C<T extends T Function()> {
}
''');
}
test_class_notSimplyBounded_function_typed_bound_simple() async {
var library = await checkLibrary('''
class C<T extends void Function()> {}
''');
checkElementText(library, r'''
class C<T extends void Function()> {
}
''');
}
test_class_notSimplyBounded_refers_to_circular_typedef() async {
// C's type parameter T has a bound of F, which is a circular typedef. This
// is illegal in Dart, but we need to make sure it doesn't lead to a crash
// or infinite loop.
var library = await checkLibrary('''
class C<T extends F> {}
typedef F(G value);
typedef G(F value);
''');
checkElementText(library, r'''
notSimplyBounded typedef F = dynamic Function(dynamic Function(dynamic Function(dynamic)) value);
notSimplyBounded typedef G = dynamic Function(dynamic Function(dynamic) value);
notSimplyBounded class C<T extends dynamic Function(dynamic Function(dynamic Function(dynamic)))> {
}
''');
}
test_class_notSimplyBounded_self() async {
var library = await checkLibrary('''
class C<T extends C> {}
''');
checkElementText(library, r'''
notSimplyBounded class C<T extends C<dynamic>> {
}
''');
}
test_class_notSimplyBounded_simple_because_non_generic() async {
// If no type parameters are specified, then the class is simply bounded, so
// there is no reason to assign it a slot.
var library = await checkLibrary('''
class C {}
''');
checkElementText(library, r'''
class C {
}
''');
}
test_class_notSimplyBounded_simple_by_lack_of_cycles() async {
var library = await checkLibrary('''
class C<T extends D> {}
class D<T> {}
''');
checkElementText(library, r'''
class C<T extends D<dynamic>> {
}
class D<T> {
}
''');
}
test_class_notSimplyBounded_simple_by_syntax() async {
// If no bounds are specified, then the class is simply bounded by syntax
// alone, so there is no reason to assign it a slot.
var library = await checkLibrary('''
class C<T> {}
''');
checkElementText(library, r'''
class C<T> {
}
''');
}
test_class_ref_nullability_none() async {
featureSet = enableNnbd;
var library = await checkLibrary('''
class C {}
C c;
''');
checkElementText(
library,
'''
class C {
}
C c;
''',
annotateNullability: true);
}
test_class_ref_nullability_question() async {
featureSet = enableNnbd;
var library = await checkLibrary('''
class C {}
C? c;
''');
checkElementText(
library,
'''
class C {
}
C? c;
''',
annotateNullability: true);
}
test_class_ref_nullability_star() async {
featureSet = disableNnbd;
var library = await checkLibrary('''
class C {}
C c;
''');
checkElementText(
library,
'''
class C {
}
C* c;
''',
annotateNullability: true);
}
test_class_setter_abstract() async {
var library =
await checkLibrary('abstract class C { void set x(int value); }');
checkElementText(library, r'''
abstract class C {
void set x(int value);
}
''');
}
test_class_setter_external() async {
var library =
await checkLibrary('class C { external void set x(int value); }');
checkElementText(library, r'''
class C {
external void set x(int value);
}
''');
}
test_class_setter_implicit_param_type() async {
var library = await checkLibrary('class C { void set x(value) {} }');
checkElementText(library, r'''
class C {
void set x(dynamic value) {}
}
''');
}
test_class_setter_implicit_return_type() async {
var library = await checkLibrary('class C { set x(int value) {} }');
checkElementText(library, r'''
class C {
void set x(int value) {}
}
''');
}
test_class_setter_invalid_named_parameter() async {
var library = await checkLibrary('class C { void set x({a}) {} }');
checkElementText(library, r'''
class C {
void set x({dynamic a}) {}
}
''');
}
test_class_setter_invalid_no_parameter() async {
var library = await checkLibrary('class C { void set x() {} }');
checkElementText(library, r'''
class C {
void set x() {}
}
''');
}
test_class_setter_invalid_optional_parameter() async {
var library = await checkLibrary('class C { void set x([a]) {} }');
checkElementText(library, r'''
class C {
void set x([dynamic a]) {}
}
''');
}
test_class_setter_invalid_too_many_parameters() async {
var library = await checkLibrary('class C { void set x(a, b) {} }');
checkElementText(library, r'''
class C {
void set x(dynamic a, dynamic b) {}
}
''');
}
test_class_setter_native() async {
var library = await checkLibrary('''
class C {
void set x(int value) native;
}
''');
checkElementText(library, r'''
class C {
external void set x(int value);
}
''');
}
test_class_setter_static() async {
var library =
await checkLibrary('class C { static void set x(int value) {} }');
checkElementText(library, r'''
class C {
static void set x(int value) {}
}
''');
}
test_class_setters() async {
var library = await checkLibrary('''
class C {
void set x(int value) {}
set y(value) {}
}
''');
checkElementText(library, r'''
class C {
void set x(int value) {}
void set y(dynamic value) {}
}
''');
}
test_class_supertype() async {
var library = await checkLibrary('''
class C extends D {}
class D {}
''');
checkElementText(library, r'''
class C extends D {
}
class D {
}
''');
}
test_class_supertype_typeArguments() async {
var library = await checkLibrary('''
class C extends D<int, double> {}
class D<T1, T2> {}
''');
checkElementText(library, r'''
class C extends D<int, double> {
}
class D<T1, T2> {
}
''');
}
test_class_supertype_typeArguments_self() async {
var library = await checkLibrary('''
class A<T> {}
class B extends A<B> {}
''');
checkElementText(library, r'''
class A<T> {
}
class B extends A<B> {
}
''');
}
test_class_supertype_unresolved() async {
var library = await checkLibrary('class C extends D {}', allowErrors: true);
checkElementText(library, r'''
class C {
}
''');
}
test_class_type_parameters() async {
var library = await checkLibrary('class C<T, U> {}');
checkElementText(library, r'''
class C<T, U> {
}
''');
}
test_class_type_parameters_bound() async {
var library = await checkLibrary('''
class C<T extends Object, U extends D> {}
class D {}
''');
checkElementText(library, r'''
class C<T, U extends D> {
}
class D {
}
''');
}
test_class_type_parameters_f_bound_complex() async {
var library = await checkLibrary('class C<T extends List<U>, U> {}');
checkElementText(library, r'''
notSimplyBounded class C<T extends List<U>, U> {
}
''');
}
test_class_type_parameters_f_bound_simple() async {
var library = await checkLibrary('class C<T extends U, U> {}');
checkElementText(library, r'''
notSimplyBounded class C<T extends U, U> {
}
''');
}
test_classes() async {
var library = await checkLibrary('class C {} class D {}');
checkElementText(library, r'''
class C {
}
class D {
}
''');
}
test_closure_executable_with_return_type_from_closure() async {
var library = await checkLibrary('''
f() {
print(() {});
print(() => () => 0);
}
''');
checkElementText(library, r'''
dynamic f() {}
''');
}
test_closure_generic() async {
var library = await checkLibrary(r'''
final f = <U, V>(U x, V y) => y;
''');
checkElementText(library, r'''
final V Function<U, V>(U, V) f;
''');
}
test_closure_in_variable_declaration_in_part() async {
addSource('/a.dart', 'part of lib; final f = (int i) => i.toDouble();');
var library = await checkLibrary('''
library lib;
part "a.dart";
''');
checkElementText(library, r'''
library lib;
part 'a.dart';
--------------------
unit: a.dart
final double Function(int) f;
''');
}
test_codeRange_class() async {
var library = await checkLibrary('''
class Raw {}
/// Comment 1.
/// Comment 2.
class HasDocComment {}
@Object()
class HasAnnotation {}
@Object()
/// Comment 1.
/// Comment 2.
class AnnotationThenComment {}
/// Comment 1.
/// Comment 2.
@Object()
class CommentThenAnnotation {}
/// Comment 1.
@Object()
/// Comment 2.
class CommentAroundAnnotation {}
''');
checkElementText(
library,
r'''
class Raw/*codeOffset=0, codeLength=12*/ {
}
/// Comment 1.
/// Comment 2.
class HasDocComment/*codeOffset=14, codeLength=52*/ {
}
@Object()
class HasAnnotation/*codeOffset=68, codeLength=32*/ {
}
/// Comment 1.
/// Comment 2.
@Object()
class AnnotationThenComment/*codeOffset=102, codeLength=70*/ {
}
/// Comment 1.
/// Comment 2.
@Object()
class CommentThenAnnotation/*codeOffset=174, codeLength=70*/ {
}
/// Comment 2.
@Object()
class CommentAroundAnnotation/*codeOffset=261, codeLength=57*/ {
}
''',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_class_namedMixin() async {
var library = await checkLibrary('''
class A {}
class B {}
class Raw = Object with A, B;
/// Comment 1.
/// Comment 2.
class HasDocComment = Object with A, B;
@Object()
class HasAnnotation = Object with A, B;
@Object()
/// Comment 1.
/// Comment 2.
class AnnotationThenComment = Object with A, B;
/// Comment 1.
/// Comment 2.
@Object()
class CommentThenAnnotation = Object with A, B;
/// Comment 1.
@Object()
/// Comment 2.
class CommentAroundAnnotation = Object with A, B;
''');
checkElementText(
library,
r'''
class A/*codeOffset=0, codeLength=10*/ {
}
class B/*codeOffset=12, codeLength=10*/ {
}
class alias Raw/*codeOffset=28, codeLength=29*/ extends Object with A, B {
synthetic Raw() = Object;
}
/// Comment 1.
/// Comment 2.
class alias HasDocComment/*codeOffset=59, codeLength=69*/ extends Object with A, B {
synthetic HasDocComment() = Object;
}
@Object()
class alias HasAnnotation/*codeOffset=130, codeLength=49*/ extends Object with A, B {
synthetic HasAnnotation() = Object;
}
/// Comment 1.
/// Comment 2.
@Object()
class alias AnnotationThenComment/*codeOffset=181, codeLength=87*/ extends Object with A, B {
synthetic AnnotationThenComment() = Object;
}
/// Comment 1.
/// Comment 2.
@Object()
class alias CommentThenAnnotation/*codeOffset=270, codeLength=87*/ extends Object with A, B {
synthetic CommentThenAnnotation() = Object;
}
/// Comment 2.
@Object()
class alias CommentAroundAnnotation/*codeOffset=374, codeLength=74*/ extends Object with A, B {
synthetic CommentAroundAnnotation() = Object;
}
''',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_constructor() async {
var library = await checkLibrary('''
class C {
C();
C.raw() {}
/// Comment 1.
/// Comment 2.
C.hasDocComment() {}
@Object()
C.hasAnnotation() {}
@Object()
/// Comment 1.
/// Comment 2.
C.annotationThenComment() {}
/// Comment 1.
/// Comment 2.
@Object()
C.commentThenAnnotation() {}
/// Comment 1.
@Object()
/// Comment 2.
C.commentAroundAnnotation() {}
}
''');
checkElementText(
library,
r'''
class C/*codeOffset=0, codeLength=362*/ {
C/*codeOffset=12, codeLength=4*/();
C.raw/*codeOffset=20, codeLength=10*/();
/// Comment 1.
/// Comment 2.
C.hasDocComment/*codeOffset=34, codeLength=54*/();
@Object()
C.hasAnnotation/*codeOffset=92, codeLength=32*/();
/// Comment 1.
/// Comment 2.
@Object()
C.annotationThenComment/*codeOffset=128, codeLength=74*/();
/// Comment 1.
/// Comment 2.
@Object()
C.commentThenAnnotation/*codeOffset=206, codeLength=74*/();
/// Comment 2.
@Object()
C.commentAroundAnnotation/*codeOffset=301, codeLength=59*/();
}
''',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_constructor_factory() async {
var library = await checkLibrary('''
class C {
factory C() => null;
factory C.raw() => null;
/// Comment 1.
/// Comment 2.
factory C.hasDocComment() => null;
@Object()
factory C.hasAnnotation() => null;
@Object()
/// Comment 1.
/// Comment 2.
factory C.annotationThenComment() => null;
/// Comment 1.
/// Comment 2.
@Object()
factory C.commentThenAnnotation() => null;
/// Comment 1.
@Object()
/// Comment 2.
factory C.commentAroundAnnotation() => null;
}
''');
checkElementText(
library,
r'''
class C/*codeOffset=0, codeLength=462*/ {
factory C/*codeOffset=12, codeLength=20*/();
factory C.raw/*codeOffset=36, codeLength=24*/();
/// Comment 1.
/// Comment 2.
factory C.hasDocComment/*codeOffset=64, codeLength=68*/();
@Object()
factory C.hasAnnotation/*codeOffset=136, codeLength=46*/();
/// Comment 1.
/// Comment 2.
@Object()
factory C.annotationThenComment/*codeOffset=186, codeLength=88*/();
/// Comment 1.
/// Comment 2.
@Object()
factory C.commentThenAnnotation/*codeOffset=278, codeLength=88*/();
/// Comment 2.
@Object()
factory C.commentAroundAnnotation/*codeOffset=387, codeLength=73*/();
}
''',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_enum() async {
var library = await checkLibrary('''
enum E {
aaa, bbb, ccc
}
''');
checkElementText(
library,
r'''
enum E/*codeOffset=0, codeLength=26*/ {
synthetic final int index/*codeOffset=null, codeLength=null*/;
synthetic static const List<E> values/*codeOffset=null, codeLength=null*/;
static const E aaa/*codeOffset=11, codeLength=3*/;
static const E bbb/*codeOffset=16, codeLength=3*/;
static const E ccc/*codeOffset=21, codeLength=3*/;
String toString/*codeOffset=null, codeLength=null*/() {}
}
''',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_extensions() async {
featureSet = enableExtensionMethods;
var library = await checkLibrary('''
class A {}
extension Raw on A {}
/// Comment 1.
/// Comment 2.
extension HasDocComment on A {}
@Object()
extension HasAnnotation on A {}
@Object()
/// Comment 1.
/// Comment 2.
extension AnnotationThenComment on A {}
/// Comment 1.
/// Comment 2.
@Object()
extension CommentThenAnnotation on A {}
/// Comment 1.
@Object()
/// Comment 2.
extension CommentAroundAnnotation on A {}
''');
checkElementText(
library,
r'''
class A/*codeOffset=0, codeLength=10*/ {
}
extension Raw/*codeOffset=12, codeLength=21*/ on A {
}
/// Comment 1.
/// Comment 2.
extension HasDocComment/*codeOffset=35, codeLength=61*/ on A {
}
@Object()
extension HasAnnotation/*codeOffset=98, codeLength=41*/ on A {
}
/// Comment 1.
/// Comment 2.
@Object()
extension AnnotationThenComment/*codeOffset=141, codeLength=79*/ on A {
}
/// Comment 1.
/// Comment 2.
@Object()
extension CommentThenAnnotation/*codeOffset=222, codeLength=79*/ on A {
}
/// Comment 2.
@Object()
extension CommentAroundAnnotation/*codeOffset=318, codeLength=66*/ on A {
}
''',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_field() async {
var library = await checkLibrary('''
class C {
int withInit = 1;
int withoutInit;
int multiWithInit = 2, multiWithoutInit, multiWithInit2 = 3;
}
''');
checkElementText(
library,
r'''
class C/*codeOffset=0, codeLength=116*/ {
int withInit/*codeOffset=12, codeLength=16*/;
int withoutInit/*codeOffset=33, codeLength=15*/;
int multiWithInit/*codeOffset=53, codeLength=21*/;
int multiWithoutInit/*codeOffset=76, codeLength=16*/;
int multiWithInit2/*codeOffset=94, codeLength=18*/;
}
''',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_field_annotations() async {
var library = await checkLibrary('''
class C {
/// Comment 1.
/// Comment 2.
int hasDocComment, hasDocComment2;
@Object()
int hasAnnotation, hasAnnotation2;
@Object()
/// Comment 1.
/// Comment 2.
int annotationThenComment, annotationThenComment2;
/// Comment 1.
/// Comment 2.
@Object()
int commentThenAnnotation, commentThenAnnotation2;
/// Comment 1.
@Object()
/// Comment 2.
int commentAroundAnnotation, commentAroundAnnotation2;
}
''');
checkElementText(
library,
r'''
class C/*codeOffset=0, codeLength=436*/ {
/// Comment 1.
/// Comment 2.
int hasDocComment/*codeOffset=12, codeLength=51*/;
/// Comment 1.
/// Comment 2.
int hasDocComment2/*codeOffset=65, codeLength=14*/;
@Object()
int hasAnnotation/*codeOffset=84, codeLength=29*/;
@Object()
int hasAnnotation2/*codeOffset=115, codeLength=14*/;
/// Comment 1.
/// Comment 2.
@Object()
int annotationThenComment/*codeOffset=134, codeLength=71*/;
/// Comment 1.
/// Comment 2.
@Object()
int annotationThenComment2/*codeOffset=207, codeLength=22*/;
/// Comment 1.
/// Comment 2.
@Object()
int commentThenAnnotation/*codeOffset=234, codeLength=71*/;
/// Comment 1.
/// Comment 2.
@Object()
int commentThenAnnotation2/*codeOffset=307, codeLength=22*/;
/// Comment 2.
@Object()
int commentAroundAnnotation/*codeOffset=351, codeLength=56*/;
/// Comment 2.
@Object()
int commentAroundAnnotation2/*codeOffset=409, codeLength=24*/;
}
''',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_function() async {
var library = await checkLibrary('''
void raw() {}
/// Comment 1.
/// Comment 2.
void hasDocComment() {}
@Object()
void hasAnnotation() {}
@Object()
/// Comment 1.
/// Comment 2.
void annotationThenComment() {}
/// Comment 1.
/// Comment 2.
@Object()
void commentThenAnnotation() {}
/// Comment 1.
@Object()
/// Comment 2.
void commentAroundAnnotation() {}
''');
checkElementText(
library,
r'''
void raw/*codeOffset=0, codeLength=13*/() {}
/// Comment 1.
/// Comment 2.
void hasDocComment/*codeOffset=15, codeLength=53*/() {}
@Object()
void hasAnnotation/*codeOffset=70, codeLength=33*/() {}
/// Comment 1.
/// Comment 2.
@Object()
void annotationThenComment/*codeOffset=105, codeLength=71*/() {}
/// Comment 1.
/// Comment 2.
@Object()
void commentThenAnnotation/*codeOffset=178, codeLength=71*/() {}
/// Comment 2.
@Object()
void commentAroundAnnotation/*codeOffset=266, codeLength=58*/() {}
''',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_functionTypeAlias() async {
var library = await checkLibrary('''
typedef Raw();
/// Comment 1.
/// Comment 2.
typedef HasDocComment();
@Object()
typedef HasAnnotation();
@Object()
/// Comment 1.
/// Comment 2.
typedef AnnotationThenComment();
/// Comment 1.
/// Comment 2.
@Object()
typedef CommentThenAnnotation();
/// Comment 1.
@Object()
/// Comment 2.
typedef CommentAroundAnnotation();
''');
checkElementText(
library,
r'''
typedef Raw/*codeOffset=0, codeLength=14*/ = dynamic Function();
/// Comment 1.
/// Comment 2.
typedef HasDocComment/*codeOffset=16, codeLength=54*/ = dynamic Function();
@Object()
typedef HasAnnotation/*codeOffset=72, codeLength=34*/ = dynamic Function();
/// Comment 1.
/// Comment 2.
@Object()
typedef AnnotationThenComment/*codeOffset=108, codeLength=72*/ = dynamic Function();
/// Comment 1.
/// Comment 2.
@Object()
typedef CommentThenAnnotation/*codeOffset=182, codeLength=72*/ = dynamic Function();
/// Comment 2.
@Object()
typedef CommentAroundAnnotation/*codeOffset=271, codeLength=59*/ = dynamic Function();
''',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_genericTypeAlias() async {
var library = await checkLibrary('''
typedef Raw = Function();
/// Comment 1.
/// Comment 2.
typedef HasDocComment = Function();
@Object()
typedef HasAnnotation = Function();
@Object()
/// Comment 1.
/// Comment 2.
typedef AnnotationThenComment = Function();
/// Comment 1.
/// Comment 2.
@Object()
typedef CommentThenAnnotation = Function();
/// Comment 1.
@Object()
/// Comment 2.
typedef CommentAroundAnnotation = Function();
''');
checkElementText(
library,
r'''
typedef Raw/*codeOffset=0, codeLength=25*/ = dynamic Function();
/// Comment 1.
/// Comment 2.
typedef HasDocComment/*codeOffset=27, codeLength=65*/ = dynamic Function();
@Object()
typedef HasAnnotation/*codeOffset=94, codeLength=45*/ = dynamic Function();
/// Comment 1.
/// Comment 2.
@Object()
typedef AnnotationThenComment/*codeOffset=141, codeLength=83*/ = dynamic Function();
/// Comment 1.
/// Comment 2.
@Object()
typedef CommentThenAnnotation/*codeOffset=226, codeLength=83*/ = dynamic Function();
/// Comment 2.
@Object()
typedef CommentAroundAnnotation/*codeOffset=326, codeLength=70*/ = dynamic Function();
''',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_method() async {
var library = await checkLibrary('''
class C {
void raw() {}
/// Comment 1.
/// Comment 2.
void hasDocComment() {}
@Object()
void hasAnnotation() {}
@Object()
/// Comment 1.
/// Comment 2.
void annotationThenComment() {}
/// Comment 1.
/// Comment 2.
@Object()
void commentThenAnnotation() {}
/// Comment 1.
@Object()
/// Comment 2.
void commentAroundAnnotation() {}
}
''');
checkElementText(
library,
r'''
class C/*codeOffset=0, codeLength=372*/ {
void raw/*codeOffset=12, codeLength=13*/() {}
/// Comment 1.
/// Comment 2.
void hasDocComment/*codeOffset=29, codeLength=57*/() {}
@Object()
void hasAnnotation/*codeOffset=90, codeLength=35*/() {}
/// Comment 1.
/// Comment 2.
@Object()
void annotationThenComment/*codeOffset=129, codeLength=77*/() {}
/// Comment 1.
/// Comment 2.
@Object()
void commentThenAnnotation/*codeOffset=210, codeLength=77*/() {}
/// Comment 2.
@Object()
void commentAroundAnnotation/*codeOffset=308, codeLength=62*/() {}
}
''',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_parameter() async {
var library = await checkLibrary('''
main({int a = 1, int b, int c = 2}) {}
''');
checkElementText(
library,
'dynamic main/*codeOffset=0, codeLength=38*/('
'{int a/*codeOffset=6, codeLength=9*/: 1}, '
'{int b/*codeOffset=17, codeLength=5*/}, '
'{int c/*codeOffset=24, codeLength=9*/: 2}) {}\n',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_parameter_annotations() async {
var library = await checkLibrary('''
main(@Object() int a, int b, @Object() int c) {}
''');
checkElementText(
library,
'dynamic main/*codeOffset=0, codeLength=48*/('
'@Object() int a/*codeOffset=5, codeLength=15*/, '
'int b/*codeOffset=22, codeLength=5*/, '
'@Object() int c/*codeOffset=29, codeLength=15*/) {}\n',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_topLevelVariable() async {
var library = await checkLibrary('''
int withInit = 1 + 2 * 3;
int withoutInit;
int multiWithInit = 2, multiWithoutInit, multiWithInit2 = 3;
''');
checkElementText(
library,
r'''
int withInit/*codeOffset=0, codeLength=24*/;
int withoutInit/*codeOffset=27, codeLength=15*/;
int multiWithInit/*codeOffset=45, codeLength=21*/;
int multiWithoutInit/*codeOffset=68, codeLength=16*/;
int multiWithInit2/*codeOffset=86, codeLength=18*/;
''',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_topLevelVariable_annotations() async {
var library = await checkLibrary('''
/// Comment 1.
/// Comment 2.
int hasDocComment, hasDocComment2;
@Object()
int hasAnnotation, hasAnnotation2;
@Object()
/// Comment 1.
/// Comment 2.
int annotationThenComment, annotationThenComment2;
/// Comment 1.
/// Comment 2.
@Object()
int commentThenAnnotation, commentThenAnnotation2;
/// Comment 1.
@Object()
/// Comment 2.
int commentAroundAnnotation, commentAroundAnnotation2;
''');
checkElementText(
library,
r'''
/// Comment 1.
/// Comment 2.
int hasDocComment/*codeOffset=0, codeLength=47*/;
/// Comment 1.
/// Comment 2.
int hasDocComment2/*codeOffset=49, codeLength=14*/;
@Object()
int hasAnnotation/*codeOffset=66, codeLength=27*/;
@Object()
int hasAnnotation2/*codeOffset=95, codeLength=14*/;
/// Comment 1.
/// Comment 2.
@Object()
int annotationThenComment/*codeOffset=112, codeLength=65*/;
/// Comment 1.
/// Comment 2.
@Object()
int annotationThenComment2/*codeOffset=179, codeLength=22*/;
/// Comment 1.
/// Comment 2.
@Object()
int commentThenAnnotation/*codeOffset=204, codeLength=65*/;
/// Comment 1.
/// Comment 2.
@Object()
int commentThenAnnotation2/*codeOffset=271, codeLength=22*/;
/// Comment 2.
@Object()
int commentAroundAnnotation/*codeOffset=311, codeLength=52*/;
/// Comment 2.
@Object()
int commentAroundAnnotation2/*codeOffset=365, codeLength=24*/;
''',
withCodeRanges: true,
withConstElements: false);
}
test_codeRange_type_parameter() async {
var library = await checkLibrary('''
class A<T> {}
void f<U extends num> {}
''');
checkElementText(
library,
r'''
class A/*codeOffset=0, codeLength=13*/<T/*codeOffset=8, codeLength=1*/> {
}
void f/*codeOffset=14, codeLength=24*/<U/*codeOffset=21, codeLength=13*/ extends num>() {}
''',
withCodeRanges: true,
withConstElements: false);
}
test_compilationUnit_nnbd_disabled_via_dart_directive() async {
featureSet = enableNnbd;
var library = await checkLibrary('''
// @dart=2.2
''');
expect(library.isNonNullableByDefault, isFalse);
}
test_compilationUnit_nnbd_disabled_via_feature_set() async {
featureSet = disableNnbd;
var library = await checkLibrary('');
expect(library.isNonNullableByDefault, isFalse);
}
test_compilationUnit_nnbd_enabled() async {
featureSet = enableNnbd;
var library = await checkLibrary('');
expect(library.isNonNullableByDefault, isTrue);
}
test_const_classField() async {
var library = await checkLibrary(r'''
class C {
static const int f1 = 1;
static const int f2 = C.f1, f3 = C.f2;
}
''');
checkElementText(library, r'''
class C {
static const int f1 = 1;
static const int f2 =
C/*location: test.dart;C*/.
f1/*location: test.dart;C;f1?*/;
static const int f3 =
C/*location: test.dart;C*/.
f2/*location: test.dart;C;f2?*/;
}
''');
}
test_const_constructor_inferred_args() async {
var library = await checkLibrary('''
class C<T> {
final T t;
const C(this.t);
const C.named(this.t);
}
const Object x = const C(0);
const Object y = const C.named(0);
''');
checkElementText(library, '''
class C<T> {
final T t;
const C(T this.t);
const C.named(T this.t);
}
const Object x = const
C/*location: test.dart;C*/(0);
const Object y = const
C/*location: test.dart;C*/.
named/*location: test.dart;C;named*/(0);
''');
TopLevelVariableElementImpl x =
library.definingCompilationUnit.topLevelVariables[0];
InstanceCreationExpression xExpr = x.constantInitializer;
var xType = xExpr.constructorName.staticElement.returnType;
expect(xType.toString(), 'C<int>');
TopLevelVariableElementImpl y =
library.definingCompilationUnit.topLevelVariables[0];
InstanceCreationExpression yExpr = y.constantInitializer;
var yType = yExpr.constructorName.staticElement.returnType;
expect(yType.toString(), 'C<int>');
}
test_const_finalField_hasConstConstructor() async {
var library = await checkLibrary(r'''
class C {
final int f = 42;
const C();
}
''');
checkElementText(library, r'''
class C {
final int f = 42;
const C();
}
''');
}
test_const_inference_downward_list() async {
var library = await checkLibrary('''
class P<T> {
const P();
}
class P1<T> extends P<T> {
const P1();
}
class P2<T> extends P<T> {
const P2();
}
const List<P> values = [
P1(),
P2<int>(),
];
''');
checkElementText(
library,
'''
class P<T> {
const P();
}
class P1<T> extends P<T> {
const P1();
}
class P2<T> extends P<T> {
const P2();
}
const List<P<dynamic>> values = /*typeArgs=P<dynamic>*/[/*typeArgs=dynamic*/
P1/*location: test.dart;P1*/(),
P2/*location: test.dart;P2*/<
int/*location: dart:core;int*/>()];
''',
withTypes: true);
}
test_const_invalid_field_const() async {
var library = await checkLibrary(r'''
class C {
static const f = 1 + foo();
}
int foo() => 42;
''', allowErrors: true);
checkElementText(library, r'''
class C {
static const int f = 1 +
foo/*location: test.dart;foo*/();
}
int foo() {}
''');
}
test_const_invalid_field_final() async {
var library = await checkLibrary(r'''
class C {
final f = 1 + foo();
}
int foo() => 42;
''', allowErrors: true);
checkElementText(library, r'''
class C {
final int f;
}
int foo() {}
''');
}
test_const_invalid_intLiteral() async {
var library = await checkLibrary(r'''
const int x = 0x;
''', allowErrors: true);
checkElementText(library, r'''
const int x = 0;
''');
}
test_const_invalid_topLevel() async {
var library = await checkLibrary(r'''
const v = 1 + foo();
int foo() => 42;
''', allowErrors: true);
checkElementText(library, r'''
const int v = 1 +
foo/*location: test.dart;foo*/();
int foo() {}
''');
}
test_const_invalid_typeMismatch() async {
var library = await checkLibrary(r'''
const int a = 0;
const bool b = a + 5;
''', allowErrors: true);
checkElementText(library, r'''
const int a = 0;
const bool b =
a/*location: test.dart;a?*/ + 5;
''');
}
test_const_invokeConstructor_generic_named() async {
var library = await checkLibrary(r'''
class C<K, V> {
const C.named(K k, V v);
}
const V = const C<int, String>.named(1, '222');
''');
checkElementText(library, r'''
class C<K, V> {
const C.named(K k, V v);
}
const C<int, String> V = const
C/*location: test.dart;C*/<
int/*location: dart:core;int*/,
String/*location: dart:core;String*/>.
named/*location: test.dart;C;named*/(1, '222');
''');
}
test_const_invokeConstructor_generic_named_imported() async {
addLibrarySource('/a.dart', r'''
class C<K, V> {
const C.named(K k, V v);
}
''');
var library = await checkLibrary(r'''
import 'a.dart';
const V = const C<int, String>.named(1, '222');
''');
checkElementText(library, r'''
import 'a.dart';
const C<int, String> V = const
C/*location: a.dart;C*/<
int/*location: dart:core;int*/,
String/*location: dart:core;String*/>.
named/*location: a.dart;C;named*/(1, '222');
''');
}
test_const_invokeConstructor_generic_named_imported_withPrefix() async {
addLibrarySource('/a.dart', r'''
class C<K, V> {
const C.named(K k, V v);
}
''');
var library = await checkLibrary(r'''
import 'a.dart' as p;
const V = const p.C<int, String>.named(1, '222');
''');
checkElementText(library, r'''
import 'a.dart' as p;
const C<int, String> V = const
p/*location: test.dart;p*/.
C/*location: a.dart;C*/<
int/*location: dart:core;int*/,
String/*location: dart:core;String*/>.
named/*location: a.dart;C;named*/(1, '222');
''');
}
test_const_invokeConstructor_generic_noTypeArguments() async {
var library = await checkLibrary(r'''
class C<K, V> {
const C();
}
const V = const C();
''');
checkElementText(library, r'''
class C<K, V> {
const C();
}
const C<dynamic, dynamic> V = const
C/*location: test.dart;C*/();
''');
}
test_const_invokeConstructor_generic_unnamed() async {
var library = await checkLibrary(r'''
class C<K, V> {
const C();
}
const V = const C<int, String>();
''');
checkElementText(library, r'''
class C<K, V> {
const C();
}
const C<int, String> V = const
C/*location: test.dart;C*/<
int/*location: dart:core;int*/,
String/*location: dart:core;String*/>();
''');
}
test_const_invokeConstructor_generic_unnamed_imported() async {
addLibrarySource('/a.dart', r'''
class C<K, V> {
const C();
}
''');
var library = await checkLibrary(r'''
import 'a.dart';
const V = const C<int, String>();
''');
checkElementText(library, r'''
import 'a.dart';
const C<int, String> V = const
C/*location: a.dart;C*/<
int/*location: dart:core;int*/,
String/*location: dart:core;String*/>();
''');
}
test_const_invokeConstructor_generic_unnamed_imported_withPrefix() async {
addLibrarySource('/a.dart', r'''
class C<K, V> {
const C();
}
''');
var library = await checkLibrary(r'''
import 'a.dart' as p;
const V = const p.C<int, String>();
''');
checkElementText(library, r'''
import 'a.dart' as p;
const C<int, String> V = const
p/*location: test.dart;p*/.
C/*location: a.dart;C*/<
int/*location: dart:core;int*/,
String/*location: dart:core;String*/>();
''');
}
test_const_invokeConstructor_named() async {
var library = await checkLibrary(r'''
class C {
const C.named(bool a, int b, int c, {String d, double e});
}
const V = const C.named(true, 1, 2, d: 'ccc', e: 3.4);
''');
checkElementText(library, r'''
class C {
const C.named(bool a, int b, int c, {String d}, {double e});
}
const C V = const
C/*location: test.dart;C*/.
named/*location: test.dart;C;named*/(true, 1, 2,
d/*location: test.dart;C;named;d*/: 'ccc',
e/*location: test.dart;C;named;e*/: 3.4);
''');
}
test_const_invokeConstructor_named_imported() async {
addLibrarySource('/a.dart', r'''
class C {
const C.named();
}
''');
var library = await checkLibrary(r'''
import 'a.dart';
const V = const C.named();
''');
checkElementText(library, r'''
import 'a.dart';
const C V = const
C/*location: a.dart;C*/.
named/*location: a.dart;C;named*/();
''');
}
test_const_invokeConstructor_named_imported_withPrefix() async {
addLibrarySource('/a.dart', r'''
class C {
const C.named();
}
''');
var library = await checkLibrary(r'''
import 'a.dart' as p;
const V = const p.C.named();
''');
checkElementText(library, r'''
import 'a.dart' as p;
const C V = const
p/*location: test.dart;p*/.
C/*location: a.dart;C*/.
named/*location: a.dart;C;named*/();
''');
}
test_const_invokeConstructor_named_unresolved() async {
var library = await checkLibrary(r'''
class C {}
const V = const C.named();
''', allowErrors: true);
checkElementText(library, r'''
class C {
}
const C V = const
C/*location: test.dart;C*/.
named/*location: null*/();
''');
}
test_const_invokeConstructor_named_unresolved2() async {
var library = await checkLibrary(r'''
const V = const C.named();
''', allowErrors: true);
checkElementText(library, r'''
const dynamic V = const
C/*location: null*/.
named/*location: null*/();
''');
}
test_const_invokeConstructor_named_unresolved3() async {
addLibrarySource('/a.dart', r'''
class C {
}
''');
var library = await checkLibrary(r'''
import 'a.dart' as p;
const V = const p.C.named();
''', allowErrors: true);
checkElementText(library, r'''
import 'a.dart' as p;
const C V = const
p/*location: test.dart;p*/.
C/*location: a.dart;C*/.
named/*location: null*/();
''');
}
test_const_invokeConstructor_named_unresolved4() async {
addLibrarySource('/a.dart', '');
var library = await checkLibrary(r'''
import 'a.dart' as p;
const V = const p.C.named();
''', allowErrors: true);
checkElementText(library, r'''
import 'a.dart' as p;
const dynamic V = const
p/*location: test.dart;p*/.
C/*location: null*/.
named/*location: null*/();
''');
}
test_const_invokeConstructor_named_unresolved5() async {
var library = await checkLibrary(r'''
const V = const p.C.named();
''', allowErrors: true);
checkElementText(library, r'''
const dynamic V = const
p/*location: null*/.
C/*location: null*/.
named/*location: null*/();
''');
}
test_const_invokeConstructor_named_unresolved6() async {
var library = await checkLibrary(r'''
class C<T> {}
const V = const C.named();
''', allowErrors: true);
checkElementText(library, r'''
class C<T> {
}
const C<dynamic> V = const
C/*location: test.dart;C*/.
named/*location: null*/();
''');
}
test_const_invokeConstructor_unnamed() async {
var library = await checkLibrary(r'''
class C {
const C();
}
const V = const C();
''');
checkElementText(library, r'''
class C {
const C();
}
const C V = const
C/*location: test.dart;C*/();
''');
}
test_const_invokeConstructor_unnamed_imported() async {
addLibrarySource('/a.dart', r'''
class C {
const C();
}
''');
var library = await checkLibrary(r'''
import 'a.dart';
const V = const C();
''');
checkElementText(library, r'''
import 'a.dart';
const C V = const
C/*location: a.dart;C*/();
''');
}
test_const_invokeConstructor_unnamed_imported_withPrefix() async {
addLibrarySource('/a.dart', r'''
class C {
const C();
}
''');
var library = await checkLibrary(r'''
import 'a.dart' as p;
const V = const p.C();
''');
checkElementText(library, r'''
import 'a.dart' as p;
const C V = const
p/*location: test.dart;p*/.
C/*location: a.dart;C*/();
''');
}
test_const_invokeConstructor_unnamed_unresolved() async {
var library = await checkLibrary(r'''
const V = const C();
''', allowErrors: true);
checkElementText(library, r'''
const dynamic V = const
C/*location: null*/();
''');
}
test_const_invokeConstructor_unnamed_unresolved2() async {
addLibrarySource('/a.dart', '');
var library = await checkLibrary(r'''
import 'a.dart' as p;
const V = const p.C();
''', allowErrors: true);
checkElementText(library, r'''
import 'a.dart' as p;
const dynamic V = const
p/*location: test.dart;p*/.
C/*location: null*/();
''');
}
test_const_invokeConstructor_unnamed_unresolved3() async {
var library = await checkLibrary(r'''
const V = const p.C();
''', allowErrors: true);
checkElementText(library, r'''
const dynamic V = const
p/*location: null*/.
C/*location: null*/();
''');
}
test_const_length_ofClassConstField() async {
var library = await checkLibrary(r'''
class C {
static const String F = '';
}
const int v = C.F.length;
''');
checkElementText(library, r'''
class C {
static const String F = '';
}
const int v =
C/*location: test.dart;C*/.
F/*location: test.dart;C;F?*/.
length/*location: dart:core;String;length?*/;
''');
}
test_const_length_ofClassConstField_imported() async {
addLibrarySource('/a.dart', r'''
class C {
static const String F = '';
}
''');
var library = await checkLibrary(r'''
import 'a.dart';
const int v = C.F.length;
''');
checkElementText(library, r'''
import 'a.dart';
const int v =
C/*location: a.dart;C*/.
F/*location: a.dart;C;F?*/.
length/*location: dart:core;String;length?*/;
''');
}
test_const_length_ofClassConstField_imported_withPrefix() async {
addLibrarySource('/a.dart', r'''
class C {
static const String F = '';
}
''');
var library = await checkLibrary(r'''
import 'a.dart' as p;
const int v = p.C.F.length;
''');
checkElementText(library, r'''
import 'a.dart' as p;
const int v =
p/*location: test.dart;p*/.
C/*location: a.dart;C*/.
F/*location: a.dart;C;F?*/.
length/*location: dart:core;String;length?*/;
''');
}
test_const_length_ofStringLiteral() async {
var library = await checkLibrary(r'''
const v = 'abc'.length;
''');
checkElementText(library, r'''
const int v = 'abc'.
length/*location: dart:core;String;length?*/;
''');
}
test_const_length_ofTopLevelVariable() async {
var library = await checkLibrary(r'''
const String S = 'abc';
const v = S.length;
''');
checkElementText(library, r'''
const String S = 'abc';
const int v =
S/*location: test.dart;S?*/.
length/*location: dart:core;String;length?*/;
''');
}
test_const_length_ofTopLevelVariable_imported() async {
addLibrarySource('/a.dart', r'''
const String S = 'abc';
''');
var library = await checkLibrary(r'''
import 'a.dart';
const v = S.length;
''');
checkElementText(library, r'''
import 'a.dart';
const int v =
S/*location: a.dart;S?*/.
length/*location: dart:core;String;length?*/;
''');
}
test_const_length_ofTopLevelVariable_imported_withPrefix() async {
addLibrarySource('/a.dart', r'''
const String S = 'abc';
''');
var library = await checkLibrary(r'''
import 'a.dart' as p;
const v = p.S.length;
''');
checkElementText(library, r'''
import 'a.dart' as p;
const int v =
p/*location: test.dart;p*/.
S/*location: a.dart;S?*/.
length/*location: dart:core;String;length?*/;
''');
}
test_const_length_staticMethod() async {
var library = await checkLibrary(r'''
class C {
static int length() => 42;
}
const v = C.length;
''');
checkElementText(library, r'''
class C {
static int length() {}
}
const int Function() v =
C/*location: test.dart;C*/.
length/*location: test.dart;C;length*/;
''');
}
test_const_list_if() async {
var library = await checkLibrary('''
const Object x = const <int>[if (true) 1];
''');
checkElementText(
library,
'''
const Object x = const <
int/*location: dart:core;int*/>[if (true) 1];
''',
withTypes: true);
}
test_const_list_if_else() async {
var library = await checkLibrary('''
const Object x = const <int>[if (true) 1 else 2];
''');
checkElementText(
library,
'''
const Object x = const <
int/*location: dart:core;int*/>[if (true) 1 else 2];
''',
withTypes: true);
}
test_const_list_inferredType() async {
// The summary needs to contain enough information so that when the constant
// is resynthesized, the constant value can get the type that was computed
// by type inference.
var library = await checkLibrary('''
const Object x = const [1];
''');
checkElementText(
library,
'''
const Object x = const /*typeArgs=int*/[1];
''',
withTypes: true);
}
test_const_list_spread() async {
var library = await checkLibrary('''
const Object x = const <int>[...<int>[1]];
''');
checkElementText(
library,
'''
const Object x = const <
int/*location: dart:core;int*/>[...<
int/*location: dart:core;int*/>[1]];
''',
withTypes: true);
}
test_const_list_spread_null_aware() async {
var library = await checkLibrary('''
const Object x = const <int>[...?<int>[1]];
''');
checkElementText(
library,
'''
const Object x = const <
int/*location: dart:core;int*/>[...?<
int/*location: dart:core;int*/>[1]];
''',
withTypes: true);
}
test_const_map_if() async {
var library = await checkLibrary('''
const Object x = const <int, int>{if (true) 1: 2};
''');
checkElementText(
library,
'''
const Object x = const <
int/*location: dart:core;int*/,
int/*location: dart:core;int*/>{if (true) 1: 2}/*isMap*/;
''',
withTypes: true);
}
test_const_map_if_else() async {
var library = await checkLibrary('''
const Object x = const <int, int>{if (true) 1: 2 else 3: 4];
''');
checkElementText(
library,
'''
const Object x = const <
int/*location: dart:core;int*/,
int/*location: dart:core;int*/>{if (true) 1: 2 else 3: 4}/*isMap*/;
''',
withTypes: true);
}
test_const_map_inferredType() async {
// The summary needs to contain enough information so that when the constant
// is resynthesized, the constant value can get the type that was computed
// by type inference.
var library = await checkLibrary('''
const Object x = const {1: 1.0};
''');
checkElementText(
library,
'''
const Object x = const /*typeArgs=int,double*/{1: 1.0}/*isMap*/;
''',
withTypes: true);
}
test_const_map_spread() async {
var library = await checkLibrary('''
const Object x = const <int, int>{...<int, int>{1: 2}};
''');
checkElementText(
library,
'''
const Object x = const <
int/*location: dart:core;int*/,
int/*location: dart:core;int*/>{...<
int/*location: dart:core;int*/,
int/*location: dart:core;int*/>{1: 2}/*isMap*/}/*isMap*/;
''',
withTypes: true);
}
test_const_map_spread_null_aware() async {
var library = await checkLibrary('''
const Object x = const <int, int>{...?<int, int>{1: 2}};
''');
checkElementText(
library,
'''
const Object x = const <
int/*location: dart:core;int*/,
int/*location: dart:core;int*/>{...?<
int/*location: dart:core;int*/,
int/*location: dart:core;int*/>{1: 2}/*isMap*/}/*isMap*/;
''',
withTypes: true);
}
test_const_parameterDefaultValue_initializingFormal_functionTyped() async {
var library = await checkLibrary(r'''
class C {
final x;
const C({this.x: foo});
}
int foo() => 42;
''');
checkElementText(library, r'''
class C {
final dynamic x;
const C({dynamic this.x:
foo/*location: test.dart;foo*/});
}
int foo() {}
''');
}
test_const_parameterDefaultValue_initializingFormal_named() async {
var library = await checkLibrary(r'''
class C {
final x;
const C({this.x: 1 + 2});
}
''');
checkElementText(library, r'''
class C {
final dynamic x;
const C({dynamic this.x: 1 + 2});
}
''');
}
test_const_parameterDefaultValue_initializingFormal_positional() async {
var library = await checkLibrary(r'''
class C {
final x;
const C([this.x = 1 + 2]);
}
''');
checkElementText(library, r'''
class C {
final dynamic x;
const C([dynamic this.x = 1 + 2]);
}
''');
}
test_const_parameterDefaultValue_normal() async {
var library = await checkLibrary(r'''
class C {
const C.positional([p = 1 + 2]);
const C.named({p: 1 + 2});
void methodPositional([p = 1 + 2]) {}
void methodPositionalWithoutDefault([p]) {}
void methodNamed({p: 1 + 2}) {}
void methodNamedWithoutDefault({p}) {}
}
''');
checkElementText(library, r'''
class C {
const C.positional([dynamic p = 1 + 2]);
const C.named({dynamic p: 1 + 2});
void methodPositional([dynamic p = 1 + 2]) {}
void methodPositionalWithoutDefault([dynamic p]) {}
void methodNamed({dynamic p: 1 + 2}) {}
void methodNamedWithoutDefault({dynamic p}) {}
}
''');
}
test_const_reference_staticField() async {
var library = await checkLibrary(r'''
class C {
static const int F = 42;
}
const V = C.F;
''');
checkElementText(library, r'''
class C {
static const int F = 42;
}
const int V =
C/*location: test.dart;C*/.
F/*location: test.dart;C;F?*/;
''');
}
test_const_reference_staticField_imported() async {
addLibrarySource('/a.dart', r'''
class C {
static const int F = 42;
}
''');
var library = await checkLibrary(r'''
import 'a.dart';
const V = C.F;
''');
checkElementText(library, r'''
import 'a.dart';
const int V =
C/*location: a.dart;C*/.
F/*location: a.dart;C;F?*/;
''');
}
test_const_reference_staticField_imported_withPrefix() async {
addLibrarySource('/a.dart', r'''
class C {
static const int F = 42;
}
''');
var library = await checkLibrary(r'''
import 'a.dart' as p;
const V = p.C.F;
''');
checkElementText(library, r'''
import 'a.dart' as p;
const int V =
p/*location: test.dart;p*/.
C/*location: a.dart;C*/.
F/*location: a.dart;C;F?*/;
''');
}
test_const_reference_staticMethod() async {
var library = await checkLibrary(r'''
class C {
static int m(int a, String b) => 42;
}
const V = C.m;
''');
checkElementText(library, r'''
class C {
static int m(int a, String b) {}
}
const int Function(int, String) V =
C/*location: test.dart;C*/.
m/*location: test.dart;C;m*/;
''');
}
test_const_reference_staticMethod_imported() async {
addLibrarySource('/a.dart', r'''
class C {
static int m(int a, String b) => 42;
}
''');
var library = await checkLibrary(r'''
import 'a.dart';
const V = C.m;
''');
checkElementText(library, r'''
import 'a.dart';
const int Function(int, String) V =
C/*location: a.dart;C*/.
m/*location: a.dart;C;m*/;
''');
}
test_const_reference_staticMethod_imported_withPrefix() async {
addLibrarySource('/a.dart', r'''
class C {
static int m(int a, String b) => 42;
}
''');
var library = await checkLibrary(r'''
import 'a.dart' as p;
const V = p.C.m;
''');
checkElementText(library, r'''
import 'a.dart' as p;
const int Function(int, String) V =
p/*location: test.dart;p*/.
C/*location: a.dart;C*/.
m/*location: a.dart;C;m*/;
''');
}
test_const_reference_staticMethod_ofExtension() async {
featureSet = enableExtensionMethods;
var library = await checkLibrary('''
class A {}
extension E on A {
static void f() {}
}
const x = E.f;
''');
checkElementText(library, r'''
class A {
}
extension E on A {
static void f() {}
}
const void Function() x =
E/*location: test.dart;E*/.
f/*location: test.dart;E;f*/;
''');
}
test_const_reference_topLevelFunction() async {
var library = await checkLibrary(r'''
foo() {}
const V = foo;
''');
checkElementText(library, r'''
const dynamic Function() V =
foo/*location: test.dart;foo*/;
dynamic foo() {}
''');
}
test_const_reference_topLevelFunction_generic() async {
var library = await checkLibrary(r'''
R foo<P, R>(P p) {}
const V = foo;
''');
checkElementText(library, r'''
const R Function<P, R>(P) V =
foo/*location: test.dart;foo*/;
R foo<P, R>(P p) {}
''');
}
test_const_reference_topLevelFunction_imported() async {
addLibrarySource('/a.dart', r'''
foo() {}
''');
var library = await checkLibrary(r'''
import 'a.dart';
const V = foo;
''');
checkElementText(library, r'''
import 'a.dart';
const dynamic Function() V =
foo/*location: a.dart;foo*/;
''');
}
test_const_reference_topLevelFunction_imported_withPrefix() async {
addLibrarySource('/a.dart', r'''
foo() {}
''');
var library = await checkLibrary(r'''
import 'a.dart' as p;
const V = p.foo;
''');
checkElementText(library, r'''
import 'a.dart' as p;
const dynamic Function() V =
p/*location: test.dart;p*/.
foo/*location: a.dart;foo*/;
''');
}
test_const_reference_topLevelVariable() async {
var library = await checkLibrary(r'''
const A = 1;
const B = A + 2;
''');
checkElementText(library, r'''
const int A = 1;
const int B =
A/*location: test.dart;A?*/ + 2;
''');
}
test_const_reference_topLevelVariable_imported() async {
addLibrarySource('/a.dart', r'''
const A = 1;
''');
var library = await checkLibrary(r'''
import 'a.dart';
const B = A + 2;
''');
checkElementText(library, r'''
import 'a.dart';
const int B =
A/*location: a.dart;A?*/ + 2;
''');
}
test_const_reference_topLevelVariable_imported_withPrefix() async {
addLibrarySource('/a.dart', r'''
const A = 1;
''');
var library = await checkLibrary(r'''
import 'a.dart' as p;
const B = p.A + 2;
''');
checkElementText(library, r'''
import 'a.dart' as p;
const int B =
p/*location: test.dart;p*/.
A/*location: a.dart;A?*/ + 2;
''');
}
test_const_reference_type() async {
var library = await checkLibrary(r'''
class C {}
class D<T> {}
enum E {a, b, c}
typedef F(int a, String b);
const vDynamic = dynamic;
const vNull = Null;
const vObject = Object;
const vClass = C;
const vGenericClass = D;
const vEnum = E;
const vFunctionTypeAlias = F;
''');
checkElementText(library, r'''
typedef F = dynamic Function(int a, String b);
enum E {
synthetic final int index;
synthetic static const List<E> values;
static const E a;
static const E b;
static const E c;
String toString() {}
}
class C {
}
class D<T> {
}
const Type vDynamic =
dynamic/*location: dynamic*/;
const Type vNull =
Null/*location: dart:core;Null*/;
const Type vObject =
Object/*location: dart:core;Object*/;
const Type vClass =
C/*location: test.dart;C*/;
const Type vGenericClass =
D/*location: test.dart;D*/;
const Type vEnum =
E/*location: test.dart;E*/;
const Type vFunctionTypeAlias =
F/*location: test.dart;F*/;
''');
}
test_const_reference_type_functionType() async {
var library = await checkLibrary(r'''
typedef F();
class C {
final f = <F>[];
}
''');
checkElementText(library, r'''
typedef F = dynamic Function();
class C {
final List<dynamic Function()> f;
}
''');
}
test_const_reference_type_imported() async {
addLibrarySource('/a.dart', r'''
class C {}
enum E {a, b, c}
typedef F(int a, String b);
''');
var library = await checkLibrary(r'''
import 'a.dart';
const vClass = C;
const vEnum = E;
const vFunctionTypeAlias = F;
''');
checkElementText(library, r'''
import 'a.dart';
const Type vClass =
C/*location: a.dart;C*/;
const Type vEnum =
E/*location: a.dart;E*/;
const Type vFunctionTypeAlias =
F/*location: a.dart;F*/;
''');
}
test_const_reference_type_imported_withPrefix() async {
addLibrarySource('/a.dart', r'''
class C {}
enum E {a, b, c}
typedef F(int a, String b);
''');
var library = await checkLibrary(r'''
import 'a.dart' as p;
const vClass = p.C;
const vEnum = p.E;
const vFunctionTypeAlias = p.F;
''');
checkElementText(library, r'''
import 'a.dart' as p;
const Type vClass =
p/*location: test.dart;p*/.
C/*location: a.dart;C*/;
const Type vEnum =
p/*location: test.dart;p*/.
E/*location: a.dart;E*/;
const Type vFunctionTypeAlias =
p/*location: test.dart;p*/.
F/*location: a.dart;F*/;
''');
}
test_const_reference_type_typeParameter() async {
var library = await checkLibrary(r'''
class C<T> {
final f = <T>[];
}
''');
checkElementText(library, r'''
class C<T> {
final List<T> f;
}
''');
}
test_const_reference_unresolved_prefix0() async {
var library = await checkLibrary(r'''
const V = foo;
''', allowErrors: true);
checkElementText(library, r'''
const dynamic V =
foo/*location: null*/;
''');
}
test_const_reference_unresolved_prefix1() async {
var library = await checkLibrary(r'''
class C {}
const V = C.foo;
''', allowErrors: true);
checkElementText(library, r'''
class C {
}
const dynamic V =
C/*location: test.dart;C*/.
foo/*location: null*/;
''');
}
test_const_reference_unresolved_prefix2() async {
addLibrarySource('/foo.dart', '''
class C {}
''');
var library = await checkLibrary(r'''
import 'foo.dart' as p;
const V = p.C.foo;
''', allowErrors: true);
checkElementText(library, r'''
import 'foo.dart' as p;
const dynamic V =
p/*location: test.dart;p*/.
C/*location: foo.dart;C*/.
foo/*location: null*/;
''');
}
test_const_set_if() async {
var library = await checkLibrary('''
const Object x = const <int>{if (true) 1};
''');
checkElementText(
library,
'''
const Object x = const <
int/*location: dart:core;int*/>{if (true) 1}/*isSet*/;
''',
withTypes: true);
}
test_const_set_if_else() async {
var library = await checkLibrary('''
const Object x = const <int>{if (true) 1 else 2];
''');
checkElementText(
library,
'''
const Object x = const <
int/*location: dart:core;int*/>{if (true) 1 else 2}/*isSet*/;
''',
withTypes: true);
}
test_const_set_inferredType() async {
// The summary needs to contain enough information so that when the constant
// is resynthesized, the constant value can get the type that was computed
// by type inference.
var library = await checkLibrary('''
const Object x = const {1};
''');
checkElementText(
library,
'''
const Object x = const /*typeArgs=int*/{1}/*isSet*/;
''',
withTypes: true);
}
test_const_set_spread() async {
var library = await checkLibrary('''
const Object x = const <int>{...<int>{1}};
''');
checkElementText(
library,
'''
const Object x = const <
int/*location: dart:core;int*/>{...<
int/*location: dart:core;int*/>{1}/*isSet*/}/*isSet*/;
''',
withTypes: true);
}
test_const_set_spread_null_aware() async {
var library = await checkLibrary('''
const Object x = const <int>{...?<int>{1}};
''');
checkElementText(
library,
'''
const Object x = const <
int/*location: dart:core;int*/>{...?<
int/*location: dart:core;int*/>{1}/*isSet*/}/*isSet*/;
''',
withTypes: true);
}
test_const_topLevel_binary() async {
var library = await checkLibrary(r'''
const vEqual = 1 == 2;
const vAnd = true && false;
const vOr = false || true;
const vBitXor = 1 ^ 2;
const vBitAnd = 1 & 2;
const vBitOr = 1 | 2;
const vBitShiftLeft = 1 << 2;
const vBitShiftRight = 1 >> 2;
const vAdd = 1 + 2;
const vSubtract = 1 - 2;
const vMiltiply = 1 * 2;
const vDivide = 1 / 2;
const vFloorDivide = 1 ~/ 2;
const vModulo = 1 % 2;
const vGreater = 1 > 2;
const vGreaterEqual = 1 >= 2;
const vLess = 1 < 2;
const vLessEqual = 1 <= 2;
''');
checkElementText(library, r'''
const bool vEqual = 1 == 2;
const bool vAnd = true && false;
const bool vOr = false || true;
const int vBitXor = 1 ^ 2;
const int vBitAnd = 1 & 2;
const int vBitOr = 1 | 2;
const int vBitShiftLeft = 1 << 2;
const int vBitShiftRight = 1 >> 2;
const int vAdd = 1 + 2;
const int vSubtract = 1 - 2;
const int vMiltiply = 1 * 2;
const double vDivide = 1 / 2;
const int vFloorDivide = 1 ~/ 2;
const int vModulo = 1 % 2;
const bool vGreater = 1 > 2;
const bool vGreaterEqual = 1 >= 2;
const bool vLess = 1 < 2;
const bool vLessEqual = 1 <= 2;
''');
}
test_const_topLevel_conditional() async {
var library = await checkLibrary(r'''
const vConditional = (1 == 2) ? 11 : 22;
''');
checkElementText(library, r'''
const int vConditional = (1 == 2) ? 11 : 22;
''');
}
test_const_topLevel_identical() async {
var library = await checkLibrary(r'''
const vIdentical = (1 == 2) ? 11 : 22;
''');
checkElementText(library, r'''
const int vIdentical = (1 == 2) ? 11 : 22;
''');
}
test_const_topLevel_ifNull() async {
var library = await checkLibrary(r'''
const vIfNull = 1 ?? 2.0;
''');
checkElementText(library, r'''
const num vIfNull = 1 ?? 2.0;
''');
}
test_const_topLevel_literal() async {
var library = await checkLibrary(r'''
const vNull = null;
const vBoolFalse = false;
const vBoolTrue = true;
const vInt = 1;
const vIntLong1 = 0x7FFFFFFFFFFFFFFF;
const vIntLong2 = 0xFFFFFFFFFFFFFFFF;
const vDouble = 2.3;
const vString = 'abc';
const vStringConcat = 'aaa' 'bbb';
const vStringInterpolation = 'aaa ${true} ${42} bbb';
const vSymbol = #aaa.bbb.ccc;
''');
checkElementText(library, r'''
const dynamic vNull = null;
const bool vBoolFalse = false;
const bool vBoolTrue = true;
const int vInt = 1;
const int vIntLong1 = 9223372036854775807;
const int vIntLong2 = -1;
const double vDouble = 2.3;
const String vString = 'abc';
const String vStringConcat = 'aaabbb';