diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_test.dart index 5b35b7c8eb54..ef2456ce29c6 100644 --- a/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_test.dart +++ b/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_test.dart @@ -120,7 +120,7 @@ class B extends A { '''); } - /// TODO(scheglov) This test will fail with NNBD SDK. + @FailingTest(issue: 'https://github.com/dart-lang/linter/issues/1997') Future test_method_toString() async { await resolveTestUnit(''' class A { diff --git a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart index 7bd4571aa7ba..40511f13971d 100644 --- a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart +++ b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart @@ -7,14 +7,11 @@ import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/src/context/packages.dart'; import 'package:analyzer/src/generated/source.dart'; import 'package:meta/meta.dart'; -import 'package:pub_semver/pub_semver.dart'; class FeatureSetProvider { /// This flag will be turned to `true` and inlined when we un-fork SDK, /// so that the only SDK is the Null Safe SDK. - static const isNullSafetySdk = false; - - static final _preNonNullableVersion = Version(2, 7, 0); + static const isNullSafetySdk = true; final FeatureSet _sdkFeatureSet; final Packages _packages; @@ -58,11 +55,7 @@ class FeatureSetProvider { @required FeatureSet packageDefaultFeatureSet, @required FeatureSet nonPackageDefaultFeatureSet, }) { - var sdkFeatureSet = _determineSdkFeatureSet( - resourceProvider, - sourceFactory, - packageDefaultFeatureSet, - ); + var sdkFeatureSet = FeatureSet.fromEnableFlags(['non-nullable']); return FeatureSetProvider._( sdkFeatureSet: sdkFeatureSet, @@ -71,32 +64,4 @@ class FeatureSetProvider { nonPackageDefaultFeatureSet: nonPackageDefaultFeatureSet, ); } - - /// Read `dart:core` file and determine if SDK in non-nullable by default. - /// - /// If it is, use the [defaultFeatureSet], which might have enabled - /// [Feature.non_nullable], so SDK will be parsed and resolved as - /// non-nullable. - /// - /// Otherwise, restrict the SDK language to the maximum known now. - static FeatureSet _determineSdkFeatureSet( - ResourceProvider resourceProvider, - SourceFactory sourceFactory, - FeatureSet defaultFeatureSet, - ) { - var objectSource = sourceFactory.forUri('dart:core/object.dart'); - if (objectSource == null) { - objectSource = sourceFactory.forUri('dart:core'); - } - - try { - var objectFile = resourceProvider.getFile(objectSource.fullName); - var objectContent = objectFile.readAsStringSync(); - if (!objectContent.contains('bool operator ==(Object other)')) { - return defaultFeatureSet.restrictToVersion(_preNonNullableVersion); - } - } catch (_) {} - - return defaultFeatureSet; - } } diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart index d5ba0907c2b0..93d231ddc972 100644 --- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart +++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart @@ -26,29 +26,46 @@ import 'dart:math'; part 'stream.dart'; -class Future { - factory Future(computation()) => null; - factory Future.delayed(Duration duration, [T computation()]) => null; - factory Future.microtask(FutureOr computation()) => null; - factory Future.value([FutureOr result]) => null; +abstract class Future { + factory Future(computation()) { + throw 0; + } + + factory Future.delayed(Duration duration, [T computation()?]) { + throw 0; + } + + factory Future.microtask(FutureOr computation()) { + throw 0; + } + + factory Future.value([FutureOr? result]) { + throw 0; + } + + Future then(FutureOr onValue(T value)); - Future then(FutureOr onValue(T value)) => null; Future whenComplete(action()); static Future> wait(Iterable> futures) => null; } -class FutureOr {} +abstract class FutureOr {} abstract class Completer { - factory Completer() => null; - factory Completer.sync() => null; + factory Completer() { + throw 0; + } + + factory Completer.sync() { + throw 0; + } Future get future; bool get isCompleted; - void complete([value]); - void completeError(Object error, [StackTrace stackTrace]); + void complete([FutureOr? value]); + void completeError(Object error, [StackTrace? stackTrace]); } abstract class Timer { @@ -68,10 +85,8 @@ abstract class Stream { Future get first; - StreamSubscription listen(void onData(T event), - { Function onError, - void onDone(), - bool cancelOnError}); + StreamSubscription listen(void onData(T event)?, + {Function? onError, void onDone()?, bool? cancelOnError}); } abstract class StreamIterator {} @@ -79,12 +94,12 @@ abstract class StreamIterator {} abstract class StreamSubscription { bool get isPaused; - Future asFuture([E futureValue]); + Future asFuture([E? futureValue]); Future cancel(); - void onData(void handleData(T data)); - void onError(Function handleError); - void onDone(void handleDone()); - void pause([Future resumeSignal]); + void onData(void handleData(T data)?); + void onError(Function? handleError); + void onDone(void handleDone()?); + void pause([Future? resumeSignal]); void resume(); } @@ -114,56 +129,80 @@ library dart.collection; abstract class HashMap implements Map { external factory HashMap( - {bool equals(K key1, K key2), - int hashCode(K key), - bool isValidKey(potentialKey)}); + {bool Function(K, K)? equals, + int Function(K)? hashCode, + bool Function(dynamic)? isValidKey}); external factory HashMap.identity(); - factory HashMap.from(Map other) => null; + factory HashMap.from(Map other) { + throw 0; + } - factory HashMap.of(Map other) => null; + factory HashMap.of(Map other) { + throw 0; + } factory HashMap.fromIterable(Iterable iterable, - {K key(element), V value(element)}) => null; + {K Function(dynamic element)? key, V Function(dynamic element)? value}) { + throw 0; + } - factory HashMap.fromIterables(Iterable keys, Iterable values) => null; + factory HashMap.fromIterables(Iterable keys, Iterable values) { + throw 0; + } - factory HashMap.fromEntries(Iterable> entries) => null; + factory HashMap.fromEntries(Iterable> entries) { + throw 0; + } } abstract class LinkedHashMap implements Map { external factory LinkedHashMap( - {bool equals(K key1, K key2), - int hashCode(K key), - bool isValidKey(potentialKey)}); + {bool Function(K, K)? equals, + int Function(K)? hashCode, + bool Function(dynamic)? isValidKey}); external factory LinkedHashMap.identity(); - factory LinkedHashMap.from(Map other) => null; + factory LinkedHashMap.from(Map other) { + throw 0; + } + + factory LinkedHashMap.of(Map other) { + throw 0; + } - factory LinkedHashMap.of(Map other) => null; + factory LinkedHashMap.fromIterable(Iterable iterable, + {K Function(dynamic element)? key, V Function(dynamic element)? value}) { + throw 0; + } - factory LinkedHashMap.fromIterable(Iterable iterable, - {K key(element), V value(element)}) => null; - factory LinkedHashMap.fromIterables(Iterable keys, Iterable values) - => null; + factory LinkedHashMap.fromIterables(Iterable keys, Iterable values) { + throw 0; + } - factory LinkedHashMap.fromEntries(Iterable> entries) => null; + factory LinkedHashMap.fromEntries(Iterable> entries) { + throw 0; + } } abstract class LinkedHashSet implements Set { external factory LinkedHashSet( - {bool equals(E e1, E e2), - int hashCode(E e), - bool isValidKey(potentialKey)}); + {bool Function(E, E)? equals, + int Function(E)? hashCode, + bool Function(dynamic)? isValidKey}); external factory LinkedHashSet.identity(); - factory LinkedHashSet.from(Iterable elements) => null; + factory LinkedHashSet.from(Iterable elements) { + throw 0; + } - factory LinkedHashSet.of(Iterable elements) => null; + factory LinkedHashSet.of(Iterable elements) { + throw 0; + } } ''', ) @@ -205,9 +244,9 @@ const override = const _Override(); const proxy = const _Proxy(); -external bool identical(Object a, Object b); +external bool identical(Object? a, Object? b); -void print(Object object) {} +void print(Object? object) {} abstract class bool extends Object { external const factory bool.fromEnvironment(String name, @@ -233,7 +272,7 @@ class Deprecated extends Object { class pragma { final String name; - final Object options; + final Object? options; const pragma(this.name, [this.options]); } @@ -264,19 +303,24 @@ abstract class double extends num { int truncate(); double truncateToDouble(); - external static double parse(String source, [double onError(String source)]); + external static double parse(String source, + [@deprecated double onError(String source)?]); + + external static double? tryParse(String source); } class Duration implements Comparable {} class Error { Error(); - static String safeToString(Object object) => ''; - external StackTrace get stackTrace; + static String safeToString(Object? object) => ''; + external StackTrace? get stackTrace; } class Exception { - factory Exception([var message]) => null; + factory Exception([var message]) { + throw 0; + } } class FormatException implements Exception {} @@ -284,7 +328,8 @@ class FormatException implements Exception {} class Function {} abstract class int extends num { - external const factory int.fromEnvironment(String name, {int defaultValue}); + external const factory int.fromEnvironment(String name, + {int defaultValue = 0}); bool get isEven => false; bool get isNegative; @@ -302,7 +347,9 @@ abstract class int extends num { String toString(); external static int parse(String source, - {int radix, int onError(String source)}); + {int? radix, @deprecated int onError(String source)?}); + + external static int? tryParse(String source, {int? radix}); } abstract class Invocation {} @@ -318,9 +365,9 @@ abstract class Iterable { Iterable expand(Iterable f(E element)); - E firstWhere(bool test(E element), { E orElse()}); + E firstWhere(bool test(E element), {E orElse()?}); - R fold(R initialValue, R combine(R previousValue, E element)) => null; + R fold(R initialValue, R combine(R previousValue, E element)); void forEach(void f(E element)); @@ -339,9 +386,9 @@ abstract class Iterator { } class List implements Iterable { - List([int length]); - external factory List.from(Iterable elements, {bool growable: true}); + external factory List([int? length]); external factory List.filled(int length, E fill, {bool growable = false}); + external factory List.empty({bool growable = false}); external factory List.from(Iterable elements, {bool growable = true}); external factory List.of(Iterable elements, {bool growable = true}); external factory List.generate(int length, E generator(int index), @@ -363,10 +410,17 @@ class List implements Iterable { } class Map { - factory Map() => null; + external factory Map(); + external factory Map.from(); + external Map.of(Map other); + external factory Map.unmodifiable(Map other); + external factory Map.identity(); + + external factory Map.fromIterable(Iterable iterable, + {K key(element)?, V value(element)?}); - factory Map.fromIterable(Iterable iterable, - {K key(element), V value(element)}) => null; + external factory Map.fromIterables(Iterable keys, Iterable values); + external factory Map.fromEntries(Iterable> entries); Iterable get keys => null; bool get isEmpty; @@ -374,17 +428,24 @@ class Map { int get length => 0; Iterable get values => null; - V operator [](K key) => null; + V? operator [](K key) => null; void operator []=(K key, V value) {} Map cast() => null; - bool containsKey(Object key) => false; + bool containsKey(Object? key) => false; } class Null extends Object { factory Null._uninstantiable() => null; } +class MapEntry { + final K key; + final V value; + const factory MapEntry(K key, V value) = MapEntry._; + const MapEntry._(this.key, this.value); +} + abstract class num implements Comparable { num operator %(num other); num operator *(num other); @@ -414,13 +475,13 @@ abstract class num implements Comparable { class Object { const Object(); - int get hashCode => 0; - Type get runtimeType => null; + external int get hashCode; + external Type get runtimeType; - bool operator ==(Object other) => identical(this, other); + external bool operator ==(Object other); - String toString() => 'a string'; - dynamic noSuchMethod(Invocation invocation) => null; + external String toString(); + external dynamic noSuchMethod(Invocation invocation); } abstract class Pattern {} @@ -430,36 +491,48 @@ abstract class RegExp implements Pattern { } abstract class Set implements Iterable { - factory Set() => null; - factory Set.identity() => null; - factory Set.from(Iterable elements) => null; - factory Set.of(Iterable elements) => null; + external factory Set(); + external factory Set.identity(); + external factory Set.from(Iterable elements); + external factory Set.of(Iterable elements); Set cast(); - void add(E element) {} + bool add(E value); + void addAll(Iterable elements); + bool remove(Object? value); + E? lookup(Object? object); } class StackTrace {} abstract class String implements Comparable, Pattern { external factory String.fromCharCodes(Iterable charCodes, - [int start = 0, int end]); + [int start = 0, int? end]); + + external factory String.fromCharCode(int charCode); + + external const factory String.fromEnvironment(String name, + {String defaultValue = ""}); List get codeUnits; - int indexOf(Pattern pattern, [int start]); bool get isEmpty => false; bool get isNotEmpty => false; int get length => 0; - String operator +(String other) => null; bool operator ==(Object other); + String operator [](int index); + String operator +(String other); + String operator *(int times); int codeUnitAt(int index); bool contains(String other, [int startIndex = 0]); + int indexOf(Pattern pattern, [int start = 0]); + int lastIndexOf(Pattern pattern, [int? start]); + bool startsWith(Pattern pattern, [int index = 0]); String splitMapJoin(Pattern pattern, - {String Function(Match) onMatch, String Function(String) onNonMatch}); - String substring(int len) => null; + {String Function(Match)? onMatch, String Function(String)? onNonMatch}); + String substring(int startIndex, [int? endIndex]); String toLowerCase(); String toUpperCase(); } diff --git a/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart b/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart index 419c32bdbd52..7fa6a0242886 100644 --- a/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart +++ b/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart @@ -134,7 +134,7 @@ test:lib/ _buildProvider([]); var featureSet = _getSdkFeatureSet(); - expect(featureSet.isEnabled(Feature.non_nullable), isFalse); + expect(featureSet.isEnabled(Feature.non_nullable), isTrue); } test_sdk_defaultNonNullable_sdkLegacy() { @@ -145,7 +145,7 @@ test:lib/ _buildProvider(['non-nullable']); var featureSet = _getSdkFeatureSet(); - expect(featureSet.isEnabled(Feature.non_nullable), isFalse); + expect(featureSet.isEnabled(Feature.non_nullable), isTrue); } test_sdk_defaultNonNullable_sdkNonNullable() { diff --git a/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart index 72981c068073..c21f0a51f98e 100644 --- a/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart +++ b/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart @@ -48,8 +48,8 @@ int f() async { error(StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE, 0, 3), error(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION, 25, 1, contextMessages: [ - message('/sdk/lib/core/core.dart', 2003, 3), - message('/sdk/lib/core/core.dart', 2003, 3) + message('/sdk/lib/core/core.dart', 2090, 3), + message('/sdk/lib/core/core.dart', 2090, 3) ]), ]); } diff --git a/pkg/nnbd_migration/lib/src/decorated_type.dart b/pkg/nnbd_migration/lib/src/decorated_type.dart index 905fbca29080..3a5b782fc7c6 100644 --- a/pkg/nnbd_migration/lib/src/decorated_type.dart +++ b/pkg/nnbd_migration/lib/src/decorated_type.dart @@ -378,6 +378,15 @@ class DecoratedType implements DecoratedTypeInfo { namedParameters: namedParameters, typeArguments: typeArguments); + /// Creates a shallow copy of `this`, replacing the nullability node and the + /// type. + DecoratedType withNodeAndType(NullabilityNode node, DartType type) => + DecoratedType(type, node, + returnType: returnType, + positionalParameters: positionalParameters, + namedParameters: namedParameters, + typeArguments: typeArguments); + /// Internal implementation of [_substitute], used as a recursion target. DecoratedType _substitute( Map substitution, @@ -404,8 +413,8 @@ class DecoratedType implements DecoratedTypeInfo { var typeFormal = typeFormals[i]; var oldDecoratedBound = DecoratedTypeParameterBounds.current.get(typeFormal); - var newDecoratedBound = oldDecoratedBound._substitute( - substitution, typeFormal.bound ?? oldDecoratedBound.type); + var newDecoratedBound = oldDecoratedBound._substitute(substitution, + undecoratedResult.typeFormals[i].bound ?? oldDecoratedBound.type); if (identical(typeFormal, undecoratedResult.typeFormals[i])) { assert(oldDecoratedBound == newDecoratedBound); } else { @@ -428,8 +437,9 @@ class DecoratedType implements DecoratedTypeInfo { if (inner == null) { return this; } else { - return inner - .withNode(NullabilityNode.forSubstitution(inner.node, node)); + return inner.withNodeAndType( + NullabilityNode.forSubstitution(inner.node, node), + undecoratedResult); } } else if (type.isVoid || type.isDynamic) { return this; diff --git a/pkg/nnbd_migration/test/fix_builder_test.dart b/pkg/nnbd_migration/test/fix_builder_test.dart index 47a1a5e4d266..4750c47a891b 100644 --- a/pkg/nnbd_migration/test/fix_builder_test.dart +++ b/pkg/nnbd_migration/test/fix_builder_test.dart @@ -2253,6 +2253,7 @@ _f(_C/*?*/ c) => c?.hashCode; visitSubexpression(findNode.propertyAccess('c?.hashCode'), 'int?'); } + @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/40475') Future test_propertyAccess_nullAware_object_tearoff() async { await analyze(''' class _C {}