Version 2.10.0-25.0.dev
Merge commit '0057b6066cf0455ab3b51262e3e9462ed8692926' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index d93eff3..b98042d 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -5186,7 +5186,8 @@
@override
final LinkedUnitContext linkedContext;
- final bool isNonNullableByDefaultInternal;
+ @override
+ final FeatureSet featureSet;
/// The compilation unit that defines this library.
CompilationUnitElement _definingCompilationUnit;
@@ -5232,7 +5233,7 @@
/// Initialize a newly created library element in the given [context] to have
/// the given [name] and [offset].
LibraryElementImpl(this.context, this.session, String name, int offset,
- this.nameLength, this.isNonNullableByDefaultInternal)
+ this.nameLength, this.featureSet)
: linkedContext = null,
super(name, offset);
@@ -5245,7 +5246,7 @@
this.linkedContext,
Reference reference,
CompilationUnit linkedNode)
- : isNonNullableByDefaultInternal = linkedContext.isNNBD,
+ : featureSet = linkedNode.featureSet,
super.forLinkedNode(null, reference, linkedNode) {
_name = name;
_nameOffset = offset;
@@ -5363,9 +5364,6 @@
}
@override
- FeatureSet get featureSet => (linkedNode as CompilationUnit).featureSet;
-
- @override
bool get hasExtUri {
if (linkedNode != null) {
var unit = linkedContext.unit_withDirectives;
@@ -5481,6 +5479,10 @@
bool get isNonNullableByDefault =>
ElementTypeProvider.current.isLibraryNonNullableByDefault(this);
+ bool get isNonNullableByDefaultInternal {
+ return featureSet.isEnabled(Feature.non_nullable);
+ }
+
/// Return `true` if the receiver directly or indirectly imports the
/// 'dart:html' libraries.
bool get isOrImportsBrowserLibrary {
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index f01860f..1a89506 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -1347,88 +1347,13 @@
@override
DartType refineBinaryExpressionType(DartType leftType, TokenType operator,
DartType rightType, DartType currentType) {
- if (leftType is TypeParameterType && leftType.bound.isDartCoreNum) {
- if (rightType == leftType || rightType.isDartCoreInt) {
- if (operator == TokenType.PLUS ||
- operator == TokenType.MINUS ||
- operator == TokenType.STAR ||
- operator == TokenType.PLUS_EQ ||
- operator == TokenType.MINUS_EQ ||
- operator == TokenType.STAR_EQ ||
- operator == TokenType.PLUS_PLUS ||
- operator == TokenType.MINUS_MINUS) {
- if (isNonNullableByDefault) {
- return promoteToNonNull(leftType as TypeImpl);
- }
- return leftType;
- }
- }
- if (rightType.isDartCoreDouble) {
- if (operator == TokenType.PLUS ||
- operator == TokenType.MINUS ||
- operator == TokenType.STAR ||
- operator == TokenType.SLASH) {
- InterfaceTypeImpl doubleType = typeProvider.doubleType;
- if (isNonNullableByDefault) {
- return promoteToNonNull(doubleType);
- }
- return doubleType;
- }
- }
- return currentType;
+ if (isNonNullableByDefault) {
+ return _refineBinaryExpressionTypeNullSafe(
+ leftType, operator, rightType, currentType);
+ } else {
+ return _refineBinaryExpressionTypeLegacy(
+ leftType, operator, rightType, currentType);
}
- // bool
- if (operator == TokenType.AMPERSAND_AMPERSAND ||
- operator == TokenType.BAR_BAR ||
- operator == TokenType.EQ_EQ ||
- operator == TokenType.BANG_EQ) {
- if (isNonNullableByDefault) {
- return promoteToNonNull(typeProvider.boolType);
- }
- return typeProvider.boolType;
- }
- if (leftType.isDartCoreInt) {
- // int op double
- if (operator == TokenType.MINUS ||
- operator == TokenType.PERCENT ||
- operator == TokenType.PLUS ||
- operator == TokenType.STAR ||
- operator == TokenType.MINUS_EQ ||
- operator == TokenType.PERCENT_EQ ||
- operator == TokenType.PLUS_EQ ||
- operator == TokenType.STAR_EQ) {
- if (rightType.isDartCoreDouble) {
- InterfaceTypeImpl doubleType = typeProvider.doubleType;
- if (isNonNullableByDefault) {
- return promoteToNonNull(doubleType);
- }
- return doubleType;
- }
- }
- // int op int
- if (operator == TokenType.MINUS ||
- operator == TokenType.PERCENT ||
- operator == TokenType.PLUS ||
- operator == TokenType.STAR ||
- operator == TokenType.TILDE_SLASH ||
- operator == TokenType.MINUS_EQ ||
- operator == TokenType.PERCENT_EQ ||
- operator == TokenType.PLUS_EQ ||
- operator == TokenType.STAR_EQ ||
- operator == TokenType.TILDE_SLASH_EQ ||
- operator == TokenType.PLUS_PLUS ||
- operator == TokenType.MINUS_MINUS) {
- if (rightType.isDartCoreInt) {
- InterfaceTypeImpl intType = typeProvider.intType;
- if (isNonNullableByDefault) {
- return promoteToNonNull(intType);
- }
- return intType;
- }
- }
- }
- // default
- return currentType;
}
/// Replaces all covariant occurrences of `dynamic`, `void`, and `Object` or
@@ -1516,6 +1441,148 @@
return typeParameterImpl.defaultType;
}).toList();
}
+
+ DartType _refineBinaryExpressionTypeLegacy(DartType leftType,
+ TokenType operator, DartType rightType, DartType currentType) {
+ if (leftType is TypeParameterType && leftType.bound.isDartCoreNum) {
+ if (rightType == leftType || rightType.isDartCoreInt) {
+ if (operator == TokenType.PLUS ||
+ operator == TokenType.MINUS ||
+ operator == TokenType.STAR ||
+ operator == TokenType.PLUS_EQ ||
+ operator == TokenType.MINUS_EQ ||
+ operator == TokenType.STAR_EQ ||
+ operator == TokenType.PLUS_PLUS ||
+ operator == TokenType.MINUS_MINUS) {
+ return leftType;
+ }
+ }
+ if (rightType.isDartCoreDouble) {
+ if (operator == TokenType.PLUS ||
+ operator == TokenType.MINUS ||
+ operator == TokenType.STAR ||
+ operator == TokenType.SLASH) {
+ InterfaceTypeImpl doubleType = typeProvider.doubleType;
+ return doubleType;
+ }
+ }
+ return currentType;
+ }
+ // bool
+ if (operator == TokenType.AMPERSAND_AMPERSAND ||
+ operator == TokenType.BAR_BAR ||
+ operator == TokenType.EQ_EQ ||
+ operator == TokenType.BANG_EQ) {
+ return typeProvider.boolType;
+ }
+ if (leftType.isDartCoreInt) {
+ // int op double
+ if (operator == TokenType.MINUS ||
+ operator == TokenType.PERCENT ||
+ operator == TokenType.PLUS ||
+ operator == TokenType.STAR ||
+ operator == TokenType.MINUS_EQ ||
+ operator == TokenType.PERCENT_EQ ||
+ operator == TokenType.PLUS_EQ ||
+ operator == TokenType.STAR_EQ) {
+ if (rightType.isDartCoreDouble) {
+ InterfaceTypeImpl doubleType = typeProvider.doubleType;
+ return doubleType;
+ }
+ }
+ // int op int
+ if (operator == TokenType.MINUS ||
+ operator == TokenType.PERCENT ||
+ operator == TokenType.PLUS ||
+ operator == TokenType.STAR ||
+ operator == TokenType.TILDE_SLASH ||
+ operator == TokenType.MINUS_EQ ||
+ operator == TokenType.PERCENT_EQ ||
+ operator == TokenType.PLUS_EQ ||
+ operator == TokenType.STAR_EQ ||
+ operator == TokenType.TILDE_SLASH_EQ ||
+ operator == TokenType.PLUS_PLUS ||
+ operator == TokenType.MINUS_MINUS) {
+ if (rightType.isDartCoreInt) {
+ InterfaceTypeImpl intType = typeProvider.intType;
+ return intType;
+ }
+ }
+ }
+ // default
+ return currentType;
+ }
+
+ DartType _refineBinaryExpressionTypeNullSafe(DartType leftType,
+ TokenType operator, DartType rightType, DartType currentType) {
+ if (leftType is TypeParameterType && leftType.bound.isDartCoreNum) {
+ if (rightType == leftType || rightType.isDartCoreInt) {
+ if (operator == TokenType.PLUS ||
+ operator == TokenType.MINUS ||
+ operator == TokenType.STAR ||
+ operator == TokenType.PLUS_EQ ||
+ operator == TokenType.MINUS_EQ ||
+ operator == TokenType.STAR_EQ ||
+ operator == TokenType.PLUS_PLUS ||
+ operator == TokenType.MINUS_MINUS) {
+ return promoteToNonNull(leftType as TypeImpl);
+ }
+ }
+ if (rightType.isDartCoreDouble) {
+ if (operator == TokenType.PLUS ||
+ operator == TokenType.MINUS ||
+ operator == TokenType.STAR ||
+ operator == TokenType.SLASH) {
+ InterfaceTypeImpl doubleType = typeProvider.doubleType;
+ return promoteToNonNull(doubleType);
+ }
+ }
+ return currentType;
+ }
+ // bool
+ if (operator == TokenType.AMPERSAND_AMPERSAND ||
+ operator == TokenType.BAR_BAR ||
+ operator == TokenType.EQ_EQ ||
+ operator == TokenType.BANG_EQ) {
+ return promoteToNonNull(typeProvider.boolType);
+ }
+ if (leftType.isDartCoreInt) {
+ // int op double
+ if (operator == TokenType.MINUS ||
+ operator == TokenType.PERCENT ||
+ operator == TokenType.PLUS ||
+ operator == TokenType.STAR ||
+ operator == TokenType.MINUS_EQ ||
+ operator == TokenType.PERCENT_EQ ||
+ operator == TokenType.PLUS_EQ ||
+ operator == TokenType.STAR_EQ) {
+ if (rightType.isDartCoreDouble) {
+ InterfaceTypeImpl doubleType = typeProvider.doubleType;
+ return promoteToNonNull(doubleType);
+ }
+ }
+ // int op int
+ if (operator == TokenType.MINUS ||
+ operator == TokenType.PERCENT ||
+ operator == TokenType.PLUS ||
+ operator == TokenType.STAR ||
+ operator == TokenType.TILDE_SLASH ||
+ operator == TokenType.MINUS_EQ ||
+ operator == TokenType.PERCENT_EQ ||
+ operator == TokenType.PLUS_EQ ||
+ operator == TokenType.STAR_EQ ||
+ operator == TokenType.TILDE_SLASH_EQ ||
+ operator == TokenType.PLUS_PLUS ||
+ operator == TokenType.MINUS_MINUS) {
+ if (rightType.isDartCoreInt) {
+ InterfaceTypeImpl intType = typeProvider.intType;
+ return promoteToNonNull(intType);
+ }
+ }
+ }
+ // default
+ return currentType;
+ }
}
class _TypeVariableEliminator extends Substitution {
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 0b63323..ec6ff4a 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -4,12 +4,14 @@
import 'dart:collection';
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
@@ -439,12 +441,15 @@
String fileName = "/$libraryName.dart";
CompilationUnitElementImpl unit = compilationUnit(fileName);
LibraryElementImpl library = LibraryElementImpl(
- context,
- AnalysisSessionImpl(null),
- libraryName,
- 0,
- libraryName.length,
- isNonNullableByDefault);
+ context,
+ AnalysisSessionImpl(null),
+ libraryName,
+ 0,
+ libraryName.length,
+ FeatureSet.fromEnableFlags(
+ isNonNullableByDefault ? [EnableString.non_nullable] : [],
+ ),
+ );
library.definingCompilationUnit = unit;
return library;
}
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 0058130..727b439 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -2,7 +2,6 @@
// 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/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/ast/token.dart';
@@ -79,11 +78,6 @@
/// Return `true` if this unit is a part of a bundle that is being linked.
bool get isLinking => bundleContext.isLinking;
- /// TODO(scheglov) remove it
- bool get isNNBD {
- return _unit.featureSet.isEnabled(Feature.non_nullable);
- }
-
TypeProvider get typeProvider {
var libraryReference = libraryContext.reference;
var libraryElement = libraryReference.element as LibraryElementImpl;
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
index 400a4bb..f97de63 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
@@ -2,9 +2,11 @@
// 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/features.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
@@ -823,7 +825,7 @@
'dart.async',
0,
0,
- true,
+ FeatureSet.fromEnableFlags([EnableString.non_nullable]),
);
var asyncUnit = CompilationUnitElementImpl();
@@ -916,7 +918,7 @@
'dart.core',
0,
0,
- true,
+ FeatureSet.fromEnableFlags([EnableString.non_nullable]),
);
coreLibrary.definingCompilationUnit = coreUnit;
diff --git a/pkg/analyzer/test/generated/elements_types_mixin.dart b/pkg/analyzer/test/generated/elements_types_mixin.dart
index 00b967c..9740869 100644
--- a/pkg/analyzer/test/generated/elements_types_mixin.dart
+++ b/pkg/analyzer/test/generated/elements_types_mixin.dart
@@ -2,10 +2,12 @@
// 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/features.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
@@ -400,8 +402,16 @@
AnalysisContext analysisContext,
AnalysisSessionImpl analysisSession,
}) {
- var library = LibraryElementImpl(analysisContext, analysisSession, uriStr,
- -1, 0, typeSystem.isNonNullableByDefault);
+ var library = LibraryElementImpl(
+ analysisContext,
+ analysisSession,
+ uriStr,
+ -1,
+ 0,
+ FeatureSet.fromEnableFlags(
+ typeSystem.isNonNullableByDefault ? [EnableString.non_nullable] : [],
+ ),
+ );
library.typeSystem = typeSystem;
library.typeProvider = typeSystem.typeProvider;
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index dddd438..33b96b4 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -488,12 +488,7 @@
compilationUnit.source = definingCompilationUnitSource;
var featureSet = context.analysisOptions.contextFeatures;
LibraryElementImpl library = LibraryElementImpl(
- context,
- driver?.currentSession,
- libraryName,
- -1,
- 0,
- featureSet.isEnabled(Feature.non_nullable));
+ context, driver?.currentSession, libraryName, -1, 0, featureSet);
library.definingCompilationUnit = compilationUnit;
library.parts = sourcedCompilationUnits;
return library;
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index e51614b..b501bfe 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -739,8 +739,8 @@
definingCompilationUnit.source = source;
var featureSet = FeatureSet.forTesting();
- _definingLibrary = LibraryElementImpl(
- context, null, null, -1, 0, featureSet.isEnabled(Feature.non_nullable));
+ _definingLibrary =
+ LibraryElementImpl(context, null, null, -1, 0, featureSet);
_definingLibrary.definingCompilationUnit = definingCompilationUnit;
_definingLibrary.typeProvider = context.typeProviderLegacy;
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index 311e888..476dcf7 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -2,6 +2,7 @@
// 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/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/ast/token.dart';
@@ -706,7 +707,8 @@
void test_visitPartDirective() {
PartDirective fromNode = AstTestFactory.partDirective2("part.dart");
- LibraryElement element = LibraryElementImpl(null, null, 'lib', -1, 0, true);
+ LibraryElement element = LibraryElementImpl(
+ null, null, 'lib', -1, 0, FeatureSet.fromEnableFlags([]));
fromNode.element = element;
PartDirective toNode = AstTestFactory.partDirective2("part.dart");
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -716,7 +718,8 @@
void test_visitPartOfDirective() {
PartOfDirective fromNode = AstTestFactory.partOfDirective(
AstTestFactory.libraryIdentifier2(["lib"]));
- LibraryElement element = LibraryElementImpl(null, null, 'lib', -1, 0, true);
+ LibraryElement element = LibraryElementImpl(
+ null, null, 'lib', -1, 0, FeatureSet.fromEnableFlags([]));
fromNode.element = element;
PartOfDirective toNode = AstTestFactory.partOfDirective(
AstTestFactory.libraryIdentifier2(["lib"]));
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 3b0915a..f8fa5e5 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -2,6 +2,7 @@
// 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/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -2197,8 +2198,8 @@
void test_setImports() {
AnalysisContext context = TestAnalysisContext();
- LibraryElementImpl library =
- LibraryElementImpl(context, null, 'l1', -1, 0, true);
+ LibraryElementImpl library = LibraryElementImpl(
+ context, null, 'l1', -1, 0, FeatureSet.fromEnableFlags([]));
List<ImportElementImpl> expectedImports = [
ElementFactory.importFor(ElementFactory.library(context, "l2"), null),
ElementFactory.importFor(ElementFactory.library(context, "l3"), null)
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index adc7f8d..e864bec 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -2,12 +2,14 @@
// 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/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/dart/element/type_system.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_provider.dart';
@@ -462,7 +464,7 @@
var uriStr = 'package:test/test.dart';
_myLibrary = LibraryElementImpl(analysisContext, analysisSession, uriStr,
- -1, 0, typeSystem.isNonNullableByDefault);
+ -1, 0, FeatureSet.fromEnableFlags([EnableString.non_nullable]));
_myLibrary.typeSystem = typeSystem;
_myLibrary.typeProvider = coreLibrary.typeProvider;
diff --git a/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart b/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart
index c5be237..a63524f 100644
--- a/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart
+++ b/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart
@@ -370,8 +370,6 @@
diffToJson(diff),
equals({
'#type': 'library',
- '@stubs': {'#type': 'library'},
- '@unknown': {'#type': 'library'},
'package:input': {
'#type': 'package',
'package:input/input.dart': {
@@ -421,8 +419,6 @@
diffToJson(diff),
equals({
'#type': 'library',
- '@stubs': {'#type': 'library'},
- '@unknown': {'#type': 'library'},
'package:input': {
'#type': 'package',
'package:input/input.dart': {
@@ -624,8 +620,6 @@
'#type': 'package',
'package:input/input.dart': {
'#type': 'library',
- '#size': lessThan(0),
- 'K': {'#size': isA<int>(), '#type': 'class'},
'::': {
'#type': 'class',
'makeSomeClosures': {
@@ -691,10 +685,48 @@
// On Windows there is some issue with interpreting entry point URI as a package URI
// it instead gets interpreted as a file URI - which breaks comparison. So we
// simply ignore entry point library (main.dart).
+// Additionally this function removes all nodes with the size below
+// the given threshold.
Map<String, dynamic> diffToJson(ProgramInfo diff,
{bool keepOnlyInputPackage = false}) {
final diffJson = diff.toJson();
diffJson.removeWhere((key, _) =>
keepOnlyInputPackage ? key != 'package:input' : key.startsWith('file:'));
- return diffJson;
+
+ // Rebuild the diff JSON discarding all nodes with size below threshold.
+ const smallChangeThreshold = 16;
+ Map<String, dynamic> discardSmallChanges(Map<String, dynamic> map) {
+ final result = <String, dynamic>{};
+
+ // First recursively process all children (skipping #type and #size keys).
+ for (var key in map.keys) {
+ if (key == '#type' || key == '#size') continue;
+ final value = discardSmallChanges(map[key]);
+ if (value != null) {
+ result[key] = value;
+ }
+ }
+
+ // Check if this node own #size is above the threshold and copy it
+ // into the result if it is.
+ final size = map['#size'] ?? 0;
+ if (size.abs() > smallChangeThreshold) {
+ result['#size'] = size;
+ }
+
+ // If the node has no children and its own size does not pass the threshold
+ // drop it.
+ if (result.isEmpty) {
+ return null;
+ }
+
+ // We decided that this node is meaningful - preserve its type.
+ if (map.containsKey('#type')) {
+ result['#type'] = map['#type'];
+ }
+
+ return result;
+ }
+
+ return discardSmallChanges(diffJson);
}
diff --git a/runtime/tests/vm/dart/deferred_loading_and_weak_serialization_references_test.dart b/runtime/tests/vm/dart/deferred_loading_and_weak_serialization_references_test.dart
new file mode 100644
index 0000000..7447a06
--- /dev/null
+++ b/runtime/tests/vm/dart/deferred_loading_and_weak_serialization_references_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, 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.
+
+// These flags can cause WeakSerializationReferences to replace the owner of
+// some Code, which must be accounted for in AssignLoadingUnitsCodeVisitor.
+
+// VMOptions=--no_retain_function_objects
+// VMOptions=--dwarf_stack_traces
+
+import "splay_test.dart" deferred as splay; // Some non-trivial code.
+
+main() async {
+ await splay.loadLibrary();
+ splay.main();
+}
diff --git a/runtime/tests/vm/dart_2/deferred_loading_and_weak_serialization_references_test.dart b/runtime/tests/vm/dart_2/deferred_loading_and_weak_serialization_references_test.dart
new file mode 100644
index 0000000..7447a06
--- /dev/null
+++ b/runtime/tests/vm/dart_2/deferred_loading_and_weak_serialization_references_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, 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.
+
+// These flags can cause WeakSerializationReferences to replace the owner of
+// some Code, which must be accounted for in AssignLoadingUnitsCodeVisitor.
+
+// VMOptions=--no_retain_function_objects
+// VMOptions=--dwarf_stack_traces
+
+import "splay_test.dart" deferred as splay; // Some non-trivial code.
+
+main() async {
+ await splay.loadLibrary();
+ splay.main();
+}
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 34cc58e..f535c91 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -213,6 +213,12 @@
}
}
+ if (FLAG_print_classes) {
+ for (intptr_t i = 0; i < class_array.Length(); i++) {
+ cls ^= class_array.At(i);
+ PrintClassInformation(cls);
+ }
+ }
// Clear pending classes array.
class_array = GrowableObjectArray::New();
object_store->set_pending_classes(class_array);
@@ -1155,9 +1161,6 @@
}
// Mark as loaded and finalized.
cls.Finalize();
- if (FLAG_print_classes) {
- PrintClassInformation(cls);
- }
FinalizeMemberTypes(cls);
if (cls.is_enum_class()) {
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index c604a7c..878ce4a 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -391,7 +391,7 @@
TraceForRetainedFunctions();
FinalizeDispatchTable();
- ReplaceFunctionPCRelativeCallEntries();
+ ReplaceFunctionStaticCallEntries();
DropFunctions();
DropFields();
@@ -1644,7 +1644,7 @@
printed.Release();
}
-void Precompiler::ReplaceFunctionPCRelativeCallEntries() {
+void Precompiler::ReplaceFunctionStaticCallEntries() {
class StaticCallTableEntryFixer : public CodeVisitor {
public:
explicit StaticCallTableEntryFixer(Zone* zone)
@@ -1660,7 +1660,9 @@
for (auto& view : static_calls) {
kind_and_offset_ = view.Get<Code::kSCallTableKindAndOffset>();
auto const kind = Code::KindField::decode(kind_and_offset_.Value());
- if (kind != Code::kPcRelativeCall) continue;
+
+ if ((kind != Code::kCallViaCode) && (kind != Code::kPcRelativeCall))
+ continue;
target_function_ = view.Get<Code::kSCallTableFunctionTarget>();
if (target_function_.IsNull()) continue;
@@ -1671,6 +1673,12 @@
ASSERT(!target_code_.IsStubCode());
view.Set<Code::kSCallTableCodeOrTypeTarget>(target_code_);
view.Set<Code::kSCallTableFunctionTarget>(Object::null_function());
+ if (kind == Code::kCallViaCode) {
+ auto const pc_offset =
+ Code::OffsetField::decode(kind_and_offset_.Value());
+ const uword pc = pc_offset + code.PayloadStart();
+ CodePatcher::PatchStaticCallAt(pc, code, target_code_);
+ }
if (FLAG_trace_precompiler) {
THR_Print("Updated static call entry to %s in \"%s\"\n",
target_function_.ToFullyQualifiedCString(),
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index 5f84a82..e80a81c 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -301,7 +301,7 @@
void TraceForRetainedFunctions();
void FinalizeDispatchTable();
- void ReplaceFunctionPCRelativeCallEntries();
+ void ReplaceFunctionStaticCallEntries();
void DropFunctions();
void DropFields();
void TraceTypesFromRetainedClasses();
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 1785105..718c6df 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -2002,11 +2002,8 @@
NameIndex KernelReaderHelper::ReadInterfaceMemberNameReference() {
NameIndex name_index = reader_.ReadCanonicalNameReference();
- NameIndex origin_name_index = reader_.ReadCanonicalNameReference();
- if (!FLAG_precompiled_mode && origin_name_index != NameIndex::kInvalidName) {
- // Reference to a skipped member signature target, return the origin target.
- return origin_name_index;
- }
+ reader_
+ .ReadCanonicalNameReference(); // read interface target origin reference
return name_index;
}
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index a992ff3..092af49 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -1947,16 +1947,7 @@
ProcedureHelper procedure_helper(&helper_);
procedure_helper.ReadUntilExcluding(ProcedureHelper::kAnnotations);
- // CFE adds 'member signature' abstract functions to a legacy class deriving
- // or implementing an opted-in interface. The signature of these functions is
- // legacy erased and used as the target of interface calls. They are used for
- // static reasoning about the program by CFE, but not really needed by the VM.
- // In certain situations (e.g. issue 162073826), a large number of these
- // additional functions can cause strain on the VM. They are therefore skipped
- // in jit mode and their associated origin function is used instead as
- // interface call target.
- if (procedure_helper.IsRedirectingFactoryConstructor() ||
- (!FLAG_precompiled_mode && procedure_helper.IsMemberSignature())) {
+ if (procedure_helper.IsRedirectingFactoryConstructor()) {
helper_.SetOffset(procedure_end);
return;
}
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
index 13665eb..b5f73c3 100644
--- a/runtime/vm/program_visitor.cc
+++ b/runtime/vm/program_visitor.cc
@@ -368,8 +368,7 @@
if (target_.IsNull()) {
target_ =
Code::RawCast(view.Get<Code::kSCallTableCodeOrTypeTarget>());
- ASSERT(!Code::Cast(target_).IsFunctionCode());
- // Allocation stub or AllocateContext or AllocateArray or ...
+ ASSERT(!target_.IsNull()); // Already bound.
continue;
}
@@ -1314,7 +1313,7 @@
void VisitCode(const Code& code) {
intptr_t id;
if (code.IsFunctionCode()) {
- func_ ^= code.owner();
+ func_ ^= code.function();
cls_ = func_.Owner();
lib_ = cls_.library();
unit_ = lib_.loading_unit();
diff --git a/tools/VERSION b/tools/VERSION
index d3b9276..93f5efb 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 10
PATCH 0
-PRERELEASE 24
+PRERELEASE 25
PRERELEASE_PATCH 0
\ No newline at end of file