Version 2.16.0-115.0.dev
Merge commit '59979dc9733498772cfe00c8baceb61a00da7770' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 181ddae..514d859 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -612,22 +612,20 @@
}
var conditionResultBool = conditionResult.toBoolValue();
- if (conditionResultBool == null) {
- node.thenExpression.accept(this);
- node.elseExpression.accept(this);
- } else if (conditionResultBool == true) {
+ if (conditionResultBool == true) {
_reportNotPotentialConstants(node.elseExpression);
return node.thenExpression.accept(this);
} else if (conditionResultBool == false) {
_reportNotPotentialConstants(node.thenExpression);
return node.elseExpression.accept(this);
+ } else {
+ node.thenExpression.accept(this);
+ node.elseExpression.accept(this);
+ return DartObjectImpl.validWithUnknownValue(
+ typeSystem,
+ node.typeOrThrow,
+ );
}
-
- // We used to return an object with a known type and an unknown value, but
- // we can't do that without evaluating both the 'then' and 'else'
- // expressions, and we're not suppose to do that under lazy semantics. I'm
- // not sure which failure mode is worse.
- return null;
}
@override
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 313caf6..b6c4de1 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -165,7 +165,7 @@
/// Create an object to represent an unknown value.
factory DartObjectImpl.validWithUnknownValue(
TypeSystemImpl typeSystem,
- ParameterizedType type,
+ DartType type,
) {
if (type.element!.library!.isDartCore) {
if (type.isDartCoreBool) {
diff --git a/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart b/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
index f9bcac1..cdd3c81 100644
--- a/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
@@ -288,6 +288,20 @@
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 46, 5),
]);
}
+
+ test_unknown_conditionalExpression_unknownCondition() async {
+ await assertNoErrorsInCode(r'''
+const bool kIsWeb = identical(0, 0.0);
+
+void f() {
+ const A(kIsWeb ? 0 : 1);
+}
+
+class A {
+ const A(int _);
+}
+''');
+ }
}
@reflectiveTest
diff --git a/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart b/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
index 8b46bb4..e961fd2 100644
--- a/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
+++ b/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
@@ -882,307 +882,3 @@
final js.Statement statement;
HolderInitCode(this.allHolders, this.activeHolders, this.statement);
}
-
-/// All of the code below this point is legacy code.
-
-/// [DeferredHolderExpressionFinalizerImpl] finalizes
-/// [DeferredHolderExpression]s, [DeferredHolderParameter]s,
-/// [DeferredHolderResource]s, [DeferredHolderResourceExpression]s.
-class LegacyDeferredHolderExpressionFinalizerImpl
- implements DeferredHolderExpressionFinalizer {
- _DeferredHolderExpressionCollectorVisitor _visitor;
- final List<DeferredHolderExpression> holderReferences = [];
- final List<DeferredHolderParameter> holderParameters = [];
- final List<DeferredHolderResource> holderResources = [];
- final Set<String> _uniqueHolders = {};
- final List<String> _holders = [];
- final Map<Entity, String> _entityMap = {};
- final JCommonElements _commonElements;
-
- LegacyDeferredHolderExpressionFinalizerImpl(this._commonElements) {
- _visitor = _DeferredHolderExpressionCollectorVisitor(this);
- }
-
- @override
- void addCode(String resourceName, js.Node code) {
- _visitor.setResourceNameAndVisit(resourceName, code);
- }
-
- final List<String> userGlobalObjects =
- List.from(Namer.reservedGlobalObjectNames)
- ..remove('C')
- ..remove('H')
- ..remove('J')
- ..remove('P')
- ..remove('W');
-
- /// Returns the [reservedGlobalObjectNames] for [library].
- String globalObjectForLibrary(LibraryEntity library) {
- if (library == _commonElements.interceptorsLibrary) return 'J';
- Uri uri = library.canonicalUri;
- if (uri.scheme == 'dart') {
- if (uri.path == 'html') return 'W';
- if (uri.path.startsWith('_')) return 'H';
- return 'P';
- }
- return userGlobalObjects[library.name.hashCode % userGlobalObjects.length];
- }
-
- /// Returns true if [element] is stored in the static state holder
- /// ([staticStateHolder]). We intend to store only mutable static state
- /// there, whereas constants are stored in 'C'. Functions, accessors,
- /// classes, etc. are stored in one of the other objects in
- /// [reservedGlobalObjectNames].
- bool _isPropertyOfStaticStateHolder(MemberEntity element) {
- // TODO(ahe): Make sure this method's documentation is always true and
- // remove the word "intend".
- return element.isField;
- }
-
- String globalObjectForMember(MemberEntity entity) {
- if (_isPropertyOfStaticStateHolder(entity)) {
- return globalObjectForStaticState();
- } else {
- return globalObjectForLibrary(entity.library);
- }
- }
-
- String globalObjectForClass(ClassEntity entity) {
- return globalObjectForLibrary(entity.library);
- }
-
- String globalObjectForInterceptors() => 'J';
-
- String globalObjectForStaticState() => r'$';
-
- String globalObjectForConstants() => 'C';
-
- String globalObjectForEntity(Entity entity) {
- if (entity is MemberEntity) {
- return globalObjectForMember(entity);
- } else if (entity is ClassEntity) {
- return globalObjectForLibrary(entity.library);
- } else {
- assert(entity is LibraryEntity);
- return globalObjectForLibrary(entity);
- }
- }
-
- /// Registers an [Entity] with a specific [holder].
- void registerHolderUse(String holder, Object data) {
- if (_uniqueHolders.add(holder)) _holders.add(holder);
- if (data != null && data is Entity) {
- assert(!_entityMap.containsKey(data) || _entityMap[data] == holder);
- _entityMap[data] = holder;
- }
- }
-
- /// Returns a global object for a given [Object] based on the
- /// [DeferredHolderExpressionKind].
- String kindToHolder(DeferredHolderExpressionKind kind, Object data) {
- switch (kind) {
- case DeferredHolderExpressionKind.globalObjectForInterceptors:
- return globalObjectForInterceptors();
- case DeferredHolderExpressionKind.globalObjectForClass:
- return globalObjectForClass(data);
- case DeferredHolderExpressionKind.globalObjectForMember:
- return globalObjectForMember(data);
- case DeferredHolderExpressionKind.globalObjectForConstant:
- return globalObjectForConstants();
- case DeferredHolderExpressionKind.globalObjectForStaticState:
- return globalObjectForStaticState();
- }
- throw UnsupportedError("Unreachable");
- }
-
- /// Finalizes [DeferredHolderExpression]s [DeferredHolderParameter]s.
- void finalizeReferences() {
- // Finalize [DeferredHolderExpression]s and registers holder usage.
- for (var reference in holderReferences) {
- if (reference.isFinalized) continue;
- Object data = reference.data;
- String holder = kindToHolder(reference.kind, data);
- js.Expression value = js.VariableUse(holder);
- registerHolderUse(holder, data);
- reference.value =
- value.withSourceInformation(reference.sourceInformation);
- }
-
- // Finalize [DeferredHolderParameter]s.
- for (var parameter in holderParameters) {
- if (parameter.isFinalized) continue;
- parameter.name = globalObjectForStaticState();
- }
- }
-
- /// Registers all of the holders used by a given [DeferredHolderResource].
- void registerHolders(DeferredHolderResource resource) {
- for (var entity in resource.holderCode.keys) {
- var holder = globalObjectForEntity(entity);
- registerHolderUse(holder, entity);
- }
- }
-
- /// Returns a [List<String>] containing all of the holders except the static
- /// state holder.
- List<String> get nonStaticStateHolders {
- return _holders
- .where((holder) => holder != globalObjectForStaticState())
- .toList(growable: false);
- }
-
- /// Generates code to declare holders.
- LegacyHolderCode declareHolders(DeferredHolderResource resource) {
- // Collect all holders except the static state holder. Then, create a map of
- // holder to list of properties which are associated with that holder, but
- // only with respect to a given [DeferredHolderResource]. Each fragment will
- // have its own [DeferredHolderResource] and associated code.
- Map<String, List<js.Property>> codePerHolder = {};
- final holders = nonStaticStateHolders;
- for (var holder in holders) {
- codePerHolder[holder] = [];
- }
-
- final holderCode = resource.holderCode;
- holderCode.forEach((entity, properties) {
- assert(_entityMap.containsKey(entity));
- var holder = _entityMap[entity];
- assert(codePerHolder.containsKey(holder));
- codePerHolder[holder].addAll(properties);
- });
-
- // Create holder initialization code based on the [codePerHolder]. If there
- // are no properties associated with a given holder in this specific
- // [DeferredHolderResource] then it will be omitted. However, in some cases,
- // i.e. the main output unit, we still want to declare the holder with an
- // empty object literal which will be filled in later by another
- // [DeferredHolderResource], i.e. in a specific deferred fragment.
- // The generated code looks like this:
- //
- // {
- // var H = {...}, ..., G = {...};
- // var holders = [ H, ..., G ]; // Main unit only.
- // }
-
- List<String> activeHolders = [];
- List<js.VariableInitialization> holderInitializations = [];
- for (var holder in holders) {
- List<js.Property> properties = codePerHolder[holder];
- if (properties.isEmpty) {
- holderInitializations.add(js.VariableInitialization(
- js.VariableDeclaration(holder, allowRename: false),
- resource.isMainFragment ? js.ObjectInitializer(properties) : null));
- } else {
- activeHolders.add(holder);
- holderInitializations.add(js.VariableInitialization(
- js.VariableDeclaration(holder, allowRename: false),
- js.ObjectInitializer(properties)));
- }
- }
-
- List<js.Statement> statements = [];
- statements.add(js.ExpressionStatement(js.VariableDeclarationList(
- holderInitializations,
- indentSplits: false)));
- if (resource.isMainFragment) {
- statements.add(js.js.statement(
- 'var holders = #',
- js.ArrayInitializer(holders
- .map((holder) => js.VariableUse(holder))
- .toList(growable: false))));
- }
- return LegacyHolderCode(activeHolders, statements);
- }
-
- /// Finalizes [resource] to code that updates holders. [resource] must be in
- /// the AST of a deferred fragment.
- void updateHolders(DeferredHolderResource resource) {
- // Declare holders.
- final holderCode = declareHolders(resource);
-
- // Set names if necessary on deferred holders list.
- js.Expression deferredHoldersList = js.ArrayInitializer(holderCode
- .activeHolders
- .map((holder) => js.js("#", holder))
- .toList(growable: false));
- js.Statement setNames = js.js.statement(
- 'hunkHelpers.setFunctionNamesIfNecessary(#deferredHoldersList)',
- {'deferredHoldersList': deferredHoldersList});
-
- // Update holder assignments.
- final holders = nonStaticStateHolders;
- List<js.Statement> updateHolderAssignments = [setNames];
- for (int i = 0; i < holders.length; i++) {
- var holder = holders[i];
- if (holderCode.activeHolders.contains(holder)) {
- updateHolderAssignments.add(js.js.statement(
- '#holder = hunkHelpers.updateHolder(holdersList[#index], #holder)',
- {'index': js.number(i), 'holder': js.VariableUse(holder)}));
- } else {
- // TODO(sra): Change declaration followed by assignments to declarations
- // with initialization.
- updateHolderAssignments.add(js.js.statement(
- '#holder = holdersList[#index]',
- {'index': js.number(i), 'holder': js.VariableUse(holder)}));
- }
- }
-
- // Create a single block of all statements.
- List<js.Statement> statements = holderCode.statements
- .followedBy(updateHolderAssignments)
- .toList(growable: false);
- resource.statement = js.Block(statements);
- }
-
- /// Allocates all [DeferredHolderResource]s and
- /// [DeferredHolderResourceExpression]s.
- void allocateResources() {
- // First ensure all holders used in all [DeferredHolderResource]s have been
- // allocated.
- for (var resource in holderResources) {
- registerHolders(resource);
- }
- _holders.sort();
-
- // Next finalize all [DeferredHolderResource]s.
- for (var resource in holderResources) {
- switch (resource.kind) {
- case DeferredHolderResourceKind.mainFragment:
- var holderCode = declareHolders(resource);
- resource.statement = js.Block(holderCode.statements);
- break;
- case DeferredHolderResourceKind.deferredFragment:
- updateHolders(resource);
- break;
- }
- }
- }
-
- @override
- void finalize() {
- finalizeReferences();
- allocateResources();
- }
-
- @override
- void registerDeferredHolderExpression(
- String resourceName, DeferredHolderExpression node) {
- holderReferences.add(node);
- }
-
- @override
- void registerDeferredHolderResource(DeferredHolderResource node) {
- holderResources.add(node);
- }
-
- @override
- void registerDeferredHolderParameter(DeferredHolderParameter node) {
- holderParameters.add(node);
- }
-}
-
-class LegacyHolderCode {
- final List<String> activeHolders;
- final List<js.Statement> statements;
- LegacyHolderCode(this.activeHolders, this.statements);
-}
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index 5e67e37..e07ef90 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -640,10 +640,8 @@
this._nativeEmitter,
this._closedWorld,
this._codegenWorld)
- : _holderFinalizer = _options.features.newHolders.isEnabled
- ? DeferredHolderExpressionFinalizerImpl(_closedWorld.commonElements)
- : LegacyDeferredHolderExpressionFinalizerImpl(
- _closedWorld.commonElements) {
+ : _holderFinalizer =
+ DeferredHolderExpressionFinalizerImpl(_closedWorld.commonElements) {
_recipeEncoder = RecipeEncoderImpl(
_closedWorld,
_options.disableRtiOptimization
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index de9ddca..ea27263 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -64,7 +64,6 @@
DeferredHolderParameter,
DeferredHolderResource,
DeferredHolderResourceKind,
- LegacyDeferredHolderExpressionFinalizerImpl,
mainResourceName;
import '../../js_backend/type_reference.dart'
show
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 088ef9c..b0be710 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -77,12 +77,13 @@
FeatureOption useContentSecurityPolicy = FeatureOption('csp');
/// [FeatureOption]s which are shipped and cannot be toggled.
- late final List<FeatureOption> shipped = [];
+ late final List<FeatureOption> shipped = [
+ newHolders,
+ ];
/// [FeatureOption]s which default to enabled.
late final List<FeatureOption> shipping = [
legacyJavaScript,
- newHolders,
useContentSecurityPolicy
];
diff --git a/tools/VERSION b/tools/VERSION
index 49eda3a..7c980b1 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 16
PATCH 0
-PRERELEASE 114
+PRERELEASE 115
PRERELEASE_PATCH 0
\ No newline at end of file