Version 2.17.0-18.0.dev
Merge commit '9bea02b9763e01f8871b7652096be9e10985197d' into 'dev'
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index 8a26c20..305bc67 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -683,6 +683,36 @@
bool isDartDocument(lsp.TextDocumentIdentifier? doc) =>
doc?.uri.endsWith('.dart') ?? false;
+/// Converts a [server.Location] to an [lsp.Range] by translating the
+/// offset/length using a `LineInfo`.
+///
+/// This function ignores any line/column info on the
+/// [server.Location] assuming it is either not available not unreliable.
+lsp.Range locationOffsetLenToRange(
+ server.LineInfo lineInfo, server.Location location) =>
+ toRange(lineInfo, location.offset, location.length);
+
+/// Converts a [server.Location] to an [lsp.Range] if all line and column
+/// values are available.
+///
+/// Returns null if any values are -1 or null.
+lsp.Range? locationToRange(server.Location location) {
+ final startLine = location.startLine;
+ final startColumn = location.startColumn;
+ final endLine = location.endLine ?? -1;
+ final endColumn = location.endColumn ?? -1;
+ if (startLine == -1 ||
+ startColumn == -1 ||
+ endLine == -1 ||
+ endColumn == -1) {
+ return null;
+ }
+ // LSP positions are 0-based but Location is 1-based.
+ return Range(
+ start: Position(line: startLine - 1, character: startColumn - 1),
+ end: Position(line: endLine - 1, character: endColumn - 1));
+}
+
/// Merges two [WorkspaceEdit]s into a single one.
///
/// Will throw if given [WorkspaceEdit]s that do not use documentChanges.
@@ -800,10 +830,12 @@
message = '$message\n${error.correction}';
}
- var lineInfo = getLineInfo(error.location.file);
+ final range = locationToRange(error.location) ??
+ locationOffsetLenToRange(
+ getLineInfo(error.location.file), error.location);
var documentationUrl = error.url;
return lsp.Diagnostic(
- range: toRange(lineInfo, error.location.offset, error.location.length),
+ range: range,
severity: pluginToDiagnosticSeverity(error.severity),
code: error.code,
source: languageSourceName,
@@ -831,6 +863,9 @@
return lsp.DiagnosticRelatedInformation(
location: lsp.Location(
uri: Uri.file(file).toString(),
+ // TODO(dantup): Switch to using line/col information from the context
+ // message once confirmed that AnalyzerConverter is not using the wrong
+ // LineInfo.
range: toRange(
lineInfo,
message.location.offset,
diff --git a/pkg/analysis_server/test/lsp/diagnostic_test.dart b/pkg/analysis_server/test/lsp/diagnostic_test.dart
index 3b7fc18..2d009c7 100644
--- a/pkg/analysis_server/test/lsp/diagnostic_test.dart
+++ b/pkg/analysis_server/test/lsp/diagnostic_test.dart
@@ -30,15 +30,15 @@
final pluginError = plugin.AnalysisError(
plugin.AnalysisErrorSeverity.ERROR,
plugin.AnalysisErrorType.STATIC_TYPE_WARNING,
- plugin.Location(pluginAnalyzedFilePath, 0, 6, 0, 0,
- endLine: 0, endColumn: 6),
+ plugin.Location(pluginAnalyzedFilePath, 0, 6, 1, 1,
+ endLine: 1, endColumn: 7),
'Test error from plugin',
'ERR1',
contextMessages: [
plugin.DiagnosticMessage(
'Related error',
- plugin.Location(pluginAnalyzedFilePath, 31, 4, 1, 12,
- endLine: 1, endColumn: 16))
+ plugin.Location(pluginAnalyzedFilePath, 31, 4, 2, 13,
+ endLine: 2, endColumn: 17))
],
);
final pluginResult =
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 9f2b66c..004c65b 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -290,7 +290,7 @@
@override
void visitSimpleIdentifier(SimpleIdentifier node) {
- var element = node.staticElement;
+ var element = node.staticElement?.declaration;
if (element is PropertyAccessorElement && element.isGetter) {
_set.add(element.variable);
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 4232bfc..5c069d3 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -31540,6 +31540,32 @@
''');
}
+ test_type_inference_classField_fromNullSafe_toLegacy() async {
+ testFile = convertPath('/home/test/lib/test.dart');
+ addLibrarySource('/home/test/lib/a.dart', '''
+class E {
+ static final a = 0;
+}
+''');
+ var library = await checkLibrary('''
+// @dart = 2.9
+import 'a.dart';
+final v = E.a;
+''');
+ checkElementText(library, r'''
+library
+ imports
+ package:test/a.dart
+ definingUnit
+ topLevelVariables
+ static final v @38
+ type: int*
+ accessors
+ synthetic static get v @-1
+ returnType: int*
+''');
+ }
+
test_type_inference_closure_with_function_typed_parameter() async {
var library = await checkLibrary('''
var x = (int f(String x)) => 0;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
index aca8022..1443d95 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
@@ -22,6 +22,6 @@
synthetic constructor •() → self::Class
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3380,getterSelectorId:3381] method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::Enum e) → core::int
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3384,getterSelectorId:3385] method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::Enum e) → core::int
return [@vm.inferred-type.metadata=!] e.{core::_Enum::index}{core::int};
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
index 446a1e7..c16c8ac 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
@@ -51,6 +51,6 @@
synthetic constructor •() → self::ConstClass
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3384,getterSelectorId:3385] method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::ConstEnum e) → core::int
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3388,getterSelectorId:3389] method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::ConstEnum e) → core::int
return [@vm.inferred-type.metadata=!] e.{core::_Enum::index}{core::int};
}
diff --git a/sdk/lib/_internal/vm/lib/compact_hash.dart b/sdk/lib/_internal/vm/lib/compact_hash.dart
index a39e324..f2b6fc0 100644
--- a/sdk/lib/_internal/vm/lib/compact_hash.dart
+++ b/sdk/lib/_internal/vm/lib/compact_hash.dart
@@ -185,6 +185,27 @@
!identical(_data, oldData) || (_checkSum != oldCheckSum);
int get length;
+
+ // If this collection has never had an insertion, and [other] is the same
+ // representation and has had no deletions, then adding the entries of [other]
+ // will end up building the same [_data] and [_index]. We can do this more
+ // efficiently by copying the Lists directly.
+ //
+ // Precondition: [this] and [other] must use the same hashcode and equality.
+ bool _quickCopy(_HashBase other) {
+ if (!identical(_index, _uninitializedIndex)) return false;
+ if (other._usedData == 0) return true; // [other] is empty, nothing to copy.
+ if (other._deletedKeys != 0) return false;
+
+ assert(!identical(other._index, _uninitializedIndex));
+ assert(!identical(other._data, _uninitializedData));
+ _index = Uint32List.fromList(other._index);
+ _hashMask = other._hashMask;
+ _data = List.of(other._data, growable: false);
+ _usedData = other._usedData;
+ _deletedKeys = other._deletedKeys;
+ return true;
+ }
}
class _OperatorEqualsAndHashCode {
@@ -233,6 +254,16 @@
_usedData = 0;
_deletedKeys = 0;
}
+
+ void addAll(Map<K, V> other) {
+ if (other is _InternalLinkedHashMap) {
+ final otherBase = other as _InternalLinkedHashMap; // manual promotion.
+ // If this map is empty we might be able to block-copy from [other].
+ if (isEmpty && _quickCopy(otherBase)) return;
+ // TODO(48143): Pre-grow capacity if it will reduce rehashing.
+ }
+ super.addAll(other);
+ }
}
// This is essentially the same class as _InternalLinkedHashMap, but it does
@@ -531,7 +562,7 @@
return false;
}
- void forEach(void f(K key, V value)) {
+ void forEach(void action(K key, V value)) {
final data = _data;
final checkSum = _checkSum;
final len = _usedData;
@@ -540,7 +571,7 @@
if (_HashBase._isDeleted(data, current)) continue;
final key = internal.unsafeCast<K>(current);
final value = internal.unsafeCast<V>(data[offset + 1]);
- f(key, value);
+ action(key, value);
if (_isModifiedSince(data, checkSum)) {
throw ConcurrentModificationError(this);
}
@@ -561,6 +592,16 @@
_IdenticalAndIdentityHashCode
implements LinkedHashMap<K, V> {
_CompactLinkedIdentityHashMap() : super(_HashBase._INITIAL_INDEX_SIZE);
+
+ void addAll(Map<K, V> other) {
+ if (other is _CompactLinkedIdentityHashMap) {
+ final otherBase = other as _CompactLinkedIdentityHashMap;
+ // If this map is empty we might be able to block-copy from [other].
+ if (isEmpty && _quickCopy(otherBase)) return;
+ // TODO(48143): Pre-grow capacity if it will reduce rehashing.
+ }
+ super.addAll(other);
+ }
}
class _CompactLinkedCustomHashMap<K, V> extends _HashFieldBase
@@ -832,6 +873,16 @@
// is not required by the spec. (For instance, always using an identity set
// would be technically correct, albeit surprising.)
Set<E> toSet() => new _CompactLinkedHashSet<E>()..addAll(this);
+
+ void addAll(Iterable<E> other) {
+ if (other is _CompactLinkedHashSet) {
+ final otherBase = other as _CompactLinkedHashSet;
+ // If this set is empty we might be able to block-copy from [other].
+ if (isEmpty && _quickCopy(otherBase)) return;
+ // TODO(48143): Pre-grow capacity if it will reduce rehashing.
+ }
+ super.addAll(other);
+ }
}
@pragma("vm:entry-point")
@@ -924,6 +975,16 @@
static Set<R> _newEmpty<R>() => new _CompactLinkedIdentityHashSet<R>();
Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newEmpty);
+
+ void addAll(Iterable<E> other) {
+ if (other is _CompactLinkedIdentityHashSet) {
+ final otherBase = other as _CompactLinkedIdentityHashSet;
+ // If this set is empty we might be able to block-copy from [other].
+ if (isEmpty && _quickCopy(otherBase)) return;
+ // TODO(48143): Pre-grow capacity if it will reduce rehashing.
+ }
+ super.addAll(other);
+ }
}
class _CompactLinkedCustomHashSet<E> extends _HashFieldBase
diff --git a/tools/VERSION b/tools/VERSION
index cb01692..1a53903 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 17
+PRERELEASE 18
PRERELEASE_PATCH 0
\ No newline at end of file