[_fe_analyzer_shared] Update SDK constraint to ^3.9.0 and reformat files.
Change-Id: I6a6a69642c8c0417d3d8f2680daf68c48694bf03 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/446989 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
@@ -324,8 +324,8 @@ class _Checker {
|
||||
|
||||
// Sorting isn't necessary, but makes the behavior deterministic.
|
||||
List<Key> sortedPropertyKeys = propertyKeys.toList()..sort();
|
||||
List<Key> sortedAdditionalPropertyKeys =
|
||||
additionalPropertyKeys.toList()..sort();
|
||||
List<Key> sortedAdditionalPropertyKeys = additionalPropertyKeys.toList()
|
||||
..sort();
|
||||
|
||||
// Remove the first column from the value list and replace it with any
|
||||
// expanded fields.
|
||||
|
||||
@@ -323,16 +323,15 @@ class ExhaustivenessCache<
|
||||
String textualRepresentation,
|
||||
) {
|
||||
Type nonNullable = typeOperations.getNonNullable(type);
|
||||
StaticType staticType =
|
||||
_uniqueTypeMap[uniqueValue] ??=
|
||||
new GeneralValueStaticType<Type, Identity>(
|
||||
typeOperations,
|
||||
this,
|
||||
nonNullable,
|
||||
new IdentityRestriction<Identity>(uniqueValue),
|
||||
textualRepresentation,
|
||||
uniqueValue,
|
||||
);
|
||||
StaticType staticType = _uniqueTypeMap[uniqueValue] ??=
|
||||
new GeneralValueStaticType<Type, Identity>(
|
||||
typeOperations,
|
||||
this,
|
||||
nonNullable,
|
||||
new IdentityRestriction<Identity>(uniqueValue),
|
||||
textualRepresentation,
|
||||
uniqueValue,
|
||||
);
|
||||
if (typeOperations.isNullable(type)) {
|
||||
staticType = staticType.nullable;
|
||||
}
|
||||
@@ -657,8 +656,9 @@ mixin SpaceCreator<Pattern extends Object, Type extends Object> {
|
||||
if (space.singleSpaces.length == 1) {
|
||||
// Optimize for simple spaces to avoid unnecessary expansion of subtypes.
|
||||
SingleSpace singleSpace = space.singleSpaces.single;
|
||||
bool isUnrestricted =
|
||||
unrestrictedCache[singleSpace] ??= _isUnrestricted(singleSpace);
|
||||
bool isUnrestricted = unrestrictedCache[singleSpace] ??= _isUnrestricted(
|
||||
singleSpace,
|
||||
);
|
||||
if (isUnrestricted && type.isSubtypeOf(singleSpace.type)) {
|
||||
return true;
|
||||
}
|
||||
@@ -677,8 +677,8 @@ mixin SpaceCreator<Pattern extends Object, Type extends Object> {
|
||||
for (StaticType subtype in subtypes) {
|
||||
bool found = false;
|
||||
for (SingleSpace singleSpace in space.singleSpaces) {
|
||||
bool isUnrestricted =
|
||||
unrestrictedCache[singleSpace] ??= _isUnrestricted(singleSpace);
|
||||
bool isUnrestricted = unrestrictedCache[singleSpace] ??=
|
||||
_isUnrestricted(singleSpace);
|
||||
if (isUnrestricted && subtype.isSubtypeOf(singleSpace.type)) {
|
||||
found = true;
|
||||
break;
|
||||
|
||||
@@ -496,18 +496,15 @@ class WrappedStaticType extends _BaseStaticType {
|
||||
@override
|
||||
late final StaticType nonNullable =
|
||||
wrappedType.nonNullable == wrappedType &&
|
||||
impliedType.nonNullable == impliedType
|
||||
? this
|
||||
: new WrappedStaticType(
|
||||
wrappedType.nonNullable,
|
||||
impliedType.nonNullable,
|
||||
);
|
||||
impliedType.nonNullable == impliedType
|
||||
? this
|
||||
: new WrappedStaticType(wrappedType.nonNullable, impliedType.nonNullable);
|
||||
|
||||
@override
|
||||
late final StaticType nullable =
|
||||
wrappedType.nullable == wrappedType && impliedType.nullable == impliedType
|
||||
? this
|
||||
: new WrappedStaticType(wrappedType.nullable, impliedType.nullable);
|
||||
? this
|
||||
: new WrappedStaticType(wrappedType.nullable, impliedType.nullable);
|
||||
|
||||
@override
|
||||
void typeToDart(DartTemplateBuffer buffer) {
|
||||
|
||||
@@ -126,14 +126,9 @@ class ExpressionInfo<Type extends Object> {
|
||||
/// contains information about the expression `x == null`, calling this method
|
||||
/// produces an [ExpressionInfo] containing information about the expression
|
||||
/// `x != null`.
|
||||
ExpressionInfo<Type> _invert() =>
|
||||
isNonTrivial
|
||||
? new ExpressionInfo<Type>(
|
||||
type: _type,
|
||||
ifTrue: ifFalse,
|
||||
ifFalse: ifTrue,
|
||||
)
|
||||
: this;
|
||||
ExpressionInfo<Type> _invert() => isNonTrivial
|
||||
? new ExpressionInfo<Type>(type: _type, ifTrue: ifFalse, ifFalse: ifTrue)
|
||||
: this;
|
||||
}
|
||||
|
||||
/// [PropertyTarget] that is an expression appearing explicitly in the source
|
||||
@@ -2584,8 +2579,8 @@ class FlowAnalysisDebug<
|
||||
Map<Type, NonPromotionReason> Function() callback,
|
||||
) {
|
||||
String callbackToString = '#CALLBACK${_nextCallbackId++}';
|
||||
Map<Type, NonPromotionReason> Function() wrappedCallback =
|
||||
() => _wrap('$callbackToString()', callback, isQuery: true);
|
||||
Map<Type, NonPromotionReason> Function() wrappedCallback = () =>
|
||||
_wrap('$callbackToString()', callback, isQuery: true);
|
||||
_description[wrappedCallback] = callbackToString;
|
||||
return wrappedCallback;
|
||||
}
|
||||
@@ -2726,8 +2721,8 @@ class FlowModel<Type extends Object> {
|
||||
// guaranteed to be already assigned and won't be assigned again.
|
||||
if (helper.isFinal(variableKey)) continue;
|
||||
|
||||
PromotionModel<Type> newInfo =
|
||||
info.discardPromotionsAndMarkNotUnassigned();
|
||||
PromotionModel<Type> newInfo = info
|
||||
.discardPromotionsAndMarkNotUnassigned();
|
||||
if (!identical(info, newInfo)) {
|
||||
result = result.updatePromotionInfo(helper, variableKey, newInfo);
|
||||
}
|
||||
@@ -2808,13 +2803,12 @@ class FlowModel<Type extends Object> {
|
||||
PromotionModel<Type>? promotionModel = left?.model;
|
||||
if (promotionModel == null) continue;
|
||||
PromotionModel<Type>? otherPromotionModel = right?.model;
|
||||
PromotionModel<Type> newPromotionModel =
|
||||
otherPromotionModel == null
|
||||
? promotionModel
|
||||
: PromotionModel.inheritTested(
|
||||
promotionModel,
|
||||
otherPromotionModel.tested,
|
||||
);
|
||||
PromotionModel<Type> newPromotionModel = otherPromotionModel == null
|
||||
? promotionModel
|
||||
: PromotionModel.inheritTested(
|
||||
promotionModel,
|
||||
otherPromotionModel.tested,
|
||||
);
|
||||
if (!identical(newPromotionModel, promotionModel)) {
|
||||
result = result.updatePromotionInfo(
|
||||
helper,
|
||||
@@ -2848,7 +2842,10 @@ class FlowModel<Type extends Object> {
|
||||
var (
|
||||
:PromotionInfo<Type>? ancestor,
|
||||
:List<FlowLinkDiffEntry<PromotionInfo<Type>>> entries,
|
||||
) = helper.reader.diff(promotionInfo, base.promotionInfo);
|
||||
) = helper.reader.diff(
|
||||
promotionInfo,
|
||||
base.promotionInfo,
|
||||
);
|
||||
// If `this` matches the ancestor, then there are no state changes that need
|
||||
// to be rewound and applied to `base`.
|
||||
if (ancestor == promotionInfo) {
|
||||
@@ -3229,17 +3226,17 @@ class FlowModel<Type extends Object> {
|
||||
identical(newPromotedTypes, info.promotedTypes)
|
||||
? this
|
||||
: updatePromotionInfo(
|
||||
helper,
|
||||
reference.promotionKey,
|
||||
new PromotionModel<Type>(
|
||||
promotedTypes: newPromotedTypes,
|
||||
tested: newTested,
|
||||
assigned: info.assigned,
|
||||
unassigned: info.unassigned,
|
||||
ssaNode: info.ssaNode,
|
||||
nonPromotionHistory: info.nonPromotionHistory,
|
||||
),
|
||||
);
|
||||
helper,
|
||||
reference.promotionKey,
|
||||
new PromotionModel<Type>(
|
||||
promotedTypes: newPromotedTypes,
|
||||
tested: newTested,
|
||||
assigned: info.assigned,
|
||||
unassigned: info.unassigned,
|
||||
ssaNode: info.ssaNode,
|
||||
nonPromotionHistory: info.nonPromotionHistory,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Forms a new state to reflect a control flow path that might have come from
|
||||
@@ -3292,7 +3289,10 @@ class FlowModel<Type extends Object> {
|
||||
var (
|
||||
:PromotionInfo<Type>? ancestor,
|
||||
:List<FlowLinkDiffEntry<PromotionInfo<Type>>> entries,
|
||||
) = helper.reader.diff(first.promotionInfo, second.promotionInfo);
|
||||
) = helper.reader.diff(
|
||||
first.promotionInfo,
|
||||
second.promotionInfo,
|
||||
);
|
||||
FlowModel<Type> newFlowModel = new FlowModel.withInfo(
|
||||
first.reachable,
|
||||
ancestor,
|
||||
@@ -3825,17 +3825,16 @@ class PromotionModel<Type extends Object> {
|
||||
|
||||
/// Returns a promotion model that is the same as this one, but with the
|
||||
/// variable definitely assigned.
|
||||
PromotionModel<Type> _setAssigned() =>
|
||||
assigned
|
||||
? this
|
||||
: new PromotionModel(
|
||||
promotedTypes: promotedTypes,
|
||||
tested: tested,
|
||||
assigned: true,
|
||||
unassigned: false,
|
||||
ssaNode: ssaNode,
|
||||
nonPromotionHistory: nonPromotionHistory,
|
||||
);
|
||||
PromotionModel<Type> _setAssigned() => assigned
|
||||
? this
|
||||
: new PromotionModel(
|
||||
promotedTypes: promotedTypes,
|
||||
tested: tested,
|
||||
assigned: true,
|
||||
unassigned: false,
|
||||
ssaNode: ssaNode,
|
||||
nonPromotionHistory: nonPromotionHistory,
|
||||
);
|
||||
|
||||
/// Determines whether a variable with the given [promotedTypes] should be
|
||||
/// promoted to [writtenType] based on types of interest. If it should,
|
||||
@@ -3855,8 +3854,9 @@ class PromotionModel<Type extends Object> {
|
||||
// Figure out if we have any promotion candidates (types that are a
|
||||
// supertype of writtenType and a proper subtype of the currently-promoted
|
||||
// type). If at any point we find an exact match, we take it immediately.
|
||||
Type currentlyPromotedType =
|
||||
promotedTypes.isNotEmpty ? promotedTypes.last : declaredType;
|
||||
Type currentlyPromotedType = promotedTypes.isNotEmpty
|
||||
? promotedTypes.last
|
||||
: declaredType;
|
||||
|
||||
List<Type>? result = null;
|
||||
List<Type>? candidates = null;
|
||||
@@ -4012,8 +4012,9 @@ class PromotionModel<Type extends Object> {
|
||||
bool newAssigned = first.assigned && second.assigned;
|
||||
bool newUnassigned = first.unassigned && second.unassigned;
|
||||
bool newWriteCaptured = first.writeCaptured || second.writeCaptured;
|
||||
List<Type> newTested =
|
||||
newWriteCaptured ? const [] : joinTested(first.tested, second.tested);
|
||||
List<Type> newTested = newWriteCaptured
|
||||
? const []
|
||||
: joinTested(first.tested, second.tested);
|
||||
SsaNode<Type>? newSsaNode = propertySsaNode;
|
||||
if (newSsaNode == null && !newWriteCaptured) {
|
||||
(newSsaNode, newFlowModel) = SsaNode._join(
|
||||
@@ -4170,10 +4171,9 @@ class PromotionModel<Type extends Object> {
|
||||
static List<Type> _addToPromotedTypes<Type extends Object>(
|
||||
List<Type> promotedTypes,
|
||||
Type promoted,
|
||||
) =>
|
||||
promotedTypes.isEmpty
|
||||
? [promoted]
|
||||
: (promotedTypes.toList()..add(promoted));
|
||||
) => promotedTypes.isEmpty
|
||||
? [promoted]
|
||||
: (promotedTypes.toList()..add(promoted));
|
||||
|
||||
static List<Type> _addTypeToUniqueList<Type extends Object>(
|
||||
List<Type> types,
|
||||
@@ -4934,11 +4934,10 @@ class _BranchTargetContext<Type extends Object> extends _FlowContext {
|
||||
_BranchTargetContext(this._checkpoint);
|
||||
|
||||
@override
|
||||
Map<String, Object?> get _debugFields =>
|
||||
super._debugFields
|
||||
..['breakModel'] = _breakModel
|
||||
..['continueModel'] = _continueModel
|
||||
..['checkpoint'] = _checkpoint;
|
||||
Map<String, Object?> get _debugFields => super._debugFields
|
||||
..['breakModel'] = _breakModel
|
||||
..['continueModel'] = _continueModel
|
||||
..['checkpoint'] = _checkpoint;
|
||||
|
||||
@override
|
||||
String get _debugType => '_BranchTargetContext';
|
||||
@@ -4966,10 +4965,9 @@ class _ConditionalContext<Type extends Object> extends _BranchContext<Type> {
|
||||
_ConditionalContext(super._branchModel);
|
||||
|
||||
@override
|
||||
Map<String, Object?> get _debugFields =>
|
||||
super._debugFields
|
||||
..['thenInfo'] = _thenInfo
|
||||
..['thenModel'] = _thenModel;
|
||||
Map<String, Object?> get _debugFields => super._debugFields
|
||||
..['thenInfo'] = _thenInfo
|
||||
..['thenModel'] = _thenModel;
|
||||
|
||||
@override
|
||||
String get _debugType => '_ConditionalContext';
|
||||
@@ -5190,8 +5188,10 @@ class _FlowAnalysisImpl<
|
||||
@override
|
||||
void assert_end() {
|
||||
_AssertContext<Type> context = _stack.removeLast() as _AssertContext<Type>;
|
||||
_current =
|
||||
_join(context._previous, context._conditionInfo!.ifTrue).unsplit();
|
||||
_current = _join(
|
||||
context._previous,
|
||||
context._conditionInfo!.ifTrue,
|
||||
).unsplit();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -5223,15 +5223,15 @@ class _FlowAnalysisImpl<
|
||||
expression,
|
||||
value
|
||||
? new ExpressionInfo(
|
||||
type: boolType,
|
||||
ifTrue: _current,
|
||||
ifFalse: unreachable,
|
||||
)
|
||||
type: boolType,
|
||||
ifTrue: _current,
|
||||
ifFalse: unreachable,
|
||||
)
|
||||
: new ExpressionInfo(
|
||||
type: boolType,
|
||||
ifTrue: unreachable,
|
||||
ifFalse: _current,
|
||||
),
|
||||
type: boolType,
|
||||
ifTrue: unreachable,
|
||||
ifFalse: _current,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5442,11 +5442,10 @@ class _FlowAnalysisImpl<
|
||||
void doStatement_end(Expression condition) {
|
||||
_BranchTargetContext<Type> context =
|
||||
_stack.removeLast() as _BranchTargetContext<Type>;
|
||||
_current =
|
||||
_join(
|
||||
_expressionEnd(condition, boolType).ifFalse,
|
||||
context._breakModel,
|
||||
).unsplit();
|
||||
_current = _join(
|
||||
_expressionEnd(condition, boolType).ifFalse,
|
||||
context._breakModel,
|
||||
).unsplit();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -5546,14 +5545,13 @@ class _FlowAnalysisImpl<
|
||||
|
||||
@override
|
||||
void for_bodyBegin(Statement? node, Expression? condition) {
|
||||
ExpressionInfo<Type> conditionInfo =
|
||||
condition == null
|
||||
? new ExpressionInfo(
|
||||
type: boolType,
|
||||
ifTrue: _current,
|
||||
ifFalse: _current.setUnreachable(),
|
||||
)
|
||||
: _expressionEnd(condition, boolType);
|
||||
ExpressionInfo<Type> conditionInfo = condition == null
|
||||
? new ExpressionInfo(
|
||||
type: boolType,
|
||||
ifTrue: _current,
|
||||
ifFalse: _current.setUnreachable(),
|
||||
)
|
||||
: _expressionEnd(condition, boolType);
|
||||
_WhileContext<Type> context = new _WhileContext<Type>(
|
||||
_current.reachable.parent!,
|
||||
conditionInfo,
|
||||
@@ -5582,11 +5580,10 @@ class _FlowAnalysisImpl<
|
||||
FlowModel<Type>? breakState = context._breakModel;
|
||||
FlowModel<Type> falseCondition = context._conditionInfo.ifFalse;
|
||||
|
||||
_current =
|
||||
_join(
|
||||
falseCondition,
|
||||
breakState,
|
||||
).inheritTested(this, _current).unsplit();
|
||||
_current = _join(
|
||||
falseCondition,
|
||||
breakState,
|
||||
).inheritTested(this, _current).unsplit();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -6343,14 +6340,12 @@ class _FlowAnalysisImpl<
|
||||
_current.promotionInfo
|
||||
?.get(this, scrutineeReference.promotionKey)
|
||||
?.ssaNode)) {
|
||||
ifTrue =
|
||||
ifTrue
|
||||
.tryPromoteForTypeCheck(this, scrutineeReference, knownType)
|
||||
.ifTrue;
|
||||
ifFalse =
|
||||
ifFalse
|
||||
.tryPromoteForTypeCheck(this, scrutineeReference, knownType)
|
||||
.ifFalse;
|
||||
ifTrue = ifTrue
|
||||
.tryPromoteForTypeCheck(this, scrutineeReference, knownType)
|
||||
.ifTrue;
|
||||
ifFalse = ifFalse
|
||||
.tryPromoteForTypeCheck(this, scrutineeReference, knownType)
|
||||
.ifFalse;
|
||||
}
|
||||
_current = ifTrue;
|
||||
if (cannotMatch) {
|
||||
@@ -6486,10 +6481,9 @@ class _FlowAnalysisImpl<
|
||||
}
|
||||
|
||||
@override
|
||||
SsaNode<Type>? ssaNodeForTesting(Variable variable) =>
|
||||
_current.promotionInfo
|
||||
?.get(this, promotionKeyStore.keyForVariable(variable))
|
||||
?.ssaNode;
|
||||
SsaNode<Type>? ssaNodeForTesting(Variable variable) => _current.promotionInfo
|
||||
?.get(this, promotionKeyStore.keyForVariable(variable))
|
||||
?.ssaNode;
|
||||
|
||||
@override
|
||||
bool switchStatement_afterCase() {
|
||||
@@ -6789,14 +6783,15 @@ class _FlowAnalysisImpl<
|
||||
promotionModel,
|
||||
);
|
||||
}
|
||||
_Reference<Type> expressionInfo = _variableReference(
|
||||
variableKey,
|
||||
unpromotedType,
|
||||
).restoreConditionVariableState(
|
||||
promotionModel.ssaNode?.conditionVariableState,
|
||||
this,
|
||||
_current,
|
||||
);
|
||||
_Reference<Type> expressionInfo =
|
||||
_variableReference(
|
||||
variableKey,
|
||||
unpromotedType,
|
||||
).restoreConditionVariableState(
|
||||
promotionModel.ssaNode?.conditionVariableState,
|
||||
this,
|
||||
_current,
|
||||
);
|
||||
_storeExpressionReference(expression, expressionInfo);
|
||||
_storeExpressionInfo(expression, expressionInfo);
|
||||
return promotionModel.promotedTypes.lastOrNull;
|
||||
@@ -7045,21 +7040,20 @@ class _FlowAnalysisImpl<
|
||||
// node can't be `null`.
|
||||
v1!;
|
||||
// - Otherwise, `p4 = rebasePromotedTypes(p1, p3)`.
|
||||
p4 =
|
||||
typeAnalyzerOptions.soundFlowAnalysisEnabled
|
||||
? PromotionModel.rebasePromotedTypes(
|
||||
basePromotions: p1,
|
||||
newPromotions: p3,
|
||||
helper: this,
|
||||
)
|
||||
:
|
||||
// (UNSPECIFIED: reproduce old buggy behavior prior to the fix for
|
||||
// https://github.com/dart-lang/language/issues/4382.)
|
||||
PromotionModel.rebasePromotedTypes(
|
||||
basePromotions: p3,
|
||||
newPromotions: p1,
|
||||
helper: this,
|
||||
);
|
||||
p4 = typeAnalyzerOptions.soundFlowAnalysisEnabled
|
||||
? PromotionModel.rebasePromotedTypes(
|
||||
basePromotions: p1,
|
||||
newPromotions: p3,
|
||||
helper: this,
|
||||
)
|
||||
:
|
||||
// (UNSPECIFIED: reproduce old buggy behavior prior to the fix for
|
||||
// https://github.com/dart-lang/language/issues/4382.)
|
||||
PromotionModel.rebasePromotedTypes(
|
||||
basePromotions: p3,
|
||||
newPromotions: p1,
|
||||
helper: this,
|
||||
);
|
||||
// (UNSPECIFIED: and the SSA node after the `try-finally` statement is the
|
||||
// SSA node after the `try` block.)
|
||||
v4 = v1;
|
||||
@@ -7261,8 +7255,8 @@ class _FlowAnalysisImpl<
|
||||
if (propertyMember != null) {
|
||||
PropertyNonPromotabilityReason? whyNotPromotable =
|
||||
reference.propertyName.startsWith('_')
|
||||
? operations.whyPropertyIsNotPromotable(propertyMember)
|
||||
: PropertyNonPromotabilityReason.isNotPrivate;
|
||||
? operations.whyPropertyIsNotPromotable(propertyMember)
|
||||
: PropertyNonPromotabilityReason.isNotPrivate;
|
||||
_PropertySsaNode<Type>? ssaNode =
|
||||
(reference.ssaNode as _PropertySsaNode<Type>).previousSsaNode;
|
||||
List<List<Type>>? allPreviouslyPromotedTypes;
|
||||
@@ -7284,21 +7278,20 @@ class _FlowAnalysisImpl<
|
||||
for (List<Type> previouslyPromotedTypes
|
||||
in allPreviouslyPromotedTypes!) {
|
||||
for (Type type in previouslyPromotedTypes) {
|
||||
result[type] =
|
||||
whyNotPromotable == null
|
||||
? new PropertyNotPromotedForNonInherentReason(
|
||||
reference.propertyName,
|
||||
propertyMember,
|
||||
fieldPromotionEnabled:
|
||||
typeAnalyzerOptions.fieldPromotionEnabled,
|
||||
)
|
||||
: new PropertyNotPromotedForInherentReason(
|
||||
reference.propertyName,
|
||||
propertyMember,
|
||||
whyNotPromotable,
|
||||
fieldPromotionEnabled:
|
||||
typeAnalyzerOptions.fieldPromotionEnabled,
|
||||
);
|
||||
result[type] = whyNotPromotable == null
|
||||
? new PropertyNotPromotedForNonInherentReason(
|
||||
reference.propertyName,
|
||||
propertyMember,
|
||||
fieldPromotionEnabled:
|
||||
typeAnalyzerOptions.fieldPromotionEnabled,
|
||||
)
|
||||
: new PropertyNotPromotedForInherentReason(
|
||||
reference.propertyName,
|
||||
propertyMember,
|
||||
whyNotPromotable,
|
||||
fieldPromotionEnabled:
|
||||
typeAnalyzerOptions.fieldPromotionEnabled,
|
||||
);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -7511,8 +7504,8 @@ class _FlowAnalysisImpl<
|
||||
SsaNode<Type> newSsaNode = new SsaNode<Type>(
|
||||
conditionVariableState:
|
||||
expressionInfo != null && expressionInfo.isNonTrivial
|
||||
? expressionInfo
|
||||
: null,
|
||||
? expressionInfo
|
||||
: null,
|
||||
);
|
||||
_current = _current.write(
|
||||
this,
|
||||
@@ -7524,14 +7517,13 @@ class _FlowAnalysisImpl<
|
||||
unpromotedType: unpromotedType,
|
||||
);
|
||||
if (isImplicitlyTyped && operations.isTypeParameterType(matchedType)) {
|
||||
_current =
|
||||
_current
|
||||
.tryPromoteForTypeCheck(
|
||||
this,
|
||||
_variableReference(promotionKey, unpromotedType),
|
||||
matchedType,
|
||||
)
|
||||
.ifTrue;
|
||||
_current = _current
|
||||
.tryPromoteForTypeCheck(
|
||||
this,
|
||||
_variableReference(promotionKey, unpromotedType),
|
||||
matchedType,
|
||||
)
|
||||
.ifTrue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7632,8 +7624,9 @@ class _FlowAnalysisImpl<
|
||||
if (typeClassification == TypeClassification.nonNullable) {
|
||||
return null;
|
||||
} else {
|
||||
FlowModel<Type>? ifNotNull =
|
||||
_current.tryMarkNonNullable(this, matchedValueReference).ifTrue;
|
||||
FlowModel<Type>? ifNotNull = _current
|
||||
.tryMarkNonNullable(this, matchedValueReference)
|
||||
.ifTrue;
|
||||
_Reference<Type>? scrutineeReference = _scrutineeReference;
|
||||
// If the scrutinee is a variable reference, and the variable hasn't
|
||||
// changed since the start of the matching operation, promote it too.
|
||||
@@ -7650,8 +7643,9 @@ class _FlowAnalysisImpl<
|
||||
_current.promotionInfo
|
||||
?.get(this, scrutineeReference.promotionKey)
|
||||
?.ssaNode)) {
|
||||
ifNotNull =
|
||||
ifNotNull.tryMarkNonNullable(this, scrutineeReference).ifTrue;
|
||||
ifNotNull = ifNotNull
|
||||
.tryMarkNonNullable(this, scrutineeReference)
|
||||
.ifTrue;
|
||||
}
|
||||
if (typeClassification == TypeClassification.nullOrEquivalent) {
|
||||
ifNotNull = ifNotNull.setUnreachable();
|
||||
@@ -7711,8 +7705,9 @@ class _FlowAnalysisImpl<
|
||||
previousScrutineeReference: _scrutineeReference,
|
||||
),
|
||||
);
|
||||
_Reference<Type>? scrutineeReference =
|
||||
scrutineeInfo is _Reference<Type> ? scrutineeInfo : null;
|
||||
_Reference<Type>? scrutineeReference = scrutineeInfo is _Reference<Type>
|
||||
? scrutineeInfo
|
||||
: null;
|
||||
_scrutineeReference = scrutineeReference;
|
||||
SsaNode<Type>? scrutineeSsaNode;
|
||||
if (allowScrutineePromotion && scrutineeReference != null) {
|
||||
@@ -7795,8 +7790,8 @@ class _FlowAnalysisImpl<
|
||||
SsaNode<Type> newSsaNode = new SsaNode<Type>(
|
||||
conditionVariableState:
|
||||
expressionInfo != null && expressionInfo.isNonTrivial
|
||||
? expressionInfo
|
||||
: null,
|
||||
? expressionInfo
|
||||
: null,
|
||||
);
|
||||
_current = _current.write(
|
||||
this,
|
||||
@@ -7987,10 +7982,9 @@ class _OrPatternContext<Type extends Object> extends _PatternContext<Type> {
|
||||
_OrPatternContext(super._matchedValueInfo, this._previousUnmatched);
|
||||
|
||||
@override
|
||||
Map<String, Object?> get _debugFields =>
|
||||
super._debugFields
|
||||
..['previousUnmatched'] = _previousUnmatched
|
||||
..['lhsMatched'] = _lhsMatched;
|
||||
Map<String, Object?> get _debugFields => super._debugFields
|
||||
..['previousUnmatched'] = _previousUnmatched
|
||||
..['lhsMatched'] = _lhsMatched;
|
||||
|
||||
@override
|
||||
String get _debugType => '_OrPatternContext';
|
||||
@@ -8248,10 +8242,9 @@ class _SwitchStatementContext<Type extends Object>
|
||||
) : _unmatched = _previous;
|
||||
|
||||
@override
|
||||
Map<String, Object?> get _debugFields =>
|
||||
super._debugFields
|
||||
..['matchedValueInfo'] = _matchedValueInfo
|
||||
..['unmatched'] = _unmatched;
|
||||
Map<String, Object?> get _debugFields => super._debugFields
|
||||
..['matchedValueInfo'] = _matchedValueInfo
|
||||
..['unmatched'] = _unmatched;
|
||||
|
||||
@override
|
||||
String get _debugType => '_SwitchStatementContext';
|
||||
@@ -8287,10 +8280,9 @@ class _TryContext<Type extends Object> extends _SimpleContext<Type> {
|
||||
_TryContext(super.previous);
|
||||
|
||||
@override
|
||||
Map<String, Object?> get _debugFields =>
|
||||
super._debugFields
|
||||
..['beforeCatch'] = _beforeCatch
|
||||
..['afterBodyAndCatches'] = '_afterBodyAndCatches';
|
||||
Map<String, Object?> get _debugFields => super._debugFields
|
||||
..['beforeCatch'] = _beforeCatch
|
||||
..['afterBodyAndCatches'] = '_afterBodyAndCatches';
|
||||
|
||||
@override
|
||||
String get _debugType => '_TryContext';
|
||||
@@ -8311,11 +8303,10 @@ class _TryFinallyContext<Type extends Object> extends _FlowContext {
|
||||
_TryFinallyContext(this._beforeTry);
|
||||
|
||||
@override
|
||||
Map<String, Object?> get _debugFields =>
|
||||
super._debugFields
|
||||
..['beforeTry'] = _beforeTry
|
||||
..['afterTry'] = _afterTry
|
||||
..['beforeFinally'] = _beforeFinally;
|
||||
Map<String, Object?> get _debugFields => super._debugFields
|
||||
..['beforeTry'] = _beforeTry
|
||||
..['afterTry'] = _afterTry
|
||||
..['beforeFinally'] = _beforeFinally;
|
||||
|
||||
@override
|
||||
String get _debugType => '_TryFinallyContext';
|
||||
|
||||
@@ -339,14 +339,14 @@ class DiagnosticMessageFromJson implements CfeDiagnosticMessage {
|
||||
decoded["plainTextFormatted"],
|
||||
);
|
||||
CfeSeverity severity = CfeSeverity.values[decoded["severity"] as int];
|
||||
Uri? uri =
|
||||
decoded["uri"] == null ? null : Uri.parse(decoded["uri"] as String);
|
||||
List<Uri>? involvedFiles =
|
||||
decoded["involvedFiles"] == null
|
||||
? null
|
||||
: _asListOfString(
|
||||
decoded["involvedFiles"],
|
||||
).map((e) => Uri.parse(e)).toList();
|
||||
Uri? uri = decoded["uri"] == null
|
||||
? null
|
||||
: Uri.parse(decoded["uri"] as String);
|
||||
List<Uri>? involvedFiles = decoded["involvedFiles"] == null
|
||||
? null
|
||||
: _asListOfString(
|
||||
decoded["involvedFiles"],
|
||||
).map((e) => Uri.parse(e)).toList();
|
||||
String codeName = decoded["codeName"] as String;
|
||||
|
||||
return new DiagnosticMessageFromJson(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -58,11 +58,11 @@ class MapEntryElement extends Element {
|
||||
return newKey == null && newValue == null
|
||||
? null
|
||||
: new MapEntryElement(
|
||||
newKey ?? key,
|
||||
newValue ?? value,
|
||||
isNullAwareKey: isNullAwareKey,
|
||||
isNullAwareValue: isNullAwareValue,
|
||||
);
|
||||
newKey ?? key,
|
||||
newValue ?? value,
|
||||
isNullAwareKey: isNullAwareKey,
|
||||
isNullAwareValue: isNullAwareValue,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,10 +103,10 @@ class IfElement extends Element {
|
||||
return newCondition == null && newThen == null && newOtherwise == null
|
||||
? null
|
||||
: new IfElement(
|
||||
newCondition ?? condition,
|
||||
newThen ?? then,
|
||||
newOtherwise ?? otherwise,
|
||||
);
|
||||
newCondition ?? condition,
|
||||
newThen ?? then,
|
||||
newOtherwise ?? otherwise,
|
||||
);
|
||||
} else {
|
||||
return newCondition == null && newThen == null
|
||||
? null
|
||||
|
||||
@@ -526,10 +526,9 @@ class Evaluator {
|
||||
}
|
||||
default:
|
||||
Element? then = _visitElement(element.then);
|
||||
Element? otherwise =
|
||||
element.otherwise != null
|
||||
? _visitElement(element.otherwise!)
|
||||
: null;
|
||||
Element? otherwise = element.otherwise != null
|
||||
? _visitElement(element.otherwise!)
|
||||
: null;
|
||||
if (then != null) {
|
||||
list.add(new IfElement(condition, then, otherwise));
|
||||
} else if (otherwise != null) {
|
||||
@@ -637,10 +636,9 @@ class Evaluator {
|
||||
}
|
||||
default:
|
||||
Element? then = _visitElement(element.then);
|
||||
Element? otherwise =
|
||||
element.otherwise != null
|
||||
? _visitElement(element.otherwise!)
|
||||
: null;
|
||||
Element? otherwise = element.otherwise != null
|
||||
? _visitElement(element.otherwise!)
|
||||
: null;
|
||||
if (then != null) {
|
||||
return new IfElement(condition, then, otherwise);
|
||||
} else if (otherwise != null) {
|
||||
|
||||
@@ -85,10 +85,10 @@ class ConstructorInvocation extends Expression {
|
||||
return newType == null && newArguments == null
|
||||
? null
|
||||
: new ConstructorInvocation(
|
||||
newType ?? type,
|
||||
constructor,
|
||||
newArguments ?? arguments,
|
||||
);
|
||||
newType ?? type,
|
||||
constructor,
|
||||
newArguments ?? arguments,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,10 +209,10 @@ class ImplicitInvocation extends Expression {
|
||||
newArguments == null
|
||||
? null
|
||||
: new ImplicitInvocation(
|
||||
newReceiver ?? receiver,
|
||||
newTypeArguments ?? typeArguments,
|
||||
newArguments ?? arguments,
|
||||
);
|
||||
newReceiver ?? receiver,
|
||||
newTypeArguments ?? typeArguments,
|
||||
newArguments ?? arguments,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,10 +235,10 @@ class StaticInvocation extends Expression {
|
||||
return newTypeArguments == null && newArguments == null
|
||||
? null
|
||||
: new StaticInvocation(
|
||||
function,
|
||||
newTypeArguments ?? typeArguments,
|
||||
newArguments ?? arguments,
|
||||
);
|
||||
function,
|
||||
newTypeArguments ?? typeArguments,
|
||||
newArguments ?? arguments,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,9 +260,9 @@ class Instantiation extends Expression {
|
||||
return newReceiver == null && newTypeArguments == null
|
||||
? null
|
||||
: new Instantiation(
|
||||
newReceiver ?? receiver,
|
||||
newTypeArguments ?? typeArguments,
|
||||
);
|
||||
newReceiver ?? receiver,
|
||||
newTypeArguments ?? typeArguments,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,11 +295,11 @@ class MethodInvocation extends Expression {
|
||||
newArguments == null
|
||||
? null
|
||||
: new MethodInvocation(
|
||||
newReceiver ?? receiver,
|
||||
name,
|
||||
newTypeArguments ?? typeArguments,
|
||||
newArguments ?? arguments,
|
||||
);
|
||||
newReceiver ?? receiver,
|
||||
name,
|
||||
newTypeArguments ?? typeArguments,
|
||||
newArguments ?? arguments,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,10 +389,10 @@ class ConditionalExpression extends Expression {
|
||||
return newCondition == null && newThen == null && newOtherwise == null
|
||||
? null
|
||||
: new ConditionalExpression(
|
||||
newCondition ?? condition,
|
||||
newThen ?? then,
|
||||
newOtherwise ?? otherwise,
|
||||
);
|
||||
newCondition ?? condition,
|
||||
newThen ?? then,
|
||||
newOtherwise ?? otherwise,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,9 +414,9 @@ class ListLiteral extends Expression {
|
||||
return newTypeArguments == null && newElements == null
|
||||
? null
|
||||
: new ListLiteral(
|
||||
newTypeArguments ?? typeArguments,
|
||||
newElements ?? elements,
|
||||
);
|
||||
newTypeArguments ?? typeArguments,
|
||||
newElements ?? elements,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,9 +438,9 @@ class SetOrMapLiteral extends Expression {
|
||||
return newTypeArguments == null && newElements == null
|
||||
? null
|
||||
: new SetOrMapLiteral(
|
||||
newTypeArguments ?? typeArguments,
|
||||
newElements ?? elements,
|
||||
);
|
||||
newTypeArguments ?? typeArguments,
|
||||
newElements ?? elements,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,10 +525,10 @@ class EqualityExpression extends Expression {
|
||||
return newLeft == null && newRight == null
|
||||
? null
|
||||
: new EqualityExpression(
|
||||
newLeft ?? left,
|
||||
newRight ?? right,
|
||||
isNotEquals: isNotEquals,
|
||||
);
|
||||
newLeft ?? left,
|
||||
newRight ?? right,
|
||||
isNotEquals: isNotEquals,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -620,10 +620,10 @@ class IsTest extends Expression {
|
||||
return newType == null && newExpression == null
|
||||
? null
|
||||
: new IsTest(
|
||||
newExpression ?? expression,
|
||||
newType ?? type,
|
||||
isNot: isNot,
|
||||
);
|
||||
newExpression ?? expression,
|
||||
newType ?? type,
|
||||
isNot: isNot,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,13 +44,13 @@ class FormalParameter {
|
||||
resolvedDefaultValue == null
|
||||
? null
|
||||
: new FormalParameter(
|
||||
resolvedMetadata ?? metadata,
|
||||
resolvedTypeAnnotation ?? typeAnnotation,
|
||||
name,
|
||||
resolvedDefaultValue ?? defaultValue,
|
||||
isNamed: isNamed,
|
||||
isRequired: isRequired,
|
||||
);
|
||||
resolvedMetadata ?? metadata,
|
||||
resolvedTypeAnnotation ?? typeAnnotation,
|
||||
name,
|
||||
resolvedDefaultValue ?? defaultValue,
|
||||
isNamed: isNamed,
|
||||
isRequired: isRequired,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -63,8 +63,9 @@ class AnnotationsListener extends StackListener {
|
||||
]),
|
||||
);
|
||||
List<Argument>? arguments = pop(_NullValues.Arguments) as List<Argument>?;
|
||||
IdentifierProto? identifier =
|
||||
periodBeforeName != null ? pop() as IdentifierProto : null;
|
||||
IdentifierProto? identifier = periodBeforeName != null
|
||||
? pop() as IdentifierProto
|
||||
: null;
|
||||
List<TypeAnnotation>? typeArguments =
|
||||
pop(_NullValues.TypeAnnotations) as List<TypeAnnotation>?;
|
||||
Proto proto = pop() as Proto;
|
||||
@@ -136,8 +137,9 @@ class AnnotationsListener extends StackListener {
|
||||
/* (qualified) name before type arguments */ _ValueKinds._Proto,
|
||||
]),
|
||||
);
|
||||
IdentifierProto? constructorName =
|
||||
periodBeforeName != null ? pop() as IdentifierProto : null;
|
||||
IdentifierProto? constructorName = periodBeforeName != null
|
||||
? pop() as IdentifierProto
|
||||
: null;
|
||||
List<TypeAnnotation>? typeArguments =
|
||||
pop(_NullValues.TypeAnnotations) as List<TypeAnnotation>?;
|
||||
Proto className = pop() as Proto;
|
||||
@@ -780,8 +782,9 @@ class AnnotationsListener extends StackListener {
|
||||
List<TypeAnnotation>? typeArguments =
|
||||
pop(_NullValues.TypeAnnotations) as List<TypeAnnotation>?;
|
||||
Proto type = pop() as Proto;
|
||||
TypeAnnotation typeAnnotation =
|
||||
type.instantiate(typeArguments).toTypeAnnotation();
|
||||
TypeAnnotation typeAnnotation = type
|
||||
.instantiate(typeArguments)
|
||||
.toTypeAnnotation();
|
||||
if (questionMark != null) {
|
||||
typeAnnotation = new NullableTypeAnnotation(typeAnnotation);
|
||||
}
|
||||
@@ -1201,9 +1204,9 @@ class AnnotationsListener extends StackListener {
|
||||
leftBracket,
|
||||
hasNamedFields
|
||||
? [
|
||||
_ValueKinds._RecordTypeEntries,
|
||||
...repeatedKind(_ValueKinds._RecordTypeEntry, count - 1),
|
||||
]
|
||||
_ValueKinds._RecordTypeEntries,
|
||||
...repeatedKind(_ValueKinds._RecordTypeEntry, count - 1),
|
||||
]
|
||||
: repeatedKind(_ValueKinds._RecordTypeEntry, count),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1052,12 +1052,12 @@ class ConstructorProto extends Proto {
|
||||
Proto invoke(List<Argument>? arguments) {
|
||||
return arguments != null
|
||||
? new ExpressionProto(
|
||||
new ConstructorInvocation(
|
||||
new NamedTypeAnnotation(type, typeArguments),
|
||||
reference,
|
||||
arguments,
|
||||
),
|
||||
)
|
||||
new ConstructorInvocation(
|
||||
new NamedTypeAnnotation(type, typeArguments),
|
||||
reference,
|
||||
arguments,
|
||||
),
|
||||
)
|
||||
: this;
|
||||
}
|
||||
|
||||
@@ -1141,8 +1141,8 @@ class FunctionProto extends Proto {
|
||||
Proto invoke(List<Argument>? arguments) {
|
||||
return arguments != null
|
||||
? new ExpressionProto(
|
||||
new StaticInvocation(reference, const [], arguments),
|
||||
)
|
||||
new StaticInvocation(reference, const [], arguments),
|
||||
)
|
||||
: this;
|
||||
}
|
||||
|
||||
@@ -1185,8 +1185,8 @@ class FunctionInstantiationProto extends Proto {
|
||||
Proto invoke(List<Argument>? arguments) {
|
||||
return arguments != null
|
||||
? new ExpressionProto(
|
||||
new StaticInvocation(reference, typeArguments, arguments),
|
||||
)
|
||||
new StaticInvocation(reference, typeArguments, arguments),
|
||||
)
|
||||
: this;
|
||||
}
|
||||
|
||||
@@ -1383,8 +1383,12 @@ class ExpressionInstantiationProto extends Proto {
|
||||
Proto invoke(List<Argument>? arguments) {
|
||||
return arguments != null
|
||||
? new ExpressionProto(
|
||||
new ImplicitInvocation(receiver.toExpression(), const [], arguments),
|
||||
)
|
||||
new ImplicitInvocation(
|
||||
receiver.toExpression(),
|
||||
const [],
|
||||
arguments,
|
||||
),
|
||||
)
|
||||
: this;
|
||||
}
|
||||
|
||||
@@ -1591,8 +1595,8 @@ class ExpressionProto extends Proto {
|
||||
Proto invoke(List<Argument>? arguments) {
|
||||
return arguments != null
|
||||
? new ExpressionProto(
|
||||
new ImplicitInvocation(expression, const [], arguments),
|
||||
)
|
||||
new ImplicitInvocation(expression, const [], arguments),
|
||||
)
|
||||
: this;
|
||||
}
|
||||
|
||||
@@ -1633,8 +1637,8 @@ class FunctionTypeParameterProto extends Proto {
|
||||
Proto invoke(List<Argument>? arguments) {
|
||||
return arguments != null
|
||||
? new ExpressionProto(
|
||||
new ImplicitInvocation(toExpression(), const [], arguments),
|
||||
)
|
||||
new ImplicitInvocation(toExpression(), const [], arguments),
|
||||
)
|
||||
: this;
|
||||
}
|
||||
|
||||
|
||||
@@ -181,10 +181,10 @@ class FunctionTypeAnnotation extends TypeAnnotation {
|
||||
resolvedTypeParameters == null
|
||||
? null
|
||||
: new FunctionTypeAnnotation(
|
||||
resolvedReturnType ?? returnType,
|
||||
resolvedTypeParameters ?? typeParameters,
|
||||
resolvedFormalParameters ?? formalParameters,
|
||||
);
|
||||
resolvedReturnType ?? returnType,
|
||||
resolvedTypeParameters ?? typeParameters,
|
||||
resolvedFormalParameters ?? formalParameters,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,9 +241,9 @@ class RecordTypeAnnotation extends TypeAnnotation {
|
||||
return resolvedPositional == null && resolvedNamed == null
|
||||
? null
|
||||
: new RecordTypeAnnotation(
|
||||
resolvedPositional ?? positional,
|
||||
resolvedNamed ?? named,
|
||||
);
|
||||
resolvedPositional ?? positional,
|
||||
resolvedNamed ?? named,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,10 +262,10 @@ class RecordTypeEntry {
|
||||
return resolvedMetadata == null && resolvedTypeAnnotation == null
|
||||
? null
|
||||
: new RecordTypeEntry(
|
||||
resolvedMetadata ?? metadata,
|
||||
resolvedTypeAnnotation ?? typeAnnotation,
|
||||
name,
|
||||
);
|
||||
resolvedMetadata ?? metadata,
|
||||
resolvedTypeAnnotation ?? typeAnnotation,
|
||||
name,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -2090,11 +2090,10 @@ class Parser {
|
||||
|
||||
if (isModifier(next)) {
|
||||
// Recovery
|
||||
ModifierContext context =
|
||||
new ModifierContext(this)
|
||||
..covariantToken = covariantToken
|
||||
..requiredToken = requiredToken
|
||||
..varFinalOrConst = varFinalOrConst;
|
||||
ModifierContext context = new ModifierContext(this)
|
||||
..covariantToken = covariantToken
|
||||
..requiredToken = requiredToken
|
||||
..varFinalOrConst = varFinalOrConst;
|
||||
|
||||
token = context.parseFormalParameterModifiers(
|
||||
token,
|
||||
@@ -3800,12 +3799,11 @@ class Parser {
|
||||
// If another `var`, `final`, or `const` then fall through
|
||||
// to parse that as part of the next top level declaration.
|
||||
} else {
|
||||
ModifierContext context =
|
||||
new ModifierContext(this)
|
||||
..externalToken = externalToken
|
||||
..augmentToken = augmentToken
|
||||
..lateToken = lateToken
|
||||
..varFinalOrConst = varFinalOrConst;
|
||||
ModifierContext context = new ModifierContext(this)
|
||||
..externalToken = externalToken
|
||||
..augmentToken = augmentToken
|
||||
..lateToken = lateToken
|
||||
..varFinalOrConst = varFinalOrConst;
|
||||
|
||||
token = context.parseTopLevelMemberModifiers(token);
|
||||
next = token.next!;
|
||||
@@ -4060,16 +4058,14 @@ class Parser {
|
||||
Token token = typeInfo.parseType(beforeType, this);
|
||||
assert(token.next == name || token.next!.isEof);
|
||||
|
||||
IdentifierContext context =
|
||||
kind == DeclarationKind.TopLevel
|
||||
? IdentifierContext.topLevelVariableDeclaration
|
||||
: IdentifierContext.fieldDeclaration;
|
||||
Token firstName =
|
||||
name = ensureIdentifierPotentiallyRecovered(
|
||||
token,
|
||||
context,
|
||||
/* isRecovered = */ nameIsRecovered,
|
||||
);
|
||||
IdentifierContext context = kind == DeclarationKind.TopLevel
|
||||
? IdentifierContext.topLevelVariableDeclaration
|
||||
: IdentifierContext.fieldDeclaration;
|
||||
Token firstName = name = ensureIdentifierPotentiallyRecovered(
|
||||
token,
|
||||
context,
|
||||
/* isRecovered = */ nameIsRecovered,
|
||||
);
|
||||
|
||||
// Check for covariant late final with initializer.
|
||||
if (covariantToken != null && lateToken != null) {
|
||||
@@ -4965,15 +4961,14 @@ class Parser {
|
||||
}
|
||||
}
|
||||
if (isModifier(next)) {
|
||||
ModifierContext context =
|
||||
new ModifierContext(this)
|
||||
..covariantToken = covariantToken
|
||||
..augmentToken = augmentToken
|
||||
..externalToken = externalToken
|
||||
..lateToken = lateToken
|
||||
..staticToken = staticToken
|
||||
..varFinalOrConst = varFinalOrConst
|
||||
..abstractToken = abstractToken;
|
||||
ModifierContext context = new ModifierContext(this)
|
||||
..covariantToken = covariantToken
|
||||
..augmentToken = augmentToken
|
||||
..externalToken = externalToken
|
||||
..lateToken = lateToken
|
||||
..staticToken = staticToken
|
||||
..varFinalOrConst = varFinalOrConst
|
||||
..abstractToken = abstractToken;
|
||||
|
||||
token = context.parseClassMemberModifiers(token);
|
||||
next = token.next!;
|
||||
@@ -5414,20 +5409,17 @@ class Parser {
|
||||
case DeclarationKind.Class:
|
||||
case DeclarationKind.Mixin:
|
||||
case DeclarationKind.Enum:
|
||||
memberKind =
|
||||
staticToken != null
|
||||
? MemberKind.StaticMethod
|
||||
: MemberKind.NonStaticMethod;
|
||||
memberKind = staticToken != null
|
||||
? MemberKind.StaticMethod
|
||||
: MemberKind.NonStaticMethod;
|
||||
case DeclarationKind.Extension:
|
||||
memberKind =
|
||||
staticToken != null
|
||||
? MemberKind.ExtensionStaticMethod
|
||||
: MemberKind.ExtensionNonStaticMethod;
|
||||
memberKind = staticToken != null
|
||||
? MemberKind.ExtensionStaticMethod
|
||||
: MemberKind.ExtensionNonStaticMethod;
|
||||
case DeclarationKind.ExtensionType:
|
||||
memberKind =
|
||||
staticToken != null
|
||||
? MemberKind.ExtensionTypeStaticMethod
|
||||
: MemberKind.ExtensionTypeNonStaticMethod;
|
||||
memberKind = staticToken != null
|
||||
? MemberKind.ExtensionTypeStaticMethod
|
||||
: MemberKind.ExtensionTypeNonStaticMethod;
|
||||
}
|
||||
|
||||
Token beforeParam = token;
|
||||
@@ -5648,11 +5640,10 @@ class Parser {
|
||||
|
||||
if (!isValidNonRecordTypeReference(token.next!)) {
|
||||
// Recovery
|
||||
ModifierContext context =
|
||||
new ModifierContext(this)
|
||||
..externalToken = externalToken
|
||||
..staticOrCovariant = staticOrCovariant
|
||||
..varFinalOrConst = varFinalOrConst;
|
||||
ModifierContext context = new ModifierContext(this)
|
||||
..externalToken = externalToken
|
||||
..staticOrCovariant = staticOrCovariant
|
||||
..varFinalOrConst = varFinalOrConst;
|
||||
|
||||
token = context.parseModifiersAfterFactory(token);
|
||||
|
||||
@@ -5859,11 +5850,10 @@ class Parser {
|
||||
) {
|
||||
Token token = beforeName.next!;
|
||||
listener.beginFunctionName(token);
|
||||
token =
|
||||
ensureIdentifier(
|
||||
beforeName,
|
||||
IdentifierContext.localFunctionDeclaration,
|
||||
).next!;
|
||||
token = ensureIdentifier(
|
||||
beforeName,
|
||||
IdentifierContext.localFunctionDeclaration,
|
||||
).next!;
|
||||
if (isFunctionExpression) {
|
||||
reportRecoverableError(
|
||||
beforeName.next!,
|
||||
@@ -6446,15 +6436,14 @@ class Parser {
|
||||
if (allowPatterns && looksLikeOuterPatternEquals(token)) {
|
||||
token = parsePatternAssignment(token);
|
||||
} else {
|
||||
token =
|
||||
token.next!.isA(Keyword.THROW)
|
||||
? parseThrowExpression(token, /* allowCascades = */ true)
|
||||
: parsePrecedenceExpression(
|
||||
token,
|
||||
ASSIGNMENT_PRECEDENCE,
|
||||
/* allowCascades = */ true,
|
||||
ConstantPatternContext.none,
|
||||
);
|
||||
token = token.next!.isA(Keyword.THROW)
|
||||
? parseThrowExpression(token, /* allowCascades = */ true)
|
||||
: parsePrecedenceExpression(
|
||||
token,
|
||||
ASSIGNMENT_PRECEDENCE,
|
||||
/* allowCascades = */ true,
|
||||
ConstantPatternContext.none,
|
||||
);
|
||||
}
|
||||
}
|
||||
expressionDepth--;
|
||||
@@ -6465,11 +6454,11 @@ class Parser {
|
||||
return token.next!.isA(Keyword.THROW)
|
||||
? parseThrowExpression(token, /* allowCascades = */ false)
|
||||
: parsePrecedenceExpression(
|
||||
token,
|
||||
ASSIGNMENT_PRECEDENCE,
|
||||
/* allowCascades = */ false,
|
||||
ConstantPatternContext.none,
|
||||
);
|
||||
token,
|
||||
ASSIGNMENT_PRECEDENCE,
|
||||
/* allowCascades = */ false,
|
||||
ConstantPatternContext.none,
|
||||
);
|
||||
}
|
||||
|
||||
bool canParseAsConditional(Token question) {
|
||||
@@ -6727,15 +6716,14 @@ class Parser {
|
||||
);
|
||||
operator = next;
|
||||
}
|
||||
token =
|
||||
next.next!.isA(Keyword.THROW)
|
||||
? parseThrowExpression(next, allowCascades)
|
||||
: parsePrecedenceExpression(
|
||||
next,
|
||||
level,
|
||||
allowCascades,
|
||||
ConstantPatternContext.none,
|
||||
);
|
||||
token = next.next!.isA(Keyword.THROW)
|
||||
? parseThrowExpression(next, allowCascades)
|
||||
: parsePrecedenceExpression(
|
||||
next,
|
||||
level,
|
||||
allowCascades,
|
||||
ConstantPatternContext.none,
|
||||
);
|
||||
listener.handleAssignmentExpression(operator, token);
|
||||
} else if (tokenLevel == POSTFIX_PRECEDENCE) {
|
||||
if ((identical(type, TokenType.PLUS_PLUS)) ||
|
||||
@@ -7305,7 +7293,7 @@ class Parser {
|
||||
while (true) {
|
||||
bool potentialNullAware =
|
||||
(next.isA(TokenType.QUESTION) &&
|
||||
next.next!.isA(TokenType.OPEN_SQUARE_BRACKET));
|
||||
next.next!.isA(TokenType.OPEN_SQUARE_BRACKET));
|
||||
if (potentialNullAware && !checkedNullAware) {
|
||||
// While it's a potential null aware index it hasn't been checked.
|
||||
// It might be a conditional expression.
|
||||
@@ -7663,11 +7651,10 @@ class Parser {
|
||||
next.isA(TokenType.COLON)) {
|
||||
// Record with named expression.
|
||||
wasRecord = true;
|
||||
token =
|
||||
ensureIdentifier(
|
||||
token,
|
||||
IdentifierContext.namedRecordFieldReference,
|
||||
).next!;
|
||||
token = ensureIdentifier(
|
||||
token,
|
||||
IdentifierContext.namedRecordFieldReference,
|
||||
).next!;
|
||||
colon = token;
|
||||
wasValidRecord = true;
|
||||
}
|
||||
@@ -7884,10 +7871,9 @@ class Parser {
|
||||
// This looks like the start of an expression.
|
||||
// Report an error, insert the comma, and continue parsing.
|
||||
SyntheticToken comma = new SyntheticToken(TokenType.COMMA, next.offset);
|
||||
codes.Message message =
|
||||
ifCount > 0
|
||||
? codes.codeExpectedElseOrComma
|
||||
: codes.codeExpectedButGot.withArguments(',');
|
||||
codes.Message message = ifCount > 0
|
||||
? codes.codeExpectedElseOrComma
|
||||
: codes.codeExpectedButGot.withArguments(',');
|
||||
next = rewriteAndRecover(token, message, comma);
|
||||
}
|
||||
token = next;
|
||||
@@ -7969,8 +7955,9 @@ class Parser {
|
||||
Token? nullAwareValueToken;
|
||||
Token next = token.next!;
|
||||
if (next.isA(TokenType.QUESTION_PERIOD)) {
|
||||
token =
|
||||
nullAwareValueToken = _splitFollowingQuestionPeriod(token);
|
||||
token = nullAwareValueToken = _splitFollowingQuestionPeriod(
|
||||
token,
|
||||
);
|
||||
} else if (next.isA(TokenType.QUESTION)) {
|
||||
token = nullAwareValueToken = next;
|
||||
}
|
||||
@@ -8024,10 +8011,9 @@ class Parser {
|
||||
TokenType.COMMA,
|
||||
next.offset,
|
||||
);
|
||||
codes.Message message =
|
||||
ifCount > 0
|
||||
? codes.codeExpectedElseOrComma
|
||||
: codes.codeExpectedButGot.withArguments(',');
|
||||
codes.Message message = ifCount > 0
|
||||
? codes.codeExpectedElseOrComma
|
||||
: codes.codeExpectedButGot.withArguments(',');
|
||||
token = rewriteAndRecover(token, message, comma);
|
||||
} else {
|
||||
reportRecoverableError(
|
||||
@@ -8884,11 +8870,10 @@ class Parser {
|
||||
Token? colon = null;
|
||||
if (next.next!.isA(TokenType.COLON) || /* recovery */
|
||||
next.isA(TokenType.COLON)) {
|
||||
token =
|
||||
ensureIdentifier(
|
||||
token,
|
||||
IdentifierContext.namedArgumentReference,
|
||||
).next!;
|
||||
token = ensureIdentifier(
|
||||
token,
|
||||
IdentifierContext.namedArgumentReference,
|
||||
).next!;
|
||||
colon = token;
|
||||
}
|
||||
bool expressionHandled = false;
|
||||
@@ -9200,10 +9185,9 @@ class Parser {
|
||||
|
||||
if (isModifier(next)) {
|
||||
// Recovery
|
||||
ModifierContext context =
|
||||
new ModifierContext(this)
|
||||
..lateToken = lateToken
|
||||
..varFinalOrConst = varFinalOrConst;
|
||||
ModifierContext context = new ModifierContext(this)
|
||||
..lateToken = lateToken
|
||||
..varFinalOrConst = varFinalOrConst;
|
||||
|
||||
token = context.parseVariableDeclarationModifiers(token);
|
||||
next = token.next!;
|
||||
@@ -9345,8 +9329,9 @@ class Parser {
|
||||
UndoableTokenStreamRewriter undoableTokenStreamRewriter =
|
||||
new UndoableTokenStreamRewriter();
|
||||
cachedRewriter = undoableTokenStreamRewriter;
|
||||
Token afterExpression =
|
||||
parseExpressionWithoutCascade(afterIdentifier).next!;
|
||||
Token afterExpression = parseExpressionWithoutCascade(
|
||||
afterIdentifier,
|
||||
).next!;
|
||||
// Undo all changes and reset.
|
||||
undoableTokenStreamRewriter.undo();
|
||||
listener = originalListener;
|
||||
@@ -9601,11 +9586,10 @@ class Parser {
|
||||
token = rewriter.insertSyntheticToken(token, TokenType.SEMICOLON);
|
||||
}
|
||||
|
||||
openParen.endGroup =
|
||||
token = rewriter.insertToken(
|
||||
token,
|
||||
new SyntheticToken(TokenType.CLOSE_PAREN, leftParenthesis.offset),
|
||||
);
|
||||
openParen.endGroup = token = rewriter.insertToken(
|
||||
token,
|
||||
new SyntheticToken(TokenType.CLOSE_PAREN, leftParenthesis.offset),
|
||||
);
|
||||
|
||||
token = rewriter.insertSyntheticIdentifier(token);
|
||||
rewriter.insertSyntheticToken(token, TokenType.SEMICOLON);
|
||||
@@ -10054,10 +10038,9 @@ class Parser {
|
||||
),
|
||||
);
|
||||
}
|
||||
token =
|
||||
allowCascades
|
||||
? parseExpression(throwToken)
|
||||
: parseExpressionWithoutCascade(throwToken);
|
||||
token = allowCascades
|
||||
? parseExpression(throwToken)
|
||||
: parseExpressionWithoutCascade(throwToken);
|
||||
listener.handleThrowExpression(throwToken, token);
|
||||
return token;
|
||||
}
|
||||
@@ -11560,11 +11543,10 @@ class Parser {
|
||||
// `((:a, :b), :c, :d)` (and similar) is fine.
|
||||
// Record with named expression.
|
||||
wasRecord = true;
|
||||
token =
|
||||
ensureIdentifier(
|
||||
token,
|
||||
IdentifierContext.namedRecordFieldReference,
|
||||
).next!;
|
||||
token = ensureIdentifier(
|
||||
token,
|
||||
IdentifierContext.namedRecordFieldReference,
|
||||
).next!;
|
||||
colon = token;
|
||||
wasValidRecord = true;
|
||||
}
|
||||
@@ -11631,11 +11613,10 @@ class Parser {
|
||||
// This is different from `parseParenthesizedPatternOrRecordPattern`
|
||||
// because this isn't valid because of the missing name:
|
||||
// `var Point((:x, :y), :z) = Point((x: 1, y: 2), 3);`
|
||||
token =
|
||||
ensureIdentifier(
|
||||
token,
|
||||
IdentifierContext.namedArgumentReference,
|
||||
).next!;
|
||||
token = ensureIdentifier(
|
||||
token,
|
||||
IdentifierContext.namedArgumentReference,
|
||||
).next!;
|
||||
colon = token;
|
||||
}
|
||||
token = parsePattern(token, patternContext);
|
||||
|
||||
@@ -36,11 +36,12 @@ mainEntryPoint(List<String> arguments) async {
|
||||
for (String argument in arguments) {
|
||||
if (argument.startsWith("@")) {
|
||||
Uri uri = Uri.base.resolve(argument.substring(/* start = */ 1));
|
||||
await for (String file in new File.fromUri(uri)
|
||||
.openRead()
|
||||
.cast<List<int>>()
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())) {
|
||||
await for (String file
|
||||
in new File.fromUri(uri)
|
||||
.openRead()
|
||||
.cast<List<int>>()
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())) {
|
||||
outLine(uri.resolve(file));
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -180,27 +180,25 @@ String unescape(
|
||||
switch (quote) {
|
||||
case Quote.Single:
|
||||
case Quote.Double:
|
||||
result =
|
||||
!string.contains("\\")
|
||||
? string
|
||||
: unescapeCodeUnits(
|
||||
string.codeUnits,
|
||||
/* isRaw = */ false,
|
||||
location,
|
||||
listener,
|
||||
);
|
||||
result = !string.contains("\\")
|
||||
? string
|
||||
: unescapeCodeUnits(
|
||||
string.codeUnits,
|
||||
/* isRaw = */ false,
|
||||
location,
|
||||
listener,
|
||||
);
|
||||
break;
|
||||
case Quote.MultiLineSingle:
|
||||
case Quote.MultiLineDouble:
|
||||
result =
|
||||
!string.contains("\\") && !string.contains("\r")
|
||||
? string
|
||||
: unescapeCodeUnits(
|
||||
string.codeUnits,
|
||||
/* isRaw = */ false,
|
||||
location,
|
||||
listener,
|
||||
);
|
||||
result = !string.contains("\\") && !string.contains("\r")
|
||||
? string
|
||||
: unescapeCodeUnits(
|
||||
string.codeUnits,
|
||||
/* isRaw = */ false,
|
||||
location,
|
||||
listener,
|
||||
);
|
||||
break;
|
||||
case Quote.RawSingle:
|
||||
case Quote.RawDouble:
|
||||
@@ -208,15 +206,14 @@ String unescape(
|
||||
break;
|
||||
case Quote.RawMultiLineSingle:
|
||||
case Quote.RawMultiLineDouble:
|
||||
result =
|
||||
!string.contains("\r")
|
||||
? string
|
||||
: unescapeCodeUnits(
|
||||
string.codeUnits,
|
||||
/* isRaw = */ true,
|
||||
location,
|
||||
listener,
|
||||
);
|
||||
result = !string.contains("\r")
|
||||
? string
|
||||
: unescapeCodeUnits(
|
||||
string.codeUnits,
|
||||
/* isRaw = */ true,
|
||||
location,
|
||||
listener,
|
||||
);
|
||||
break;
|
||||
}
|
||||
return considerCanonicalizeString(result);
|
||||
|
||||
@@ -38,8 +38,10 @@ abstract class TokenStreamRewriter {
|
||||
|
||||
Token next = token.next!;
|
||||
int offset = next.charOffset;
|
||||
BeginToken leftParen =
|
||||
next = new SyntheticBeginToken(TokenType.OPEN_PAREN, offset);
|
||||
BeginToken leftParen = next = new SyntheticBeginToken(
|
||||
TokenType.OPEN_PAREN,
|
||||
offset,
|
||||
);
|
||||
if (includeIdentifier) {
|
||||
next = _setNext(
|
||||
next,
|
||||
|
||||
@@ -579,15 +579,15 @@ class ComplexTypeInfo implements TypeInfo {
|
||||
return beforeQuestionMark == null
|
||||
? this
|
||||
: new ComplexTypeInfo._nonNullable(
|
||||
start,
|
||||
typeArguments,
|
||||
beforeQuestionMark,
|
||||
typeVariableStarters,
|
||||
gftHasReturnType,
|
||||
isRecordType,
|
||||
gftReturnTypeHasRecordType,
|
||||
recovered,
|
||||
);
|
||||
start,
|
||||
typeArguments,
|
||||
beforeQuestionMark,
|
||||
typeVariableStarters,
|
||||
gftHasReturnType,
|
||||
isRecordType,
|
||||
gftReturnTypeHasRecordType,
|
||||
recovered,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -1677,10 +1677,9 @@ class ComplexTypeParamOrArgInfo extends TypeParamOrArgInfo {
|
||||
// but ensure that parser events are ignored by replacing the listener.
|
||||
final Listener originalListener = parser.listener;
|
||||
parser.listener = new ForwardingListener();
|
||||
token =
|
||||
isArguments
|
||||
? invalidTypeVar.parseArguments(token, parser)
|
||||
: invalidTypeVar.parseVariables(token, parser);
|
||||
token = isArguments
|
||||
? invalidTypeVar.parseArguments(token, parser)
|
||||
: invalidTypeVar.parseVariables(token, parser);
|
||||
next = token.next!;
|
||||
parser.listener = originalListener;
|
||||
|
||||
|
||||
@@ -1516,8 +1516,9 @@ abstract class AbstractScanner implements Scanner {
|
||||
advance();
|
||||
return tokenizeFractionPart(nextnext, start, hasSeparators);
|
||||
} else {
|
||||
TokenType tokenType =
|
||||
hasSeparators ? TokenType.INT_WITH_SEPARATORS : TokenType.INT;
|
||||
TokenType tokenType = hasSeparators
|
||||
? TokenType.INT_WITH_SEPARATORS
|
||||
: TokenType.INT;
|
||||
appendSubstringToken(tokenType, start, /* asciiOnly = */ true);
|
||||
return next;
|
||||
}
|
||||
@@ -1532,8 +1533,9 @@ abstract class AbstractScanner implements Scanner {
|
||||
),
|
||||
);
|
||||
}
|
||||
TokenType tokenType =
|
||||
hasSeparators ? TokenType.INT_WITH_SEPARATORS : TokenType.INT;
|
||||
TokenType tokenType = hasSeparators
|
||||
? TokenType.INT_WITH_SEPARATORS
|
||||
: TokenType.INT;
|
||||
appendSubstringToken(tokenType, start, /* asciiOnly = */ true);
|
||||
return next;
|
||||
}
|
||||
@@ -1598,10 +1600,9 @@ abstract class AbstractScanner implements Scanner {
|
||||
),
|
||||
);
|
||||
}
|
||||
TokenType tokenType =
|
||||
hasSeparators
|
||||
? TokenType.HEXADECIMAL_WITH_SEPARATORS
|
||||
: TokenType.HEXADECIMAL;
|
||||
TokenType tokenType = hasSeparators
|
||||
? TokenType.HEXADECIMAL_WITH_SEPARATORS
|
||||
: TokenType.HEXADECIMAL;
|
||||
appendSubstringToken(tokenType, start, /* asciiOnly = */ true);
|
||||
return next;
|
||||
}
|
||||
@@ -1744,8 +1745,9 @@ abstract class AbstractScanner implements Scanner {
|
||||
}
|
||||
next = advance();
|
||||
}
|
||||
TokenType tokenType =
|
||||
hasSeparators ? TokenType.DOUBLE_WITH_SEPARATORS : TokenType.DOUBLE;
|
||||
TokenType tokenType = hasSeparators
|
||||
? TokenType.DOUBLE_WITH_SEPARATORS
|
||||
: TokenType.DOUBLE;
|
||||
appendSubstringToken(tokenType, start, /* asciiOnly = */ true);
|
||||
return next;
|
||||
}
|
||||
|
||||
@@ -72,8 +72,8 @@ ScannerResult scan(
|
||||
// If there was a single missing `}` and the scanner can identify a good
|
||||
// candidate for better recovery, create a new scanner and instruct it to
|
||||
// do that recovery.
|
||||
int? offsetForCurlyBracketRecoveryStart =
|
||||
scanner.getOffsetForCurlyBracketRecoveryStart();
|
||||
int? offsetForCurlyBracketRecoveryStart = scanner
|
||||
.getOffsetForCurlyBracketRecoveryStart();
|
||||
if (offsetForCurlyBracketRecoveryStart != null) {
|
||||
scanner = new Utf8BytesScanner(
|
||||
bytes,
|
||||
@@ -108,8 +108,8 @@ ScannerResult scanString(
|
||||
// If there was a single missing `}` and the scanner can identify a good
|
||||
// candidate for better recovery, create a new scanner and instruct it to
|
||||
// do that recovery.
|
||||
int? offsetForCurlyBracketRecoveryStart =
|
||||
scanner.getOffsetForCurlyBracketRecoveryStart();
|
||||
int? offsetForCurlyBracketRecoveryStart = scanner
|
||||
.getOffsetForCurlyBracketRecoveryStart();
|
||||
if (offsetForCurlyBracketRecoveryStart != null) {
|
||||
scanner = new StringScanner(
|
||||
source,
|
||||
|
||||
@@ -172,12 +172,11 @@ class StringScanner extends AbstractScanner {
|
||||
bool asciiOnly,
|
||||
String syntheticChars,
|
||||
) {
|
||||
String value =
|
||||
syntheticChars.length == 0
|
||||
? canonicalizeSubString(_string, start, scanOffset)
|
||||
: canonicalizeString(
|
||||
_string.substring(start, scanOffset) + syntheticChars,
|
||||
);
|
||||
String value = syntheticChars.length == 0
|
||||
? canonicalizeSubString(_string, start, scanOffset)
|
||||
: canonicalizeString(
|
||||
_string.substring(start, scanOffset) + syntheticChars,
|
||||
);
|
||||
return new SyntheticStringToken(
|
||||
type,
|
||||
value,
|
||||
|
||||
@@ -66,10 +66,9 @@ class StringTokenImpl extends SimpleToken implements StringToken {
|
||||
}) : super(type, charOffset, precedingComments) {
|
||||
int length = end - start;
|
||||
if (!allowLazy || length <= LAZY_THRESHOLD) {
|
||||
valueOrLazySubstring =
|
||||
canonicalize
|
||||
? canonicalizeSubString(data, start, end)
|
||||
: data.substring(start, end);
|
||||
valueOrLazySubstring = canonicalize
|
||||
? canonicalizeSubString(data, start, end)
|
||||
: data.substring(start, end);
|
||||
} else {
|
||||
valueOrLazySubstring = new _LazySubstring(
|
||||
data,
|
||||
|
||||
@@ -510,13 +510,11 @@ class Utf8BytesScanner extends AbstractScanner {
|
||||
bool asciiOnly,
|
||||
String syntheticChars,
|
||||
) {
|
||||
String value =
|
||||
syntheticChars.length == 0
|
||||
? canonicalizeUtf8SubString(_bytes, start, byteOffset, asciiOnly)
|
||||
: canonicalizeString(
|
||||
decodeString(_bytes, start, byteOffset, asciiOnly) +
|
||||
syntheticChars,
|
||||
);
|
||||
String value = syntheticChars.length == 0
|
||||
? canonicalizeUtf8SubString(_bytes, start, byteOffset, asciiOnly)
|
||||
: canonicalizeString(
|
||||
decodeString(_bytes, start, byteOffset, asciiOnly) + syntheticChars,
|
||||
);
|
||||
return new SyntheticStringToken(
|
||||
type,
|
||||
value,
|
||||
|
||||
@@ -263,23 +263,23 @@ class AnnotatedCode {
|
||||
|
||||
String toText() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
List<Annotation> list =
|
||||
annotations.toList()..sort((a, b) {
|
||||
int result = a.offset.compareTo(b.offset);
|
||||
if (result == 0) {
|
||||
if (a.index != null && b.index != null) {
|
||||
result = a.index!.compareTo(b.index!);
|
||||
} else if (a.index != null) {
|
||||
result = -1;
|
||||
} else if (b.index != null) {
|
||||
result = 1;
|
||||
}
|
||||
List<Annotation> list = annotations.toList()
|
||||
..sort((a, b) {
|
||||
int result = a.offset.compareTo(b.offset);
|
||||
if (result == 0) {
|
||||
if (a.index != null && b.index != null) {
|
||||
result = a.index!.compareTo(b.index!);
|
||||
} else if (a.index != null) {
|
||||
result = -1;
|
||||
} else if (b.index != null) {
|
||||
result = 1;
|
||||
}
|
||||
if (result == 0) {
|
||||
result = annotations.indexOf(a).compareTo(annotations.indexOf(b));
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
if (result == 0) {
|
||||
result = annotations.indexOf(a).compareTo(annotations.indexOf(b));
|
||||
}
|
||||
return result;
|
||||
});
|
||||
int offset = 0;
|
||||
for (Annotation annotation in list) {
|
||||
sb.write(sourceCode.substring(offset, annotation.offset));
|
||||
|
||||
@@ -50,8 +50,8 @@ Map<Uri, List<Annotation>> computeAnnotationsPerUri<T>(
|
||||
dataMap.forEach((Id id, ActualData<T> data) {
|
||||
Map<Id, Map<String, ActualData<T>>> actualDataPerId =
|
||||
actualDataPerUri[uri] ??= {};
|
||||
Map<String, ActualData<T>> actualDataPerMarker =
|
||||
actualDataPerId[id] ??= {};
|
||||
Map<String, ActualData<T>> actualDataPerMarker = actualDataPerId[id] ??=
|
||||
{};
|
||||
actualDataPerMarker[marker] = data;
|
||||
});
|
||||
});
|
||||
@@ -164,10 +164,9 @@ List<Annotation> _computeAnnotations<T>(
|
||||
);
|
||||
}
|
||||
|
||||
Set<Id> idSet =
|
||||
{}
|
||||
..addAll(idValuePerId.keys)
|
||||
..addAll(actualDataPerId.keys);
|
||||
Set<Id> idSet = {}
|
||||
..addAll(idValuePerId.keys)
|
||||
..addAll(actualDataPerId.keys);
|
||||
List<Annotation> result = <Annotation>[];
|
||||
for (Id id in idSet) {
|
||||
Map<String, IdValue> idValuePerMarker = idValuePerId[id] ?? {};
|
||||
@@ -203,10 +202,9 @@ List<Annotation> _computeAnnotations<T>(
|
||||
actualAnnotation = createAnnotationFromData(actualData, null);
|
||||
}
|
||||
}
|
||||
Annotation? annotation =
|
||||
createDiff != null
|
||||
? createDiff(expectedAnnotation, actualAnnotation)
|
||||
: actualAnnotation;
|
||||
Annotation? annotation = createDiff != null
|
||||
? createDiff(expectedAnnotation, actualAnnotation)
|
||||
: actualAnnotation;
|
||||
if (annotation != null) {
|
||||
newAnnotationsPerMarker[marker] = annotation;
|
||||
}
|
||||
|
||||
@@ -270,9 +270,10 @@ TestData computeTestData(
|
||||
} else if (testFile is Directory) {
|
||||
testName = testFileUri.pathSegments[testFileUri.pathSegments.length - 2];
|
||||
additionalFiles = new Map<String, File>();
|
||||
for (FileSystemEntity entry in testFile
|
||||
.listSync(recursive: true)
|
||||
.where((entity) => !entity.path.endsWith('~'))) {
|
||||
for (FileSystemEntity entry
|
||||
in testFile
|
||||
.listSync(recursive: true)
|
||||
.where((entity) => !entity.path.endsWith('~'))) {
|
||||
if (entry is! File) continue;
|
||||
if (entry.uri.pathSegments.last == "main.dart") {
|
||||
mainTestFile = entry;
|
||||
@@ -572,9 +573,9 @@ Future<TestResult<T>> checkCode<T>(
|
||||
succinct
|
||||
? 'EXTRA $modeName DATA for ${id.descriptor}'
|
||||
: 'EXTRA $modeName DATA for ${id.descriptor}:\n '
|
||||
'object : ${actualData.objectText}\n '
|
||||
'actual : ${colorizeActual(actualValueText)}\n '
|
||||
'Data was expected for these ids: ${expectedMap.keys}',
|
||||
'object : ${actualData.objectText}\n '
|
||||
'actual : ${colorizeActual(actualValueText)}\n '
|
||||
'Data was expected for these ids: ${expectedMap.keys}',
|
||||
succinct: succinct,
|
||||
);
|
||||
if (filterActualData == null || filterActualData(null, actualData)) {
|
||||
@@ -595,10 +596,10 @@ Future<TestResult<T>> checkCode<T>(
|
||||
succinct
|
||||
? 'UNEXPECTED $modeName DATA for ${id.descriptor}'
|
||||
: 'UNEXPECTED $modeName DATA for ${id.descriptor}:\n '
|
||||
'detail : ${colorizeMessage(unexpectedMessage)}\n '
|
||||
'object : ${actualData.objectText}\n '
|
||||
'expected: ${colorizeExpected('$expected')}\n '
|
||||
'actual : ${colorizeActual(actualValueText)}',
|
||||
'detail : ${colorizeMessage(unexpectedMessage)}\n '
|
||||
'object : ${actualData.objectText}\n '
|
||||
'expected: ${colorizeExpected('$expected')}\n '
|
||||
'actual : ${colorizeActual(actualValueText)}',
|
||||
succinct: succinct,
|
||||
);
|
||||
if (filterActualData == null ||
|
||||
@@ -943,16 +944,15 @@ Future<void> runTests<T>(
|
||||
|
||||
String relativeDir = dataDir.uri.path.replaceAll(Uri.base.path, '');
|
||||
print('Data dir: ${relativeDir}');
|
||||
List<FileSystemEntity> entities =
|
||||
dataDir
|
||||
.listSync()
|
||||
.where(
|
||||
(entity) =>
|
||||
!entity.path.endsWith('~') &&
|
||||
!entity.path.endsWith('marker.options') &&
|
||||
!entity.path.endsWith('.expect'),
|
||||
)
|
||||
.toList();
|
||||
List<FileSystemEntity> entities = dataDir
|
||||
.listSync()
|
||||
.where(
|
||||
(entity) =>
|
||||
!entity.path.endsWith('~') &&
|
||||
!entity.path.endsWith('marker.options') &&
|
||||
!entity.path.endsWith('.expect'),
|
||||
)
|
||||
.toList();
|
||||
if (shards > 1) {
|
||||
entities.sort((a, b) => getTestName(a).compareTo(getTestName(b)));
|
||||
int start = entities.length * shardIndex ~/ shards;
|
||||
@@ -1045,8 +1045,8 @@ Future<void> runTests<T>(
|
||||
// invalid uris.
|
||||
return;
|
||||
}
|
||||
Map<Id, ActualData<T>> actualDataPerId =
|
||||
actualDataPerUri[uri] ??= {};
|
||||
Map<Id, ActualData<T>> actualDataPerId = actualDataPerUri[uri] ??=
|
||||
{};
|
||||
actualDataPerId.addAll(actualData);
|
||||
}
|
||||
|
||||
|
||||
@@ -371,10 +371,9 @@ abstract class SharedInferenceLogWriterImpl
|
||||
List<String> nodeSetDescriptions = [
|
||||
for (Object? node in state.nodeSet) describe(node),
|
||||
];
|
||||
String nodeSetDescription =
|
||||
nodeSetDescriptions.length == 1
|
||||
? nodeSetDescriptions[0]
|
||||
: nodeSetDescriptions.join(', ');
|
||||
String nodeSetDescription = nodeSetDescriptions.length == 1
|
||||
? nodeSetDescriptions[0]
|
||||
: nodeSetDescriptions.join(', ');
|
||||
fail(
|
||||
'${describeMethod()}: expected containing node to be '
|
||||
'${describe(expectedNode)}, actual is $nodeSetDescription',
|
||||
@@ -790,8 +789,9 @@ abstract class SharedInferenceLogWriterImpl
|
||||
expectedNode: expression,
|
||||
expectedKind: StateKind.expression,
|
||||
);
|
||||
String query =
|
||||
target != null ? '${describe(target)}.$methodName' : methodName;
|
||||
String query = target != null
|
||||
? '${describe(target)}.$methodName'
|
||||
: methodName;
|
||||
addEvent(new Event(message: 'LOOKUP $query FINDS $type'));
|
||||
}
|
||||
|
||||
|
||||
@@ -213,14 +213,14 @@ class MatchContext<
|
||||
/// [TypeAnalyzerErrors.refutablePatternInIrrefutableContext].
|
||||
MatchContext<Node, Expression, Pattern, Type, Variable> makeRefutable() =>
|
||||
irrefutableContext == null
|
||||
? this
|
||||
: new MatchContext(
|
||||
isFinal: isFinal,
|
||||
switchScrutinee: switchScrutinee,
|
||||
assignedVariables: assignedVariables,
|
||||
componentVariables: componentVariables,
|
||||
patternVariablePromotionKeys: patternVariablePromotionKeys,
|
||||
);
|
||||
? this
|
||||
: new MatchContext(
|
||||
isFinal: isFinal,
|
||||
switchScrutinee: switchScrutinee,
|
||||
assignedVariables: assignedVariables,
|
||||
componentVariables: componentVariables,
|
||||
patternVariablePromotionKeys: patternVariablePromotionKeys,
|
||||
);
|
||||
|
||||
/// Returns a modified version of `this`, with a new value of
|
||||
/// [patternVariablePromotionKeys].
|
||||
|
||||
@@ -557,15 +557,14 @@ mixin TypeAnalyzer<
|
||||
SharedTypeView promotedValueType = flow.getMatchedValueType();
|
||||
bool isImplicitlyTyped = declaredType == null;
|
||||
// TODO(paulberry): are we handling _isFinal correctly?
|
||||
int promotionKey =
|
||||
context.patternVariablePromotionKeys[variableName] = flow
|
||||
.declaredVariablePattern(
|
||||
matchedType: promotedValueType,
|
||||
staticType: staticType,
|
||||
isFinal: context.isFinal || operations.isVariableFinal(variable),
|
||||
isLate: false,
|
||||
isImplicitlyTyped: isImplicitlyTyped,
|
||||
);
|
||||
int promotionKey = context.patternVariablePromotionKeys[variableName] = flow
|
||||
.declaredVariablePattern(
|
||||
matchedType: promotedValueType,
|
||||
staticType: staticType,
|
||||
isFinal: context.isFinal || operations.isVariableFinal(variable),
|
||||
isLate: false,
|
||||
isImplicitlyTyped: isImplicitlyTyped,
|
||||
);
|
||||
setVariableType(variable, staticType);
|
||||
(context.componentVariables[variableName] ??= []).add(variable);
|
||||
flow.assignMatchedPatternVariable(variable, promotionKey);
|
||||
@@ -857,8 +856,9 @@ mixin TypeAnalyzer<
|
||||
type: operations.doubleType,
|
||||
typeSchema: schema,
|
||||
);
|
||||
SharedTypeView type =
|
||||
convertToDouble ? operations.doubleType : operations.intType;
|
||||
SharedTypeView type = convertToDouble
|
||||
? operations.doubleType
|
||||
: operations.intType;
|
||||
return new IntTypeAnalysisResult(
|
||||
type: type,
|
||||
convertedToDouble: convertToDouble,
|
||||
@@ -1538,10 +1538,9 @@ mixin TypeAnalyzer<
|
||||
}) {
|
||||
// Stack: ()
|
||||
SharedTypeSchemaView patternTypeSchema = dispatchPatternSchema(pattern);
|
||||
SharedTypeSchemaView expressionTypeSchema =
|
||||
hasAwait
|
||||
? operations.streamTypeSchema(patternTypeSchema)
|
||||
: operations.iterableTypeSchema(patternTypeSchema);
|
||||
SharedTypeSchemaView expressionTypeSchema = hasAwait
|
||||
? operations.streamTypeSchema(patternTypeSchema)
|
||||
: operations.iterableTypeSchema(patternTypeSchema);
|
||||
SharedTypeView expressionType = analyzeExpression(
|
||||
expression,
|
||||
expressionTypeSchema,
|
||||
@@ -1549,10 +1548,9 @@ mixin TypeAnalyzer<
|
||||
// Stack: (Expression)
|
||||
|
||||
Error? patternForInExpressionIsNotIterableError;
|
||||
SharedTypeView? elementType =
|
||||
hasAwait
|
||||
? operations.matchStreamType(expressionType)
|
||||
: operations.matchIterableType(expressionType);
|
||||
SharedTypeView? elementType = hasAwait
|
||||
? operations.matchStreamType(expressionType)
|
||||
: operations.matchIterableType(expressionType);
|
||||
if (elementType == null) {
|
||||
if (expressionType is SharedDynamicType) {
|
||||
elementType = operations.dynamicType;
|
||||
@@ -2185,8 +2183,8 @@ mixin TypeAnalyzer<
|
||||
isExhaustive = true;
|
||||
requiresExhaustivenessValidation = false;
|
||||
} else if (typeAnalyzerOptions.patternsEnabled) {
|
||||
requiresExhaustivenessValidation =
|
||||
isExhaustive = operations.isAlwaysExhaustiveType(scrutineeType);
|
||||
requiresExhaustivenessValidation = isExhaustive = operations
|
||||
.isAlwaysExhaustiveType(scrutineeType);
|
||||
} else {
|
||||
isExhaustive = isLegacySwitchExhaustive(node, scrutineeType);
|
||||
requiresExhaustivenessValidation = false;
|
||||
@@ -2723,9 +2721,8 @@ mixin TypeAnalyzer<
|
||||
location: location,
|
||||
inconsistency:
|
||||
typeIfConsistent != null && isFinalIfConsistent != null
|
||||
? JoinedPatternVariableInconsistency.none
|
||||
: JoinedPatternVariableInconsistency
|
||||
.differentFinalityOrType,
|
||||
? JoinedPatternVariableInconsistency.none
|
||||
: JoinedPatternVariableInconsistency.differentFinalityOrType,
|
||||
isFinal: isFinalIfConsistent ?? false,
|
||||
type: typeIfConsistent ?? operations.errorType,
|
||||
);
|
||||
|
||||
@@ -1351,8 +1351,8 @@ mixin TypeAnalyzerOperationsMixin<
|
||||
!isBoundOmitted(typeParameterToInfer)) {
|
||||
MergedTypeConstraint constraintFromBound = mergeInConstraintsFromBound(
|
||||
typeParameterToInfer: typeParameterToInfer,
|
||||
typeParametersToInfer:
|
||||
typeParametersToInfer.cast<SharedTypeParameterView>(),
|
||||
typeParametersToInfer: typeParametersToInfer
|
||||
.cast<SharedTypeParameterView>(),
|
||||
lower: constraint.lower.unwrapTypeSchemaView(),
|
||||
inferencePhaseConstraints: constraints,
|
||||
dataForTesting: dataForTesting,
|
||||
@@ -1439,8 +1439,8 @@ mixin TypeAnalyzerOperationsMixin<
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
MergedTypeConstraint constraintFromBound = mergeInConstraintsFromBound(
|
||||
typeParameterToInfer: typeParameterToInfer,
|
||||
typeParametersToInfer:
|
||||
typeParametersToInfer.cast<SharedTypeParameterView>(),
|
||||
typeParametersToInfer: typeParametersToInfer
|
||||
.cast<SharedTypeParameterView>(),
|
||||
lower: constraint.lower.unwrapTypeSchemaView(),
|
||||
inferencePhaseConstraints: constraints,
|
||||
dataForTesting: dataForTesting,
|
||||
|
||||
@@ -186,12 +186,11 @@ abstract class VariableBinder<Node extends Object, Variable extends Object> {
|
||||
result[entry.key] = joinPatternVariables(
|
||||
key: key,
|
||||
components: variables,
|
||||
inconsistency:
|
||||
sharedVariable.allCases
|
||||
? JoinedPatternVariableInconsistency.none
|
||||
: sharedScope.hasLabel
|
||||
? JoinedPatternVariableInconsistency.sharedCaseHasLabel
|
||||
: JoinedPatternVariableInconsistency.sharedCaseAbsent,
|
||||
inconsistency: sharedVariable.allCases
|
||||
? JoinedPatternVariableInconsistency.none
|
||||
: sharedScope.hasLabel
|
||||
? JoinedPatternVariableInconsistency.sharedCaseHasLabel
|
||||
: JoinedPatternVariableInconsistency.sharedCaseAbsent,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,8 +303,9 @@ class LibrariesSpecification {
|
||||
Uri uri = checkAndResolve(data['uri']);
|
||||
List<Uri> patches;
|
||||
if (data['patches'] is List) {
|
||||
patches =
|
||||
data['patches'].map<Uri>((s) => specUri.resolve(s)).toList();
|
||||
patches = data['patches']
|
||||
.map<Uri>((s) => specUri.resolve(s))
|
||||
.toList();
|
||||
} else if (data['patches'] is String) {
|
||||
patches = [checkAndResolve(data['patches'])];
|
||||
} else if (data['patches'] == null) {
|
||||
|
||||
@@ -6,7 +6,7 @@ description: Logic that is shared between the front_end and analyzer packages.
|
||||
repository: https://github.com/dart-lang/sdk/tree/main/pkg/_fe_analyzer_shared
|
||||
|
||||
environment:
|
||||
sdk: ^3.7.0
|
||||
sdk: ^3.9.0
|
||||
|
||||
resolution: workspace
|
||||
|
||||
|
||||
@@ -35,8 +35,10 @@ void testDir(String dataDirPath) {
|
||||
);
|
||||
String relativeDir = dataDir.uri.path.replaceAll(Uri.base.path, '');
|
||||
print('Data dir: ${relativeDir}');
|
||||
List<FileSystemEntity> entities =
|
||||
dataDir.listSync().where((entity) => !entity.path.endsWith('~')).toList();
|
||||
List<FileSystemEntity> entities = dataDir
|
||||
.listSync()
|
||||
.where((entity) => !entity.path.endsWith('~'))
|
||||
.toList();
|
||||
for (FileSystemEntity entity in entities) {
|
||||
print('----------------------------------------------------------------');
|
||||
|
||||
|
||||
@@ -18,12 +18,12 @@ int test1(Object obj) {
|
||||
}
|
||||
|
||||
int test2(Object obj) =>
|
||||
/*
|
||||
/*
|
||||
error=non-exhaustive:Object(),
|
||||
fields={isEven:-},
|
||||
type=Object
|
||||
*/
|
||||
switch (obj) {
|
||||
int(isEven: true) as int /*space=int(isEven: true)|Null*/ => 1,
|
||||
int _ /*space=int*/ => 2,
|
||||
};
|
||||
switch (obj) {
|
||||
int(isEven: true) as int /*space=int(isEven: true)|Null*/ => 1,
|
||||
int _ /*space=int*/ => 2,
|
||||
};
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
int nonExhaustive1<T extends int?>(T value) =>
|
||||
/*
|
||||
/*
|
||||
checkingOrder={int?,int,Null},
|
||||
error=non-exhaustive:null,
|
||||
subtypes={int,Null},
|
||||
type=int?
|
||||
*/
|
||||
switch (value) {
|
||||
int() /*space=int*/ => value,
|
||||
};
|
||||
switch (value) {
|
||||
int() /*space=int*/ => value,
|
||||
};
|
||||
|
||||
int nonExhaustive2<T extends int?>(T? value) => /*
|
||||
checkingOrder={int?,int,Null},
|
||||
|
||||
@@ -20,17 +20,15 @@ doubleNesting(int a, int b, int c) {
|
||||
// Note: for a closure, "assigned" and "captured" are restricted to
|
||||
// variables declared in enclosing contexts, so d, e, and f are not
|
||||
// included.
|
||||
var fn1 = /*declared={d, e, fn2}, assigned={b, c}, captured={c}*/ (
|
||||
int d,
|
||||
int e,
|
||||
) {
|
||||
b = 0;
|
||||
d = 0;
|
||||
// Similarly, f is not included in "assigned" here.
|
||||
var fn2 = /*declared={f}, assigned={c, e}*/ (int f) {
|
||||
c = 0;
|
||||
e = 0;
|
||||
f = 0;
|
||||
};
|
||||
};
|
||||
var fn1 = /*declared={d, e, fn2}, assigned={b, c}, captured={c}*/
|
||||
(int d, int e) {
|
||||
b = 0;
|
||||
d = 0;
|
||||
// Similarly, f is not included in "assigned" here.
|
||||
var fn2 = /*declared={f}, assigned={c, e}*/ (int f) {
|
||||
c = 0;
|
||||
e = 0;
|
||||
f = 0;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -595,10 +595,9 @@ main() {
|
||||
group('Final assertions:', () {
|
||||
bool assertionsEnabled = false;
|
||||
assert(assertionsEnabled = true);
|
||||
var asserts =
|
||||
assertionsEnabled
|
||||
? throwsA(TypeMatcher<AssertionError>())
|
||||
: returnsNormally;
|
||||
var asserts = assertionsEnabled
|
||||
? throwsA(TypeMatcher<AssertionError>())
|
||||
: returnsNormally;
|
||||
|
||||
test('finish may not be called twice', () {
|
||||
var assignedVariables = AssignedVariablesForTesting<_Node, _Variable>();
|
||||
|
||||
@@ -3409,8 +3409,8 @@ main() {
|
||||
expect(reachableSplitUnsplit.overallReachable, true);
|
||||
expect(reachableSplitUnsplit.locallyReachable, true);
|
||||
var reachableSplitUnreachable = reachableSplit.setUnreachable();
|
||||
var reachableSplitUnreachableUnsplit =
|
||||
reachableSplitUnreachable.unsplit();
|
||||
var reachableSplitUnreachableUnsplit = reachableSplitUnreachable
|
||||
.unsplit();
|
||||
expect(reachableSplitUnreachableUnsplit.parent, same(base.parent));
|
||||
expect(reachableSplitUnreachableUnsplit.overallReachable, false);
|
||||
expect(reachableSplitUnreachableUnsplit.locallyReachable, false);
|
||||
@@ -3419,8 +3419,8 @@ main() {
|
||||
var unreachableSplitUnsplit = unreachableSplit.unsplit();
|
||||
expect(unreachableSplitUnsplit, same(unreachable));
|
||||
var unreachableSplitUnreachable = unreachableSplit.setUnreachable();
|
||||
var unreachableSplitUnreachableUnsplit =
|
||||
unreachableSplitUnreachable.unsplit();
|
||||
var unreachableSplitUnreachableUnsplit = unreachableSplitUnreachable
|
||||
.unsplit();
|
||||
expect(unreachableSplitUnreachableUnsplit, same(unreachable));
|
||||
});
|
||||
|
||||
@@ -3637,37 +3637,33 @@ main() {
|
||||
});
|
||||
|
||||
test('promoted -> unchanged (same)', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(
|
||||
Reachability.initial,
|
||||
)._tryPromoteForTypeCheck(h, objectQVar, 'int').ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(
|
||||
Reachability.initial,
|
||||
)._tryPromoteForTypeCheck(h, objectQVar, 'int').ifTrue;
|
||||
var s2 = s1._tryPromoteForTypeCheck(h, objectQVar, 'int').ifTrue;
|
||||
expect(s2, same(s1));
|
||||
});
|
||||
|
||||
test('promoted -> unchanged (supertype)', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(
|
||||
Reachability.initial,
|
||||
)._tryPromoteForTypeCheck(h, objectQVar, 'int').ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(
|
||||
Reachability.initial,
|
||||
)._tryPromoteForTypeCheck(h, objectQVar, 'int').ifTrue;
|
||||
var s2 = s1._tryPromoteForTypeCheck(h, objectQVar, 'Object').ifTrue;
|
||||
expect(s2, same(s1));
|
||||
});
|
||||
|
||||
test('promoted -> unchanged (unrelated)', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(
|
||||
Reachability.initial,
|
||||
)._tryPromoteForTypeCheck(h, objectQVar, 'int').ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(
|
||||
Reachability.initial,
|
||||
)._tryPromoteForTypeCheck(h, objectQVar, 'int').ifTrue;
|
||||
var s2 = s1._tryPromoteForTypeCheck(h, objectQVar, 'String').ifTrue;
|
||||
expect(s2, same(s1));
|
||||
});
|
||||
|
||||
test('promoted -> subtype', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(
|
||||
Reachability.initial,
|
||||
)._tryPromoteForTypeCheck(h, objectQVar, 'int?').ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(
|
||||
Reachability.initial,
|
||||
)._tryPromoteForTypeCheck(h, objectQVar, 'int?').ifTrue;
|
||||
var s2 = s1._tryPromoteForTypeCheck(h, objectQVar, 'int').ifTrue;
|
||||
expect(s2.reachable.overallReachable, true);
|
||||
expect(s2.promotionInfo.unwrap(h), {
|
||||
@@ -3753,11 +3749,10 @@ main() {
|
||||
});
|
||||
|
||||
test('un-promotes fully', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int')
|
||||
.ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int')
|
||||
.ifTrue;
|
||||
expect(
|
||||
s1.promotionInfo.unwrap(h),
|
||||
contains(h.promotionKeyStore.keyForVariable(objectQVar)),
|
||||
@@ -3781,13 +3776,12 @@ main() {
|
||||
});
|
||||
|
||||
test('un-promotes partially, when no exact match', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num?')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int')
|
||||
.ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num?')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int')
|
||||
.ifTrue;
|
||||
expect(s1.promotionInfo.unwrap(h), {
|
||||
h.promotionKeyStore.keyForVariable(objectQVar): _matchVariableModel(
|
||||
chain: ['num?', 'int'],
|
||||
@@ -3815,15 +3809,14 @@ main() {
|
||||
});
|
||||
|
||||
test('un-promotes partially, when exact match', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num?')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int')
|
||||
.ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num?')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int')
|
||||
.ifTrue;
|
||||
expect(s1.promotionInfo.unwrap(h), {
|
||||
h.promotionKeyStore.keyForVariable(objectQVar): _matchVariableModel(
|
||||
chain: ['num?', 'num', 'int'],
|
||||
@@ -3851,13 +3844,12 @@ main() {
|
||||
});
|
||||
|
||||
test('leaves promoted, when exact match', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num?')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num')
|
||||
.ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num?')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num')
|
||||
.ifTrue;
|
||||
expect(s1.promotionInfo.unwrap(h), {
|
||||
h.promotionKeyStore.keyForVariable(objectQVar): _matchVariableModel(
|
||||
chain: ['num?', 'num'],
|
||||
@@ -3886,13 +3878,12 @@ main() {
|
||||
});
|
||||
|
||||
test('leaves promoted, when writing a subtype', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num?')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num')
|
||||
.ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num?')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num')
|
||||
.ifTrue;
|
||||
expect(s1.promotionInfo.unwrap(h), {
|
||||
h.promotionKeyStore.keyForVariable(objectQVar): _matchVariableModel(
|
||||
chain: ['num?', 'num'],
|
||||
@@ -3984,11 +3975,10 @@ main() {
|
||||
});
|
||||
|
||||
test('when promoted', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int?')
|
||||
.ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int?')
|
||||
.ifTrue;
|
||||
expect(s1.promotionInfo.unwrap(h), {
|
||||
h.promotionKeyStore.keyForVariable(objectQVar): _matchVariableModel(
|
||||
chain: ['int?'],
|
||||
@@ -4011,11 +4001,10 @@ main() {
|
||||
});
|
||||
|
||||
test('when not promoted', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int?')
|
||||
.ifFalse;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int?')
|
||||
.ifFalse;
|
||||
expect(s1.promotionInfo.unwrap(h), {
|
||||
h.promotionKeyStore.keyForVariable(objectQVar): _matchVariableModel(
|
||||
chain: ['Object'],
|
||||
@@ -4039,11 +4028,10 @@ main() {
|
||||
});
|
||||
|
||||
test('Promotes to type of interest when not previously promoted', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num?')
|
||||
.ifFalse;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num?')
|
||||
.ifFalse;
|
||||
expect(s1.promotionInfo.unwrap(h), {
|
||||
h.promotionKeyStore.keyForVariable(objectQVar): _matchVariableModel(
|
||||
chain: ['Object'],
|
||||
@@ -4066,13 +4054,12 @@ main() {
|
||||
});
|
||||
|
||||
test('Promotes to type of interest when previously promoted', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num?')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int?')
|
||||
.ifFalse;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'num?')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int?')
|
||||
.ifFalse;
|
||||
expect(s1.promotionInfo.unwrap(h), {
|
||||
h.promotionKeyStore.keyForVariable(objectQVar): _matchVariableModel(
|
||||
chain: ['num?', 'num'],
|
||||
@@ -4111,13 +4098,12 @@ main() {
|
||||
test('; first', () {
|
||||
var x = Var('x')..type = Type('Object?');
|
||||
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, x, true)
|
||||
._tryPromoteForTypeCheck(h, x, 'B?')
|
||||
.ifFalse
|
||||
._tryPromoteForTypeCheck(h, x, 'A?')
|
||||
.ifFalse;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, x, true)
|
||||
._tryPromoteForTypeCheck(h, x, 'B?')
|
||||
.ifFalse
|
||||
._tryPromoteForTypeCheck(h, x, 'A?')
|
||||
.ifFalse;
|
||||
expect(s1.promotionInfo.unwrap(h), {
|
||||
h.promotionKeyStore.keyForVariable(x): _matchVariableModel(
|
||||
chain: ['Object'],
|
||||
@@ -4143,13 +4129,12 @@ main() {
|
||||
test('; second', () {
|
||||
var x = Var('x')..type = Type('Object?');
|
||||
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, x, true)
|
||||
._tryPromoteForTypeCheck(h, x, 'A?')
|
||||
.ifFalse
|
||||
._tryPromoteForTypeCheck(h, x, 'B?')
|
||||
.ifFalse;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, x, true)
|
||||
._tryPromoteForTypeCheck(h, x, 'A?')
|
||||
.ifFalse
|
||||
._tryPromoteForTypeCheck(h, x, 'B?')
|
||||
.ifFalse;
|
||||
expect(s1.promotionInfo.unwrap(h), {
|
||||
h.promotionKeyStore.keyForVariable(x): _matchVariableModel(
|
||||
chain: ['Object'],
|
||||
@@ -4175,13 +4160,12 @@ main() {
|
||||
test('; nullable and non-nullable', () {
|
||||
var x = Var('x')..type = Type('Object?');
|
||||
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, x, true)
|
||||
._tryPromoteForTypeCheck(h, x, 'A')
|
||||
.ifFalse
|
||||
._tryPromoteForTypeCheck(h, x, 'A?')
|
||||
.ifFalse;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, x, true)
|
||||
._tryPromoteForTypeCheck(h, x, 'A')
|
||||
.ifFalse
|
||||
._tryPromoteForTypeCheck(h, x, 'A?')
|
||||
.ifFalse;
|
||||
expect(s1.promotionInfo.unwrap(h), {
|
||||
h.promotionKeyStore.keyForVariable(x): _matchVariableModel(
|
||||
chain: ['Object'],
|
||||
@@ -4207,13 +4191,12 @@ main() {
|
||||
|
||||
group('; ambiguous', () {
|
||||
test('; no promotion', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'List<Object?>')
|
||||
.ifFalse
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'List<dynamic>')
|
||||
.ifFalse;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'List<Object?>')
|
||||
.ifFalse
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'List<dynamic>')
|
||||
.ifFalse;
|
||||
expect(s1.promotionInfo.unwrap(h), {
|
||||
h.promotionKeyStore.keyForVariable(
|
||||
objectQVar,
|
||||
@@ -4242,13 +4225,12 @@ main() {
|
||||
});
|
||||
|
||||
test('exact match', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'List<Object?>')
|
||||
.ifFalse
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'List<dynamic>')
|
||||
.ifFalse;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, objectQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'List<Object?>')
|
||||
.ifFalse
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'List<dynamic>')
|
||||
.ifFalse;
|
||||
expect(s1.promotionInfo.unwrap(h), {
|
||||
h.promotionKeyStore.keyForVariable(objectQVar): _matchVariableModel(
|
||||
ofInterest: ['List<Object?>', 'List<dynamic>'],
|
||||
@@ -4278,13 +4260,12 @@ main() {
|
||||
test('when promoted via test', () {
|
||||
var x = Var('x')..type = Type('Object?');
|
||||
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, x, true)
|
||||
._tryPromoteForTypeCheck(h, x, 'num?')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, x, 'int?')
|
||||
.ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, x, true)
|
||||
._tryPromoteForTypeCheck(h, x, 'num?')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, x, 'int?')
|
||||
.ifTrue;
|
||||
expect(s1.promotionInfo.unwrap(h), {
|
||||
h.promotionKeyStore.keyForVariable(x): _matchVariableModel(
|
||||
chain: ['num?', 'int?'],
|
||||
@@ -4358,19 +4339,17 @@ main() {
|
||||
});
|
||||
|
||||
test('promoted -> unchanged', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(
|
||||
Reachability.initial,
|
||||
)._tryPromoteForTypeCheck(h, objectQVar, 'int').ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(
|
||||
Reachability.initial,
|
||||
)._tryPromoteForTypeCheck(h, objectQVar, 'int').ifTrue;
|
||||
var s2 = s1._tryMarkNonNullable(h, objectQVar).ifTrue;
|
||||
expect(s2, same(s1));
|
||||
});
|
||||
|
||||
test('promoted -> re-promoted', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(
|
||||
Reachability.initial,
|
||||
)._tryPromoteForTypeCheck(h, objectQVar, 'int?').ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(
|
||||
Reachability.initial,
|
||||
)._tryPromoteForTypeCheck(h, objectQVar, 'int?').ifTrue;
|
||||
var s2 = s1._tryMarkNonNullable(h, objectQVar).ifTrue;
|
||||
expect(s2.reachable.overallReachable, true);
|
||||
expect(s2.promotionInfo.unwrap(h), {
|
||||
@@ -4394,11 +4373,10 @@ main() {
|
||||
|
||||
group('conservativeJoin', () {
|
||||
test('unchanged', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, intQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int')
|
||||
.ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._declare(h, intQVar, true)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int')
|
||||
.ifTrue;
|
||||
var s2 = s1._conservativeJoin(h, [intQVar], []);
|
||||
expect(s2, isNot(same(s1)));
|
||||
expect(s2.reachable, same(s1.reachable));
|
||||
@@ -4415,12 +4393,11 @@ main() {
|
||||
});
|
||||
|
||||
test('written', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, intQVar, 'int')
|
||||
.ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, intQVar, 'int')
|
||||
.ifTrue;
|
||||
var s2 = s1._conservativeJoin(h, [intQVar], []);
|
||||
expect(s2.reachable.overallReachable, true);
|
||||
expect(s2.promotionInfo.unwrap(h), {
|
||||
@@ -4436,12 +4413,11 @@ main() {
|
||||
});
|
||||
|
||||
test('write captured', () {
|
||||
var s1 =
|
||||
FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, intQVar, 'int')
|
||||
.ifTrue;
|
||||
var s1 = FlowModel<SharedTypeView>(Reachability.initial)
|
||||
._tryPromoteForTypeCheck(h, objectQVar, 'int')
|
||||
.ifTrue
|
||||
._tryPromoteForTypeCheck(h, intQVar, 'int')
|
||||
.ifTrue;
|
||||
var s2 = s1._conservativeJoin(h, [], [intQVar]);
|
||||
expect(s2.reachable.overallReachable, true);
|
||||
expect(s2.promotionInfo.unwrap(h), {
|
||||
@@ -4596,10 +4572,9 @@ main() {
|
||||
if (thisType != null) {
|
||||
s1 = s1._tryPromoteForTypeCheck(h, x, thisType).ifTrue;
|
||||
}
|
||||
var s2 =
|
||||
otherType == null
|
||||
? s0
|
||||
: s0._tryPromoteForTypeCheck(h, x, otherType).ifTrue;
|
||||
var s2 = otherType == null
|
||||
? s0
|
||||
: s0._tryPromoteForTypeCheck(h, x, otherType).ifTrue;
|
||||
var result = s2.rebaseForward(h, s1);
|
||||
if (expectedChain == null) {
|
||||
expect(
|
||||
@@ -4637,8 +4612,9 @@ main() {
|
||||
// Verify that the given promotion chain matches the expected list of
|
||||
// strings.
|
||||
void _checkChain(List<SharedTypeView> chain, List<String> expected) {
|
||||
var strings =
|
||||
chain.map((t) => t.unwrapTypeView<Type>().type).toList();
|
||||
var strings = chain
|
||||
.map((t) => t.unwrapTypeView<Type>().type)
|
||||
.toList();
|
||||
expect(strings, expected);
|
||||
}
|
||||
|
||||
@@ -7532,8 +7508,9 @@ main() {
|
||||
ifCase(
|
||||
x,
|
||||
recordPattern([
|
||||
(wildcard(type: 'num')
|
||||
..errorId = 'NUM').and(wildcard(type: 'int')).recordField(),
|
||||
(wildcard(
|
||||
type: 'num',
|
||||
)..errorId = 'NUM').and(wildcard(type: 'int')).recordField(),
|
||||
]),
|
||||
[checkPromoted(x, '(int,)')],
|
||||
),
|
||||
@@ -7575,9 +7552,9 @@ main() {
|
||||
ifCase(
|
||||
x,
|
||||
recordPattern([
|
||||
(wildcard(type: 'Object')
|
||||
..errorId =
|
||||
'OBJECT').and(wildcard(type: 'int')).recordField(),
|
||||
(wildcard(type: 'Object')..errorId = 'OBJECT')
|
||||
.and(wildcard(type: 'int'))
|
||||
.recordField(),
|
||||
]),
|
||||
[checkPromoted(x, '(int,)')],
|
||||
),
|
||||
@@ -12829,12 +12806,12 @@ Matcher _matchVariableModel({
|
||||
assigned ??= anything;
|
||||
unassigned ??= anything;
|
||||
writeCaptured ??= anything;
|
||||
Matcher chainMatcher =
|
||||
chain is List<String> ? _matchPromotionChain(chain) : wrapMatcher(chain);
|
||||
Matcher ofInterestMatcher =
|
||||
ofInterest is List<String>
|
||||
? _matchOfInterestSet(ofInterest)
|
||||
: wrapMatcher(ofInterest);
|
||||
Matcher chainMatcher = chain is List<String>
|
||||
? _matchPromotionChain(chain)
|
||||
: wrapMatcher(chain);
|
||||
Matcher ofInterestMatcher = ofInterest is List<String>
|
||||
? _matchOfInterestSet(ofInterest)
|
||||
: wrapMatcher(ofInterest);
|
||||
Matcher assignedMatcher = wrapMatcher(assigned);
|
||||
Matcher unassignedMatcher = wrapMatcher(unassigned);
|
||||
Matcher writeCapturedMatcher = wrapMatcher(writeCaptured);
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
class C {
|
||||
C method(dynamic value) => this;
|
||||
C Function(dynamic) get functionGetter => (_) => this;
|
||||
C Function(dynamic) get functionGetter =>
|
||||
(_) => this;
|
||||
}
|
||||
|
||||
void methodCall(C? c) {
|
||||
|
||||
+54
-58
@@ -23,18 +23,17 @@ topLevel_function(Object x, Object y) {
|
||||
y = 'foo';
|
||||
}
|
||||
|
||||
topLevel_function_arrow(Object x, Object y) =>
|
||||
(x is int && y is int)
|
||||
? [
|
||||
/*int*/ x,
|
||||
/*int*/ y,
|
||||
() {
|
||||
/*int*/
|
||||
x;
|
||||
y;
|
||||
},
|
||||
]
|
||||
: (y = 'foo');
|
||||
topLevel_function_arrow(Object x, Object y) => (x is int && y is int)
|
||||
? [
|
||||
/*int*/ x,
|
||||
/*int*/ y,
|
||||
() {
|
||||
/*int*/
|
||||
x;
|
||||
y;
|
||||
},
|
||||
]
|
||||
: (y = 'foo');
|
||||
|
||||
void topLevel_setter(Object x) {
|
||||
Object y = f(0);
|
||||
@@ -52,15 +51,14 @@ void topLevel_setter(Object x) {
|
||||
y = 'foo';
|
||||
}
|
||||
|
||||
void topLevel_setter_arrow(Object y) =>
|
||||
(y is int)
|
||||
? [
|
||||
/*int*/ y,
|
||||
() {
|
||||
y;
|
||||
},
|
||||
]
|
||||
: (y = 'foo');
|
||||
void topLevel_setter_arrow(Object y) => (y is int)
|
||||
? [
|
||||
/*int*/ y,
|
||||
() {
|
||||
y;
|
||||
},
|
||||
]
|
||||
: (y = 'foo');
|
||||
|
||||
get topLevel_getter {
|
||||
Object x = f(0);
|
||||
@@ -101,14 +99,14 @@ class C {
|
||||
factory C.constructor_arrow(Object x, Object y) => C(
|
||||
(x is int && y is int)
|
||||
? [
|
||||
/*int*/ x,
|
||||
/*int*/ y,
|
||||
() {
|
||||
/*int*/
|
||||
x;
|
||||
y;
|
||||
},
|
||||
]
|
||||
/*int*/ x,
|
||||
/*int*/ y,
|
||||
() {
|
||||
/*int*/
|
||||
x;
|
||||
y;
|
||||
},
|
||||
]
|
||||
: (y = 'foo'),
|
||||
);
|
||||
|
||||
@@ -117,14 +115,14 @@ class C {
|
||||
f(
|
||||
(x is int && y is int)
|
||||
? [
|
||||
/*int*/ x,
|
||||
/*int*/ y,
|
||||
() {
|
||||
/*int*/
|
||||
x;
|
||||
y;
|
||||
},
|
||||
]
|
||||
/*int*/ x,
|
||||
/*int*/ y,
|
||||
() {
|
||||
/*int*/
|
||||
x;
|
||||
y;
|
||||
},
|
||||
]
|
||||
: (y = 'foo'),
|
||||
),
|
||||
);
|
||||
@@ -144,18 +142,17 @@ class C {
|
||||
y = 'foo';
|
||||
}
|
||||
|
||||
method_arrow(Object x, Object y) =>
|
||||
(x is int && y is int)
|
||||
? [
|
||||
/*int*/ x,
|
||||
/*int*/ y,
|
||||
() {
|
||||
/*int*/
|
||||
x;
|
||||
y;
|
||||
},
|
||||
]
|
||||
: (y = 'foo');
|
||||
method_arrow(Object x, Object y) => (x is int && y is int)
|
||||
? [
|
||||
/*int*/ x,
|
||||
/*int*/ y,
|
||||
() {
|
||||
/*int*/
|
||||
x;
|
||||
y;
|
||||
},
|
||||
]
|
||||
: (y = 'foo');
|
||||
|
||||
void setter(Object x) {
|
||||
Object y = f(0);
|
||||
@@ -173,15 +170,14 @@ class C {
|
||||
y = 'foo';
|
||||
}
|
||||
|
||||
void setter_arrow(Object y) =>
|
||||
(y is int)
|
||||
? [
|
||||
/*int*/ y,
|
||||
() {
|
||||
y;
|
||||
},
|
||||
]
|
||||
: (y = 'foo');
|
||||
void setter_arrow(Object y) => (y is int)
|
||||
? [
|
||||
/*int*/ y,
|
||||
() {
|
||||
y;
|
||||
},
|
||||
]
|
||||
: (y = 'foo');
|
||||
|
||||
get getter {
|
||||
Object x = f(0);
|
||||
|
||||
+45
-60
@@ -42,10 +42,9 @@ class C3 {
|
||||
required_named(C3 c) {
|
||||
if (c.bad == null) return;
|
||||
c.f(
|
||||
i:
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C3.bad))*/ bad,
|
||||
i: c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C3.bad))*/ bad,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -57,10 +56,9 @@ class C4 {
|
||||
optional_named(C4 c) {
|
||||
if (c.bad == null) return;
|
||||
c.f(
|
||||
i:
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C4.bad))*/ bad,
|
||||
i: c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C4.bad))*/ bad,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -345,10 +343,9 @@ class C21 {
|
||||
|
||||
assignmentRhs(C21 c, int i) {
|
||||
if (c.bad == null) return;
|
||||
i =
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C21.bad))*/ bad;
|
||||
i = c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C21.bad))*/ bad;
|
||||
}
|
||||
|
||||
class C22 {
|
||||
@@ -357,10 +354,9 @@ class C22 {
|
||||
|
||||
variableInitializer(C22 c) {
|
||||
if (c.bad == null) return;
|
||||
int i =
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C22.bad))*/ bad;
|
||||
int i = c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C22.bad))*/ bad;
|
||||
}
|
||||
|
||||
class C23 {
|
||||
@@ -369,10 +365,9 @@ class C23 {
|
||||
final int y;
|
||||
C23.constructorInitializer(C23 c)
|
||||
: x = c.bad!,
|
||||
y =
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C23.bad))*/ bad;
|
||||
y = c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C23.bad))*/ bad;
|
||||
}
|
||||
|
||||
class C24 {
|
||||
@@ -382,38 +377,34 @@ class C24 {
|
||||
forVariableInitializer(C24 c) {
|
||||
if (c.bad == null) return;
|
||||
for (
|
||||
int i =
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C24.bad))*/ bad;
|
||||
int i = c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C24.bad))*/ bad;
|
||||
false;
|
||||
) {}
|
||||
[
|
||||
for (
|
||||
int i =
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C24.bad))*/ bad;
|
||||
int i = c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C24.bad))*/ bad;
|
||||
false;
|
||||
)
|
||||
null,
|
||||
];
|
||||
({
|
||||
for (
|
||||
int i =
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C24.bad))*/ bad;
|
||||
int i = c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C24.bad))*/ bad;
|
||||
false;
|
||||
)
|
||||
null,
|
||||
});
|
||||
({
|
||||
for (
|
||||
int i =
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C24.bad))*/ bad;
|
||||
int i = c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C24.bad))*/ bad;
|
||||
false;
|
||||
)
|
||||
null: null,
|
||||
@@ -427,38 +418,34 @@ class C25 {
|
||||
forAssignmentInitializer(C25 c, int i) {
|
||||
if (c.bad == null) return;
|
||||
for (
|
||||
i =
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C25.bad))*/ bad;
|
||||
i = c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C25.bad))*/ bad;
|
||||
false;
|
||||
) {}
|
||||
[
|
||||
for (
|
||||
i =
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C25.bad))*/ bad;
|
||||
i = c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C25.bad))*/ bad;
|
||||
false;
|
||||
)
|
||||
null,
|
||||
];
|
||||
({
|
||||
for (
|
||||
i =
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C25.bad))*/ bad;
|
||||
i = c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C25.bad))*/ bad;
|
||||
false;
|
||||
)
|
||||
null,
|
||||
});
|
||||
({
|
||||
for (
|
||||
i =
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C25.bad))*/ bad;
|
||||
i = c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C25.bad))*/ bad;
|
||||
false;
|
||||
)
|
||||
null: null,
|
||||
@@ -472,10 +459,9 @@ class C26 {
|
||||
compoundAssignmentRhs(C26 c) {
|
||||
num n = 0;
|
||||
if (c.bad == null) return;
|
||||
n +=
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C26.bad))*/ bad;
|
||||
n += c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C26.bad))*/ bad;
|
||||
}
|
||||
|
||||
class C27 {
|
||||
@@ -592,8 +578,7 @@ class C35 {
|
||||
|
||||
indexSetRhs(C35 c, List<int> x) {
|
||||
if (c.bad == null) return;
|
||||
x[0] =
|
||||
c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C35.bad))*/ bad;
|
||||
x[0] = c
|
||||
.
|
||||
/*notPromoted(propertyNotPromotedForInherentReason(target: member:C35.bad))*/ bad;
|
||||
}
|
||||
|
||||
+13
-14
@@ -19,9 +19,9 @@ localFunctions() {
|
||||
}
|
||||
|
||||
var /*dynamic Function(dynamic)*/ singleReturn2 =
|
||||
/*dynamic*/ (/*dynamic*/ o) {
|
||||
return o;
|
||||
};
|
||||
/*dynamic*/ (/*dynamic*/ o) {
|
||||
return o;
|
||||
};
|
||||
|
||||
/*int*/
|
||||
typedArrowReturn1() => 1;
|
||||
@@ -45,16 +45,15 @@ localFunctions() {
|
||||
}
|
||||
}
|
||||
|
||||
var /*int? Function(bool)*/ multipleTypedReturns2 = /*int?*/ (
|
||||
bool condition,
|
||||
) {
|
||||
if (condition) {
|
||||
return 1;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
var /*int? Function(bool)*/ multipleTypedReturns2 = /*int?*/
|
||||
(bool condition) {
|
||||
if (condition) {
|
||||
return 1;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
int Function(String) inferredFromContext = /*int*/
|
||||
(/*String*/ condition) => condition.length;
|
||||
int Function(String) inferredFromContext = /*int*/ (/*String*/ condition) =>
|
||||
condition.length;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,9 @@ evaluate=ListLiteral([ExpressionElement(IntegerLiteral(1))])
|
||||
constBool=BooleanLiteral(true)*/
|
||||
void listLiteral10() {}
|
||||
|
||||
@Helper([...[0, 1]])
|
||||
@Helper([
|
||||
...[0, 1],
|
||||
])
|
||||
/*member: listLiteral11:
|
||||
resolved=ListLiteral([SpreadElement(...ListLiteral([
|
||||
ExpressionElement(IntegerLiteral(0)),
|
||||
@@ -111,7 +113,9 @@ constList=ListLiteral([
|
||||
ExpressionElement(IntegerLiteral(3))])*/
|
||||
void listLiteral12() {}
|
||||
|
||||
@Helper([...?[0, 1]])
|
||||
@Helper([
|
||||
...?[0, 1],
|
||||
])
|
||||
/*member: listLiteral13:
|
||||
resolved=ListLiteral([SpreadElement(?...ListLiteral([
|
||||
ExpressionElement(IntegerLiteral(0)),
|
||||
@@ -222,7 +226,10 @@ evaluate=ListLiteral([])
|
||||
constBool=BooleanLiteral(true)*/
|
||||
void listLiteral24() {}
|
||||
|
||||
@Helper([if (constBool) if (constBool) ?null else ?null])
|
||||
@Helper([
|
||||
if (constBool)
|
||||
if (constBool) ?null else ?null,
|
||||
])
|
||||
/*member: listLiteral25:
|
||||
resolved=ListLiteral([IfElement(
|
||||
StaticGet(constBool),
|
||||
|
||||
@@ -90,7 +90,9 @@ evaluate=SetOrMapLiteral({ExpressionElement(IntegerLiteral(1))})
|
||||
constBool=BooleanLiteral(true)*/
|
||||
void setOrMapLiteral10() {}
|
||||
|
||||
@Helper({...{0, 1}})
|
||||
@Helper({
|
||||
...{0, 1},
|
||||
})
|
||||
/*member: setOrMapLiteral11:
|
||||
resolved=SetOrMapLiteral({SpreadElement(...SetOrMapLiteral({
|
||||
ExpressionElement(IntegerLiteral(0)),
|
||||
@@ -111,7 +113,9 @@ constList=ListLiteral([
|
||||
ExpressionElement(IntegerLiteral(3))])*/
|
||||
void setOrMapLiteral12() {}
|
||||
|
||||
@Helper({...?{0, 1}})
|
||||
@Helper({
|
||||
...?{0, 1},
|
||||
})
|
||||
/*member: setOrMapLiteral13:
|
||||
resolved=SetOrMapLiteral({SpreadElement(?...SetOrMapLiteral({
|
||||
ExpressionElement(IntegerLiteral(0)),
|
||||
@@ -222,7 +226,10 @@ evaluate=SetOrMapLiteral({})
|
||||
constBool=BooleanLiteral(true)*/
|
||||
void setOrMapLiteral24() {}
|
||||
|
||||
@Helper({if (constBool) if (constBool) ?null else ?null})
|
||||
@Helper({
|
||||
if (constBool)
|
||||
if (constBool) ?null else ?null,
|
||||
})
|
||||
/*member: setOrMapLiteral25:
|
||||
resolved=SetOrMapLiteral({IfElement(
|
||||
StaticGet(constBool),
|
||||
|
||||
@@ -867,10 +867,8 @@ class Cascade extends Expression {
|
||||
var previousCascadeTargetIR = h.typeAnalyzer._currentCascadeTargetIR;
|
||||
var previousCascadeType = h.typeAnalyzer._currentCascadeTargetType;
|
||||
// Create a let-variable that will be initialized to the value of the LHS
|
||||
var targetTmp =
|
||||
h.typeAnalyzer._currentCascadeTargetIR = h.irBuilder.allocateTmp(
|
||||
location: location,
|
||||
);
|
||||
var targetTmp = h.typeAnalyzer._currentCascadeTargetIR = h.irBuilder
|
||||
.allocateTmp(location: location);
|
||||
h.typeAnalyzer._currentCascadeTargetType = h.flow
|
||||
.cascadeExpression_afterTarget(
|
||||
target,
|
||||
@@ -1107,10 +1105,9 @@ class CheckPromoted extends Expression {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
var predicate =
|
||||
expectedTypeStr == null
|
||||
? 'not promoted'
|
||||
: 'promoted to $expectedTypeStr';
|
||||
var predicate = expectedTypeStr == null
|
||||
? 'not promoted'
|
||||
: 'promoted to $expectedTypeStr';
|
||||
return 'check $promotable $predicate;';
|
||||
}
|
||||
|
||||
@@ -1553,10 +1550,9 @@ class ExpressionCollectionElement extends CollectionElement {
|
||||
|
||||
@override
|
||||
void visit(Harness h, CollectionElementContext context) {
|
||||
SharedTypeSchemaView typeSchema =
|
||||
context is CollectionElementContextType
|
||||
? context.elementTypeSchema
|
||||
: h.operations.unknownType;
|
||||
SharedTypeSchemaView typeSchema = context is CollectionElementContextType
|
||||
? context.elementTypeSchema
|
||||
: h.operations.unknownType;
|
||||
h.typeAnalyzer.analyzeExpression(expression, typeSchema);
|
||||
h.irBuilder.apply(
|
||||
'celt',
|
||||
@@ -2000,10 +1996,9 @@ class Harness {
|
||||
) {
|
||||
if (operator == '==' || operator == '!=') {
|
||||
return RelationalOperatorResolution(
|
||||
kind:
|
||||
operator == '=='
|
||||
? RelationalOperatorKind.equals
|
||||
: RelationalOperatorKind.notEquals,
|
||||
kind: operator == '=='
|
||||
? RelationalOperatorKind.equals
|
||||
: RelationalOperatorKind.notEquals,
|
||||
parameterType: SharedTypeView(Type('Object')),
|
||||
returnType: SharedTypeView(Type('bool')),
|
||||
);
|
||||
@@ -3914,8 +3909,8 @@ class ObjectPattern extends Pattern {
|
||||
this,
|
||||
fields: fields,
|
||||
);
|
||||
var matchedType =
|
||||
objectPatternResult.matchedValueType.unwrapTypeView<Type>();
|
||||
var matchedType = objectPatternResult.matchedValueType
|
||||
.unwrapTypeView<Type>();
|
||||
var requiredType = objectPatternResult.requiredType.unwrapTypeView<Type>();
|
||||
h.irBuilder.atom(matchedType.type, Kind.type, location: location);
|
||||
h.irBuilder.atom(requiredType.type, Kind.type, location: location);
|
||||
@@ -4368,10 +4363,9 @@ class PostIncDec extends Expression {
|
||||
|
||||
@override
|
||||
ExpressionTypeAnalysisResult visit(Harness h, SharedTypeSchemaView schema) {
|
||||
Type type =
|
||||
h.typeAnalyzer
|
||||
.analyzeExpression(lhs, h.operations.unknownType)
|
||||
.unwrapTypeView();
|
||||
Type type = h.typeAnalyzer
|
||||
.analyzeExpression(lhs, h.operations.unknownType)
|
||||
.unwrapTypeView();
|
||||
lhs._visitPostIncDec(h, this, type);
|
||||
return new ExpressionTypeAnalysisResult(type: SharedTypeView(type));
|
||||
}
|
||||
@@ -4456,10 +4450,9 @@ class Property extends PromotableLValue {
|
||||
'a null-aware property.',
|
||||
);
|
||||
}
|
||||
var receiverType =
|
||||
h.typeAnalyzer
|
||||
.analyzeExpression(target, h.operations.unknownType)
|
||||
.unwrapTypeView<Type>();
|
||||
var receiverType = h.typeAnalyzer
|
||||
.analyzeExpression(target, h.operations.unknownType)
|
||||
.unwrapTypeView<Type>();
|
||||
var member = h.typeAnalyzer._lookupMember(receiverType, propertyName);
|
||||
return member;
|
||||
}
|
||||
@@ -4884,8 +4877,8 @@ class RecordPattern extends Pattern {
|
||||
this,
|
||||
fields: fields,
|
||||
);
|
||||
var matchedType =
|
||||
recordPatternResult.matchedValueType.unwrapTypeView<Type>();
|
||||
var matchedType = recordPatternResult.matchedValueType
|
||||
.unwrapTypeView<Type>();
|
||||
var requiredType = recordPatternResult.requiredType.unwrapTypeView<Type>();
|
||||
h.irBuilder.atom(matchedType.type, Kind.type, location: location);
|
||||
h.irBuilder.atom(requiredType.type, Kind.type, location: location);
|
||||
@@ -5193,12 +5186,11 @@ class SwitchStatement extends Statement {
|
||||
@override
|
||||
String toString() {
|
||||
var isLegacyExhaustive = this.isLegacyExhaustive;
|
||||
var exhaustiveness =
|
||||
isLegacyExhaustive == null
|
||||
? ''
|
||||
: isLegacyExhaustive
|
||||
? '<exhaustive>'
|
||||
: '<non-exhaustive>';
|
||||
var exhaustiveness = isLegacyExhaustive == null
|
||||
? ''
|
||||
: isLegacyExhaustive
|
||||
? '<exhaustive>'
|
||||
: '<non-exhaustive>';
|
||||
String body;
|
||||
if (cases.isEmpty) {
|
||||
body = '{}';
|
||||
@@ -5706,15 +5698,14 @@ class VariableDeclaration extends Statement {
|
||||
if (initializer == null) {
|
||||
// Use the shared logic for analyzing uninitialized variable
|
||||
// declarations.
|
||||
staticType =
|
||||
h.typeAnalyzer
|
||||
.analyzeUninitializedVariableDeclaration(
|
||||
this,
|
||||
variable,
|
||||
declaredType?.wrapSharedTypeView(),
|
||||
isFinal: isFinal,
|
||||
)
|
||||
.unwrapTypeView();
|
||||
staticType = h.typeAnalyzer
|
||||
.analyzeUninitializedVariableDeclaration(
|
||||
this,
|
||||
variable,
|
||||
declaredType?.wrapSharedTypeView(),
|
||||
isFinal: isFinal,
|
||||
)
|
||||
.unwrapTypeView();
|
||||
h.irBuilder.atom(staticType.type, Kind.type, location: location);
|
||||
irName = 'declare';
|
||||
argKinds = [Kind.variable, Kind.type];
|
||||
@@ -5723,23 +5714,21 @@ class VariableDeclaration extends Statement {
|
||||
// There's no shared logic for analyzing initialized variable
|
||||
// declarations, so analyze the declaration directly.
|
||||
if (isLate) h.flow.lateInitializer_begin(this);
|
||||
var initializerType =
|
||||
h.typeAnalyzer
|
||||
.analyzeExpression(
|
||||
initializer,
|
||||
declaredType?.wrapSharedTypeSchemaView() ??
|
||||
h.operations.unknownType,
|
||||
)
|
||||
.unwrapTypeView<Type>();
|
||||
var initializerType = h.typeAnalyzer
|
||||
.analyzeExpression(
|
||||
initializer,
|
||||
declaredType?.wrapSharedTypeSchemaView() ??
|
||||
h.operations.unknownType,
|
||||
)
|
||||
.unwrapTypeView<Type>();
|
||||
if (isLate) h.flow.lateInitializer_end();
|
||||
staticType =
|
||||
variable.type =
|
||||
declaredType ??
|
||||
h.typeAnalyzer
|
||||
.variableTypeFromInitializerType(
|
||||
initializerType.wrapSharedTypeView(),
|
||||
)
|
||||
.unwrapTypeView();
|
||||
staticType = variable.type =
|
||||
declaredType ??
|
||||
h.typeAnalyzer
|
||||
.variableTypeFromInitializerType(
|
||||
initializerType.wrapSharedTypeView(),
|
||||
)
|
||||
.unwrapTypeView();
|
||||
h.flow.declare(variable, SharedTypeView(staticType), initialized: true);
|
||||
h.flow.initialize(
|
||||
variable,
|
||||
@@ -5836,10 +5825,10 @@ class VariablePattern extends Pattern {
|
||||
variable.name,
|
||||
declaredType?.wrapSharedTypeView(),
|
||||
);
|
||||
var matchedType =
|
||||
declaredVariablePatternResult.matchedValueType.unwrapTypeView<Type>();
|
||||
var staticType =
|
||||
declaredVariablePatternResult.staticType.unwrapTypeView<Type>();
|
||||
var matchedType = declaredVariablePatternResult.matchedValueType
|
||||
.unwrapTypeView<Type>();
|
||||
var staticType = declaredVariablePatternResult.staticType
|
||||
.unwrapTypeView<Type>();
|
||||
h.typeAnalyzer.handleDeclaredVariablePattern(
|
||||
this,
|
||||
matchedType: matchedType,
|
||||
@@ -6084,8 +6073,9 @@ class Write extends Expression {
|
||||
void preVisit(PreVisitor visitor) {
|
||||
lhs.preVisit(
|
||||
visitor,
|
||||
disposition:
|
||||
rhs == null ? _LValueDisposition.readWrite : _LValueDisposition.write,
|
||||
disposition: rhs == null
|
||||
? _LValueDisposition.readWrite
|
||||
: _LValueDisposition.write,
|
||||
);
|
||||
rhs?.preVisit(visitor);
|
||||
}
|
||||
@@ -6100,15 +6090,13 @@ class Write extends Expression {
|
||||
if (rhs == null) {
|
||||
// We are simulating an increment/decrement operation.
|
||||
// TODO(paulberry): Make a separate node type for this.
|
||||
type =
|
||||
h.typeAnalyzer
|
||||
.analyzeExpression(lhs, h.operations.unknownType)
|
||||
.unwrapTypeView();
|
||||
type = h.typeAnalyzer
|
||||
.analyzeExpression(lhs, h.operations.unknownType)
|
||||
.unwrapTypeView();
|
||||
} else {
|
||||
type =
|
||||
h.typeAnalyzer
|
||||
.analyzeExpression(rhs, h.operations.unknownType)
|
||||
.unwrapTypeView();
|
||||
type = h.typeAnalyzer
|
||||
.analyzeExpression(rhs, h.operations.unknownType)
|
||||
.unwrapTypeView();
|
||||
}
|
||||
lhs._visitWrite(h, this, type, rhs);
|
||||
// TODO(paulberry): null shorting
|
||||
@@ -6678,8 +6666,8 @@ class _MiniAstTypeAnalyzer
|
||||
arguments[i],
|
||||
methodType is FunctionType && !methodType.isQuestionType
|
||||
? operations.typeToSchema(
|
||||
SharedTypeView(methodType.positionalParameters[i]),
|
||||
)
|
||||
SharedTypeView(methodType.positionalParameters[i]),
|
||||
)
|
||||
: operations.unknownType,
|
||||
);
|
||||
}
|
||||
@@ -6767,18 +6755,17 @@ class _MiniAstTypeAnalyzer
|
||||
}) {
|
||||
var member = _lookupMember(thisType, propertyName);
|
||||
var memberType = member?._type ?? operations.dynamicType.unwrapTypeView();
|
||||
var promotedType =
|
||||
flow
|
||||
.propertyGet(
|
||||
node,
|
||||
isSuperAccess
|
||||
? SuperPropertyTarget.singleton
|
||||
: ThisPropertyTarget.singleton,
|
||||
propertyName,
|
||||
member,
|
||||
SharedTypeView(memberType),
|
||||
)
|
||||
?.unwrapTypeView();
|
||||
var promotedType = flow
|
||||
.propertyGet(
|
||||
node,
|
||||
isSuperAccess
|
||||
? SuperPropertyTarget.singleton
|
||||
: ThisPropertyTarget.singleton,
|
||||
propertyName,
|
||||
member,
|
||||
SharedTypeView(memberType),
|
||||
)
|
||||
?.unwrapTypeView();
|
||||
return new ExpressionTypeAnalysisResult(
|
||||
type: SharedTypeView(promotedType ?? memberType),
|
||||
);
|
||||
|
||||
@@ -268,8 +268,9 @@ class MiniIRBuilder {
|
||||
}) {
|
||||
var value = _pop(Kind.expression);
|
||||
var index = indexTmp == null ? _pop(Kind.expression) : indexTmp._name;
|
||||
var receiver =
|
||||
receiverTmp == null ? _pop(Kind.expression) : receiverTmp._name;
|
||||
var receiver = receiverTmp == null
|
||||
? _pop(Kind.expression)
|
||||
: receiverTmp._name;
|
||||
_push(
|
||||
IRNode(
|
||||
ir: '[]=($receiver, $index, $value)',
|
||||
@@ -344,8 +345,9 @@ class MiniIRBuilder {
|
||||
required String location,
|
||||
}) {
|
||||
var value = _pop(Kind.expression);
|
||||
var receiver =
|
||||
receiverTmp == null ? _pop(Kind.expression) : receiverTmp._name;
|
||||
var receiver = receiverTmp == null
|
||||
? _pop(Kind.expression)
|
||||
: receiverTmp._name;
|
||||
_push(
|
||||
IRNode(
|
||||
ir: 'set_$propertyName($receiver, $value)',
|
||||
|
||||
@@ -167,10 +167,9 @@ class FunctionType extends Type implements SharedFunctionType {
|
||||
}
|
||||
if (typeParametersShared.isNotEmpty) {
|
||||
// Check if types are equal under a consistent renaming of type formals
|
||||
var freshTypeParameterGenerator =
|
||||
FreshTypeParameterGenerator()
|
||||
..excludeNamesUsedIn(this)
|
||||
..excludeNamesUsedIn(other);
|
||||
var freshTypeParameterGenerator = FreshTypeParameterGenerator()
|
||||
..excludeNamesUsedIn(this)
|
||||
..excludeNamesUsedIn(other);
|
||||
var thisSubstitution = <TypeParameter, Type>{};
|
||||
var otherSubstitution = <TypeParameter, Type>{};
|
||||
var thisTypeFormalBounds = <Type>[];
|
||||
@@ -893,16 +892,13 @@ abstract class Type implements SharedType, _Substitutable<Type> {
|
||||
/// - A function type (e.g. `void Function()`)
|
||||
/// - A promoted type variable type (e.g. `T&int`)
|
||||
@override
|
||||
String toString({bool parenthesizeIfComplex = false}) =>
|
||||
isQuestionType
|
||||
? _parenthesizeIf(
|
||||
parenthesizeIfComplex,
|
||||
'${_toStringWithoutSuffix(parenthesizeIfComplex: true)}'
|
||||
'?',
|
||||
)
|
||||
: _toStringWithoutSuffix(
|
||||
parenthesizeIfComplex: parenthesizeIfComplex,
|
||||
);
|
||||
String toString({bool parenthesizeIfComplex = false}) => isQuestionType
|
||||
? _parenthesizeIf(
|
||||
parenthesizeIfComplex,
|
||||
'${_toStringWithoutSuffix(parenthesizeIfComplex: true)}'
|
||||
'?',
|
||||
)
|
||||
: _toStringWithoutSuffix(parenthesizeIfComplex: parenthesizeIfComplex);
|
||||
|
||||
/// Returns a string representation of the portion of this string that
|
||||
/// precedes the nullability suffix.
|
||||
@@ -1225,11 +1221,10 @@ class TypeSystem {
|
||||
'Future': (_) => [Type('Object')],
|
||||
'int': (_) => [Type('num'), Type('Object')],
|
||||
'Iterable': (_) => [Type('Object')],
|
||||
'List':
|
||||
(args) => [
|
||||
PrimaryType(TypeRegistry.iterable, args: args),
|
||||
Type('Object'),
|
||||
],
|
||||
'List': (args) => [
|
||||
PrimaryType(TypeRegistry.iterable, args: args),
|
||||
Type('Object'),
|
||||
],
|
||||
'Map': (_) => [Type('Object')],
|
||||
'Object': (_) => [],
|
||||
'num': (_) => [Type('Object')],
|
||||
@@ -2431,10 +2426,10 @@ extension on List<NamedFunctionParameter> {
|
||||
newType == null
|
||||
? namedFunctionParameter
|
||||
: NamedFunctionParameter(
|
||||
isRequired: namedFunctionParameter.isRequired,
|
||||
name: namedFunctionParameter.name,
|
||||
type: newType,
|
||||
),
|
||||
isRequired: namedFunctionParameter.isRequired,
|
||||
name: namedFunctionParameter.name,
|
||||
type: newType,
|
||||
),
|
||||
);
|
||||
}
|
||||
return newList;
|
||||
@@ -2458,10 +2453,10 @@ extension on List<NamedFunctionParameter> {
|
||||
newType == null
|
||||
? namedFunctionParameter
|
||||
: NamedFunctionParameter(
|
||||
isRequired: namedFunctionParameter.isRequired,
|
||||
name: namedFunctionParameter.name,
|
||||
type: newType,
|
||||
),
|
||||
isRequired: namedFunctionParameter.isRequired,
|
||||
name: namedFunctionParameter.name,
|
||||
type: newType,
|
||||
),
|
||||
);
|
||||
}
|
||||
return newList;
|
||||
|
||||
@@ -50,33 +50,30 @@ void main(List<String> args) {
|
||||
case ScanType.string:
|
||||
lengthProcessed = content.length;
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
hasErrors =
|
||||
scanString(
|
||||
content,
|
||||
configuration: new ScannerConfiguration(enableTripleShift: true),
|
||||
includeComments: true,
|
||||
).hasErrors;
|
||||
hasErrors = scanString(
|
||||
content,
|
||||
configuration: new ScannerConfiguration(enableTripleShift: true),
|
||||
includeComments: true,
|
||||
).hasErrors;
|
||||
}
|
||||
case ScanType.bytes:
|
||||
lengthProcessed = contentBytes.length;
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
hasErrors =
|
||||
scan(
|
||||
contentBytes,
|
||||
configuration: new ScannerConfiguration(enableTripleShift: true),
|
||||
includeComments: true,
|
||||
).hasErrors;
|
||||
hasErrors = scan(
|
||||
contentBytes,
|
||||
configuration: new ScannerConfiguration(enableTripleShift: true),
|
||||
includeComments: true,
|
||||
).hasErrors;
|
||||
}
|
||||
case ScanType.stringAsBytes:
|
||||
lengthProcessed = content.length;
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
Uint8List tmp = utf8.encode(contentZeroTerminated);
|
||||
hasErrors =
|
||||
scan(
|
||||
tmp,
|
||||
configuration: new ScannerConfiguration(enableTripleShift: true),
|
||||
includeComments: true,
|
||||
).hasErrors;
|
||||
hasErrors = scan(
|
||||
tmp,
|
||||
configuration: new ScannerConfiguration(enableTripleShift: true),
|
||||
includeComments: true,
|
||||
).hasErrors;
|
||||
}
|
||||
case ScanType.countLfs:
|
||||
lengthProcessed = contentBytes.length;
|
||||
|
||||
@@ -1371,8 +1371,9 @@ main() {
|
||||
h.run(
|
||||
[
|
||||
switch_(expr('int')..errorId = 'SCRUTINEE', [
|
||||
(expr('num')
|
||||
..errorId = 'EXPRESSION').pattern.then([break_()]),
|
||||
(expr(
|
||||
'num',
|
||||
)..errorId = 'EXPRESSION').pattern.then([break_()]),
|
||||
], isLegacyExhaustive: false),
|
||||
],
|
||||
expectedErrors: {
|
||||
@@ -1388,8 +1389,9 @@ main() {
|
||||
h.run(
|
||||
[
|
||||
switch_(expr('int')..errorId = 'SCRUTINEE', [
|
||||
(expr('String')
|
||||
..errorId = 'EXPRESSION').pattern.then([break_()]),
|
||||
(expr(
|
||||
'String',
|
||||
)..errorId = 'EXPRESSION').pattern.then([break_()]),
|
||||
], isLegacyExhaustive: false),
|
||||
],
|
||||
expectedErrors: {
|
||||
@@ -1414,8 +1416,9 @@ main() {
|
||||
h.run(
|
||||
[
|
||||
switch_(expr('int')..errorId = 'SCRUTINEE', [
|
||||
(expr('dynamic')
|
||||
..errorId = 'EXPRESSION').pattern.then([break_()]),
|
||||
(expr(
|
||||
'dynamic',
|
||||
)..errorId = 'EXPRESSION').pattern.then([break_()]),
|
||||
], isLegacyExhaustive: false),
|
||||
],
|
||||
expectedErrors: {
|
||||
@@ -2753,9 +2756,9 @@ main() {
|
||||
h.run(
|
||||
[
|
||||
(patternVariableDeclaration(
|
||||
(wildcard(type: 'int')
|
||||
..errorId =
|
||||
'LHS').and(wildcard(type: 'double')..errorId = 'RHS'),
|
||||
(wildcard(type: 'int')..errorId = 'LHS').and(
|
||||
wildcard(type: 'double')..errorId = 'RHS',
|
||||
),
|
||||
expr('num'),
|
||||
)..errorId = 'CONTEXT'),
|
||||
],
|
||||
@@ -3575,8 +3578,9 @@ main() {
|
||||
[
|
||||
(patternVariableDeclaration(
|
||||
recordPattern([
|
||||
(Var('a').pattern(type: 'int')
|
||||
..errorId = 'VAR(a)').recordField(),
|
||||
(Var(
|
||||
'a',
|
||||
).pattern(type: 'int')..errorId = 'VAR(a)').recordField(),
|
||||
Var('b').pattern().recordField(),
|
||||
])..errorId = 'PATTERN',
|
||||
expr('(int,)').checkSchema('(int, _)'),
|
||||
@@ -3705,8 +3709,9 @@ main() {
|
||||
[
|
||||
(patternVariableDeclaration(
|
||||
recordPattern([
|
||||
(Var('a').pattern(type: 'int')
|
||||
..errorId = 'VAR(a)').recordField('a'),
|
||||
(Var('a').pattern(
|
||||
type: 'int',
|
||||
)..errorId = 'VAR(a)').recordField('a'),
|
||||
Var('b').pattern().recordField('b'),
|
||||
])..errorId = 'PATTERN',
|
||||
expr('({int a})').checkSchema('({int a, _ b})'),
|
||||
|
||||
@@ -479,7 +479,8 @@ void main() {
|
||||
test('include entry must be a existing path and target', () async {
|
||||
var otherFile = 'g.json';
|
||||
var otherUri = specUri.resolve(otherFile);
|
||||
var jsonString = '''
|
||||
var jsonString =
|
||||
'''
|
||||
{
|
||||
"target": {
|
||||
"include": [{"path": "$otherFile", "target": "none"}],
|
||||
@@ -531,7 +532,8 @@ void main() {
|
||||
var thisUri = specUri.resolve(thisFile);
|
||||
var otherFile = 'g.json';
|
||||
var otherUri = thisUri.resolve(otherFile);
|
||||
var thisJsonString = '''
|
||||
var thisJsonString =
|
||||
'''
|
||||
{
|
||||
"target": {
|
||||
"include": [{"path": "$thisFile", "target": "target"}],
|
||||
@@ -547,7 +549,8 @@ void main() {
|
||||
throwsA(checkException(messageCyclicSpec(thisUri))),
|
||||
);
|
||||
|
||||
thisJsonString = '''
|
||||
thisJsonString =
|
||||
'''
|
||||
{
|
||||
"target": {
|
||||
"include": [{"path": "$otherFile", "target": "none"}],
|
||||
@@ -555,7 +558,8 @@ void main() {
|
||||
}
|
||||
}
|
||||
''';
|
||||
var otherJsonString = '''
|
||||
var otherJsonString =
|
||||
'''
|
||||
{
|
||||
"none": {
|
||||
"include": [{"path": "$thisFile", "target": "target"}],
|
||||
@@ -614,7 +618,8 @@ void main() {
|
||||
var otherUri2 = thisUri.resolve(otherFile2);
|
||||
var otherFile3 = '../i.json';
|
||||
var otherUri3 = otherUri2.resolve(otherFile3);
|
||||
var thisJsonString = '''
|
||||
var thisJsonString =
|
||||
'''
|
||||
{
|
||||
"foo": {
|
||||
"include": [
|
||||
@@ -645,7 +650,8 @@ void main() {
|
||||
}
|
||||
}
|
||||
}''';
|
||||
var otherJsonString2 = '''
|
||||
var otherJsonString2 =
|
||||
'''
|
||||
{
|
||||
"foo": {
|
||||
"libraries": {
|
||||
@@ -962,7 +968,8 @@ void main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
'''.replaceAll(new RegExp('\\s'), ''),
|
||||
'''
|
||||
.replaceAll(new RegExp('\\s'), ''),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user