| // 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 '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/type.dart'; |
| import 'package:analyzer/file_system/file_system.dart'; |
| import 'package:analyzer/src/dart/element/element.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:pub_semver/pub_semver.dart'; |
| import 'package:test/test.dart'; |
| import 'package:test_reflective_loader/test_reflective_loader.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 = DeclaredVariables(); |
| /*late final*/ SourceFactory sourceFactory; |
| /*late final*/ MockSdk sdk; |
| |
| /*late final*/ String testFile; |
| Source testSource; |
| Set<Source> otherLibrarySources = <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 = MockSdk(resourceProvider: resourceProvider); |
| |
| sourceFactory = SourceFactory( |
| [ |
| DartUriResolver(sdk), |
| ResourceUriResolver(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 { |
| static final FeatureSet featureSetLegacy = FeatureSet.fromEnableFlags2( |
| sdkLanguageVersion: Version.parse('2.9.0'), |
| flags: [], |
| ); |
| |
| static final FeatureSet featureSetNullSafe = FeatureSet.fromEnableFlags2( |
| sdkLanguageVersion: Version.parse('2.12.0'), |
| flags: [], |
| ); |
| |
| 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_const_constructors() async { |
| addLibrarySource('/a.dart', ''' |
| class Base { |
| const Base._priv(); |
| const Base(); |
| const Base.named(); |
| } |
| '''); |
| 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 const MixinApp() = Base; |
| synthetic const MixinApp.named() = Base.named; |
| } |
| '''); |
| } |
| |
| 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() => Base(); |
| 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; |
| } |
| '''); |
| } |
| |
| 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() => throw 0; }'); |
| 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 = featureSetNullSafe; |
| 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 = featureSetNullSafe; |
| 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 = featureSetNullSafe; |
| 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 = featureSetNullSafe; |
| var library = await checkLibrary(''' |
| class C { |
| late int foo; |
| } |
| '''); |
| checkElementText( |
| library, |
| r''' |
| class C { |
| late int foo; |
| synthetic int get foo {} |
| synthetic void set foo(int _foo) {} |
| } |
| ''', |
| withSyntheticAccessors: true); |
| } |
| |
| test_class_fields_late_final() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(''' |
| class C { |
| late final int foo; |
| } |
| '''); |
| checkElementText( |
| library, |
| r''' |
| class C { |
| late final int foo; |
| synthetic int get foo {} |
| synthetic void set foo(int _foo) {} |
| } |
| ''', |
| withSyntheticAccessors: true); |
| } |
| |
| test_class_fields_late_final_initialized() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(''' |
| class C { |
| late final int foo = 0; |
| } |
| '''); |
| checkElementText( |
| library, |
| r''' |
| class C { |
| late final int foo; |
| synthetic int get foo {} |
| } |
| ''', |
| withSyntheticAccessors: true); |
| } |
| |
| 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>) = 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> = 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> = 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> = D<dynamic>> { |
| } |
| 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> = D<dynamic>> { |
| } |
| notSimplyBounded class D<T extends D<T> = D<dynamic>> { |
| } |
| '''); |
| } |
| |
| 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) = void Function(Null)> { |
| } |
| '''); |
| } |
| |
| 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() = dynamic 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() = 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) value); |
| notSimplyBounded typedef G = dynamic Function(dynamic value); |
| notSimplyBounded class C<T extends dynamic Function(dynamic Function(dynamic)) = 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> = 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 = featureSetNullSafe; |
| var library = await checkLibrary(''' |
| class C {} |
| C c; |
| '''); |
| checkElementText( |
| library, |
| ''' |
| class C { |
| } |
| C c; |
| ''', |
| annotateNullability: true); |
| } |
| |
| test_class_ref_nullability_question() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(''' |
| class C {} |
| C? c; |
| '''); |
| checkElementText( |
| library, |
| ''' |
| class C { |
| } |
| C? c; |
| ''', |
| annotateNullability: true); |
| } |
| |
| test_class_ref_nullability_star() async { |
| featureSet = featureSetLegacy; |
| 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 = Object, U extends D = D> { |
| } |
| class D { |
| } |
| '''); |
| } |
| |
| test_class_type_parameters_cycle_1of1() async { |
| var library = await checkLibrary('class C<T extends T> {}'); |
| checkElementText( |
| library, |
| r''' |
| notSimplyBounded class C<T extends dynamic> { |
| } |
| ''', |
| withTypes: true); |
| } |
| |
| test_class_type_parameters_cycle_2of3() async { |
| var library = await checkLibrary(r''' |
| class C<T extends V, U, V extends T> {} |
| '''); |
| checkElementText( |
| library, |
| r''' |
| notSimplyBounded class C<T extends dynamic, U, V extends dynamic> { |
| } |
| ''', |
| withTypes: true); |
| } |
| |
| 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> = List<dynamic>, 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_class_type_parameters_variance_contravariant() async { |
| var library = await checkLibrary('class C<in T> {}'); |
| checkElementText( |
| library, |
| r''' |
| class C<contravariant T> { |
| } |
| ''', |
| withTypeParameterVariance: true); |
| } |
| |
| test_class_type_parameters_variance_covariant() async { |
| var library = await checkLibrary('class C<out T> {}'); |
| checkElementText( |
| library, |
| r''' |
| class C<covariant T> { |
| } |
| ''', |
| withTypeParameterVariance: true); |
| } |
| |
| test_class_type_parameters_variance_invariant() async { |
| var library = await checkLibrary('class C<inout T> {}'); |
| checkElementText( |
| library, |
| r''' |
| class C<invariant T> { |
| } |
| ''', |
| withTypeParameterVariance: true); |
| } |
| |
| test_class_type_parameters_variance_multiple() async { |
| var library = await checkLibrary('class C<inout T, in U, out V> {}'); |
| checkElementText( |
| library, |
| r''' |
| class C<invariant T, contravariant U, covariant V> { |
| } |
| ''', |
| withTypeParameterVariance: true); |
| } |
| |
| test_class_typeParameters_defaultType_functionTypeAlias_contravariant_legacy() async { |
| var library = await checkLibrary(r''' |
| typedef F<X> = void Function(X); |
| |
| class A<X extends F<X>> {} |
| '''); |
| checkElementText( |
| library, |
| r''' |
| typedef F<contravariant X> = void Function(X ); |
| notSimplyBounded class A<covariant X extends void Function(X) = void Function(Null)> { |
| } |
| ''', |
| withTypeParameterVariance: true); |
| } |
| |
| test_class_typeParameters_defaultType_functionTypeAlias_contravariant_nullSafe() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(r''' |
| typedef F<X> = void Function(X); |
| |
| class A<X extends F<X>> {} |
| '''); |
| checkElementText( |
| library, |
| r''' |
| typedef F<contravariant X> = void Function(X ); |
| notSimplyBounded class A<covariant X extends void Function(X) = void Function(Never)> { |
| } |
| ''', |
| withTypeParameterVariance: true); |
| } |
| |
| test_class_typeParameters_defaultType_functionTypeAlias_invariant_legacy() async { |
| var library = await checkLibrary(r''' |
| typedef F<X> = X Function(X); |
| |
| class A<X extends F<X>> {} |
| '''); |
| checkElementText( |
| library, |
| r''' |
| typedef F<invariant X> = X Function(X ); |
| notSimplyBounded class A<covariant X extends X Function(X) = dynamic Function(dynamic)> { |
| } |
| ''', |
| withTypeParameterVariance: true); |
| } |
| |
| test_class_typeParameters_defaultType_functionTypeAlias_invariant_nullSafe() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(r''' |
| typedef F<X> = X Function(X); |
| |
| class A<X extends F<X>> {} |
| '''); |
| checkElementText( |
| library, |
| r''' |
| typedef F<invariant X> = X Function(X ); |
| notSimplyBounded class A<covariant X extends X Function(X) = dynamic Function(dynamic)> { |
| } |
| ''', |
| withTypeParameterVariance: true); |
| } |
| |
| test_class_typeParameters_defaultType_genericFunctionType_both_legacy() async { |
| var library = await checkLibrary(r''' |
| class A<X extends X Function(X)> {} |
| '''); |
| checkElementText(library, r''' |
| notSimplyBounded class A<X extends X Function(X) = dynamic Function(Null)> { |
| } |
| '''); |
| } |
| |
| test_class_typeParameters_defaultType_genericFunctionType_both_nullSafe() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(r''' |
| class A<X extends X Function(X)> {} |
| '''); |
| checkElementText(library, r''' |
| notSimplyBounded class A<X extends X Function(X) = dynamic Function(Never)> { |
| } |
| '''); |
| } |
| |
| test_class_typeParameters_defaultType_genericFunctionType_contravariant_legacy() async { |
| var library = await checkLibrary(r''' |
| class A<X extends void Function(X)> {} |
| '''); |
| checkElementText(library, r''' |
| notSimplyBounded class A<X extends void Function(X) = void Function(Null)> { |
| } |
| '''); |
| } |
| |
| test_class_typeParameters_defaultType_genericFunctionType_contravariant_nullSafe() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(r''' |
| class A<X extends void Function(X)> {} |
| '''); |
| checkElementText(library, r''' |
| notSimplyBounded class A<X extends void Function(X) = void Function(Never)> { |
| } |
| '''); |
| } |
| |
| test_class_typeParameters_defaultType_genericFunctionType_covariant_legacy() async { |
| var library = await checkLibrary(r''' |
| class A<X extends X Function()> {} |
| '''); |
| checkElementText(library, r''' |
| notSimplyBounded class A<X extends X Function() = dynamic Function()> { |
| } |
| '''); |
| } |
| |
| test_class_typeParameters_defaultType_genericFunctionType_covariant_nullSafe() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(r''' |
| class A<X extends X Function()> {} |
| '''); |
| checkElementText(library, r''' |
| notSimplyBounded class A<X extends X Function() = dynamic Function()> { |
| } |
| '''); |
| } |
| |
| 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 const Raw() = Object; |
| } |
| /// Comment 1. |
| /// Comment 2. |
| class alias HasDocComment/*codeOffset=59, codeLength=69*/ extends Object with A, B { |
| synthetic const HasDocComment() = Object; |
| } |
| @Object() |
| class alias HasAnnotation/*codeOffset=130, codeLength=49*/ extends Object with A, B { |
| synthetic const HasAnnotation() = Object; |
| } |
| /// Comment 1. |
| /// Comment 2. |
| @Object() |
| class alias AnnotationThenComment/*codeOffset=181, codeLength=87*/ extends Object with A, B { |
| synthetic const AnnotationThenComment() = Object; |
| } |
| /// Comment 1. |
| /// Comment 2. |
| @Object() |
| class alias CommentThenAnnotation/*codeOffset=270, codeLength=87*/ extends Object with A, B { |
| synthetic const CommentThenAnnotation() = Object; |
| } |
| /// Comment 2. |
| @Object() |
| class alias CommentAroundAnnotation/*codeOffset=374, codeLength=74*/ extends Object with A, B { |
| synthetic const 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() => throw 0; |
| |
| factory C.raw() => throw 0; |
| |
| /// Comment 1. |
| /// Comment 2. |
| factory C.hasDocComment() => throw 0; |
| |
| @Object() |
| factory C.hasAnnotation() => throw 0; |
| |
| @Object() |
| /// Comment 1. |
| /// Comment 2. |
| factory C.annotationThenComment() => throw 0; |
| |
| /// Comment 1. |
| /// Comment 2. |
| @Object() |
| factory C.commentThenAnnotation() => throw 0; |
| |
| /// Comment 1. |
| @Object() |
| /// Comment 2. |
| factory C.commentAroundAnnotation() => throw 0; |
| } |
| '''); |
| checkElementText( |
| library, |
| r''' |
| class C/*codeOffset=0, codeLength=483*/ { |
| factory C/*codeOffset=12, codeLength=23*/(); |
| factory C.raw/*codeOffset=39, codeLength=27*/(); |
| /// Comment 1. |
| /// Comment 2. |
| factory C.hasDocComment/*codeOffset=70, codeLength=71*/(); |
| @Object() |
| factory C.hasAnnotation/*codeOffset=145, codeLength=49*/(); |
| /// Comment 1. |
| /// Comment 2. |
| @Object() |
| factory C.annotationThenComment/*codeOffset=198, codeLength=91*/(); |
| /// Comment 1. |
| /// Comment 2. |
| @Object() |
| factory C.commentThenAnnotation/*codeOffset=293, codeLength=91*/(); |
| /// Comment 2. |
| @Object() |
| factory C.commentAroundAnnotation/*codeOffset=405, codeLength=76*/(); |
| } |
| ''', |
| 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 { |
| 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 = featureSetNullSafe; |
| var library = await checkLibrary(''' |
| // @dart=2.2 |
| '''); |
| expect(library.isNonNullableByDefault, isFalse); |
| } |
| |
| test_compilationUnit_nnbd_disabled_via_feature_set() async { |
| featureSet = featureSetLegacy; |
| var library = await checkLibrary(''); |
| expect(library.isNonNullableByDefault, isFalse); |
| } |
| |
| test_compilationUnit_nnbd_enabled() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(''); |
| expect(library.isNonNullableByDefault, isTrue); |
| } |
| |
| test_const_asExpression() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(''' |
| const num a = 0; |
| const b = a as int; |
| '''); |
| checkElementText(library, ''' |
| const num a = 0; |
| const int b = |
| a/*location: test.dart;a?*/ as |
| int/*location: dart:core;int*/; |
| '''); |
| } |
| |
| test_const_assignmentExpression() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(r''' |
| const a = 0; |
| const b = (a += 1); |
| '''); |
| checkElementText( |
| library, |
| r''' |
| const int a; |
| constantInitializer |
| IntegerLiteral |
| literal: 0 |
| staticType: int |
| const int b; |
| constantInitializer |
| ParenthesizedExpression |
| expression: AssignmentExpression |
| leftHandSide: SimpleIdentifier |
| staticElement: <null> |
| staticType: null |
| token: a |
| operator: += |
| readElement: self::@getter::a |
| readType: int |
| rightHandSide: IntegerLiteral |
| literal: 1 |
| staticType: int |
| staticElement: dart:core::@class::num::@method::+ |
| staticType: int |
| writeElement: self::@getter::a |
| writeType: dynamic |
| staticType: int |
| ''', |
| annotateNullability: true, |
| withFullyResolvedAst: true, |
| ); |
| } |
| |
| test_const_cascadeExpression() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(r''' |
| const a = 0..isEven..abs(); |
| '''); |
| checkElementText( |
| library, |
| r''' |
| const int a; |
| constantInitializer |
| CascadeExpression |
| cascadeSections |
| PropertyAccess |
| operator: .. |
| propertyName: SimpleIdentifier |
| staticElement: dart:core::@class::int::@getter::isEven |
| staticType: bool |
| token: isEven |
| staticType: bool |
| MethodInvocation |
| argumentList: ArgumentList |
| methodName: SimpleIdentifier |
| staticElement: dart:core::@class::int::@method::abs |
| staticType: int Function() |
| token: abs |
| operator: .. |
| staticInvokeType: null |
| staticType: int |
| staticType: int |
| target: IntegerLiteral |
| literal: 0 |
| staticType: int |
| ''', |
| annotateNullability: true, |
| withFullyResolvedAst: true, |
| ); |
| } |
| |
| 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; |
| _assertTypeStr( |
| xType, |
| 'C<int>', |
| ); |
| TopLevelVariableElementImpl y = |
| library.definingCompilationUnit.topLevelVariables[0]; |
| InstanceCreationExpression yExpr = y.constantInitializer; |
| var yType = yExpr.constructorName.staticElement.returnType; |
| _assertTypeStr(yType, '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_indexExpression() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(r''' |
| const a = [0]; |
| const b = 0; |
| const c = a[b]; |
| '''); |
| checkElementText( |
| library, |
| r''' |
| const List<int> a; |
| constantInitializer |
| ListLiteral |
| elements |
| IntegerLiteral |
| literal: 0 |
| staticType: int |
| staticType: List<int> |
| const int b; |
| constantInitializer |
| IntegerLiteral |
| literal: 0 |
| staticType: int |
| const int c; |
| constantInitializer |
| IndexExpression |
| index: SimpleIdentifier |
| staticElement: self::@getter::b |
| staticType: int |
| token: b |
| staticElement: MethodMember |
| base: dart:core::@class::List::@method::[] |
| substitution: {E: int} |
| staticType: int |
| target: SimpleIdentifier |
| staticElement: self::@getter::a |
| staticType: List<int> |
| token: a |
| ''', |
| annotateNullability: true, |
| withFullyResolvedAst: true, |
| ); |
| } |
| |
| 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_isExpression() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(''' |
| const a = 0; |
| const b = a is int; |
| '''); |
| checkElementText(library, ''' |
| const int a = 0; |
| const bool b = |
| a/*location: test.dart;a?*/ is |
| int/*location: dart:core;int*/; |
| '''); |
| } |
| |
| 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_methodInvocation() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(r''' |
| T f<T>(T a) => a; |
| const b = f<int>(0); |
| '''); |
| checkElementText( |
| library, |
| r''' |
| const int b; |
| constantInitializer |
| MethodInvocation |
| argumentList: ArgumentList |
| arguments |
| IntegerLiteral |
| literal: 0 |
| staticType: int |
| methodName: SimpleIdentifier |
| staticElement: self::@function::f |
| staticType: T Function<T>(T) |
| token: f |
| staticInvokeType: null |
| staticType: int |
| typeArguments: TypeArgumentList |
| arguments |
| TypeName |
| name: SimpleIdentifier |
| staticElement: dart:core::@class::int |
| staticType: null |
| token: int |
| type: int |
| T f(T a) {} |
| ''', |
| annotateNullability: true, |
| withFullyResolvedAst: 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_postfixExpression_increment() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(r''' |
| const a = 0; |
| const b = a++; |
| '''); |
| checkElementText( |
| library, |
| r''' |
| const int a; |
| constantInitializer |
| IntegerLiteral |
| literal: 0 |
| staticType: int |
| const int b; |
| constantInitializer |
| PostfixExpression |
| operand: SimpleIdentifier |
| staticElement: <null> |
| staticType: null |
| token: a |
| operator: ++ |
| readElement: self::@getter::a |
| readType: int |
| staticElement: dart:core::@class::num::@method::+ |
| staticType: int |
| writeElement: self::@getter::a |
| writeType: dynamic |
| ''', |
| annotateNullability: true, |
| withFullyResolvedAst: true, |
| ); |
| } |
| |
| test_const_postfixExpression_nullCheck() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(r''' |
| const int? a = 0; |
| const b = a!; |
| '''); |
| checkElementText( |
| library, |
| r''' |
| const int? a; |
| constantInitializer |
| IntegerLiteral |
| literal: 0 |
| staticType: int |
| const int b; |
| constantInitializer |
| PostfixExpression |
| operand: SimpleIdentifier |
| staticElement: self::@getter::a |
| staticType: int? |
| token: a |
| operator: ! |
| staticElement: <null> |
| staticType: int |
| ''', |
| annotateNullability: true, |
| withFullyResolvedAst: true, |
| ); |
| } |
| |
| test_const_prefixExpression_increment() async { |
| featureSet = featureSetNullSafe; |
| var library = await checkLibrary(r''' |
| const a = 0; |
| const b = ++a; |
| '''); |
| checkElementText( |
| library, |
| r''' |
| const int a; |
| constantInitializer |
| IntegerLiteral |
| literal: 0 |
| staticType: int |
| const int b; |
| constantInitializer |
| PrefixExpression |
| operand: SimpleIdentifier |
| staticElement: <null> |
| staticType: null |
| token: a |
| operator: ++ |
| readElement: self::@getter::a |
| readType: int |
| staticElement: dart:core::@class::num::@method::+ |
| staticType: int |
| writeElement: self::@getter::a |
| writeType: dynamic |
| ''', |
| annotateNullability: true, |
| withFullyResolvedAst: true, |
| ); |
| } |
| |
| 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; |
|