Version 2.18.0-278.0.dev
Merge commit '4c263d3754cc793671eee6346ced1c63e191064a' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d8979c8..9b8f7c1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -34,6 +34,10 @@
- Deprecates `BidirectionalIterator`.
+### `dart:developer`
+
+- Deprecates `UserTag.MAX_USER_TAGS` in favor of `UserTag.maxUserTags`.
+
### Dart VM
Implementation of `async`/`async*`/`sync*` is revamped in Dart VM,
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index 39f7c88d..57df318 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -295,7 +295,7 @@
return sb.toString();
}
- Variable variableForKey(int key) => _promotionKeyStore.variableForKey(key);
+ Variable variableForKey(int key) => _promotionKeyStore.variableForKey(key)!;
Set<int> writtenInNode(Node node) => _getInfoForNode(node)._written;
}
@@ -1833,13 +1833,11 @@
///
/// A local variable is [initialized] if its declaration has an initializer.
/// A function parameter is always initialized, so [initialized] is `true`.
- FlowModel<Type> declare<Variable extends Object>(
- Variable variable, int variableKey, bool initialized) {
+ FlowModel<Type> declare(int variableKey, bool initialized) {
VariableModel<Type> newInfoForVar =
new VariableModel.fresh(assigned: initialized);
- return _updateVariableInfo(
- new VariableReference(variable, variableKey), newInfoForVar);
+ return _updateVariableInfo(variableKey, newInfoForVar);
}
/// Gets the info for the given [promotionKey], creating it if it doesn't
@@ -1997,10 +1995,11 @@
///
/// Note that the state is only changed if the previous type of [variable] was
/// potentially nullable.
- ExpressionInfo<Type> tryMarkNonNullable(TypeOperations<Type> typeOperations,
- ReferenceWithType<Type> referenceWithType) {
- VariableModel<Type> info =
- referenceWithType.reference.getInfo(variableInfo);
+ ExpressionInfo<Type> tryMarkNonNullable(
+ TypeOperations<Type> typeOperations,
+ ReferenceWithType<Type> referenceWithType,
+ PromotionKeyStore<Object> promotionKeyStore) {
+ VariableModel<Type> info = _getInfo(referenceWithType.promotionKey);
if (info.writeCaptured) {
return new _TrivialExpressionInfo<Type>(this);
}
@@ -2012,8 +2011,8 @@
}
assert(typeOperations.isSubtypeOf(newType, previousType));
- FlowModel<Type> ifTrue = _finishTypeTest(
- typeOperations, referenceWithType.reference, info, null, newType);
+ FlowModel<Type> ifTrue = _finishTypeTest(typeOperations, referenceWithType,
+ info, null, newType, promotionKeyStore);
return new ExpressionInfo<Type>(after: this, ifTrue: ifTrue, ifFalse: this);
}
@@ -2027,10 +2026,12 @@
///
/// TODO(paulberry): if the type is non-nullable, should this method mark the
/// variable as definitely assigned? Does it matter?
- FlowModel<Type> tryPromoteForTypeCast(TypeOperations<Type> typeOperations,
- ReferenceWithType<Type> referenceWithType, Type type) {
- VariableModel<Type> info =
- referenceWithType.reference.getInfo(variableInfo);
+ FlowModel<Type> tryPromoteForTypeCast(
+ TypeOperations<Type> typeOperations,
+ ReferenceWithType<Type> referenceWithType,
+ Type type,
+ PromotionKeyStore<Object> promotionKeyStore) {
+ VariableModel<Type> info = _getInfo(referenceWithType.promotionKey);
if (info.writeCaptured) {
return this;
}
@@ -2043,8 +2044,8 @@
assert(typeOperations.isSubtypeOf(newType, previousType),
"Expected $newType to be a subtype of $previousType.");
- return _finishTypeTest(
- typeOperations, referenceWithType.reference, info, type, newType);
+ return _finishTypeTest(typeOperations, referenceWithType, info, type,
+ newType, promotionKeyStore);
}
/// Returns an [ExpressionInfo] indicating the result of checking whether the
@@ -2059,9 +2060,9 @@
ExpressionInfo<Type> tryPromoteForTypeCheck(
TypeOperations<Type> typeOperations,
ReferenceWithType<Type> referenceWithType,
- Type type) {
- VariableModel<Type> info =
- referenceWithType.reference.getInfo(variableInfo);
+ Type type,
+ PromotionKeyStore<Object> promotionKeyStore) {
+ VariableModel<Type> info = _getInfo(referenceWithType.promotionKey);
if (info.writeCaptured) {
return new _TrivialExpressionInfo<Type>(this);
}
@@ -2073,8 +2074,8 @@
!typeOperations.isSameType(typeIfSuccess, previousType)) {
assert(typeOperations.isSubtypeOf(typeIfSuccess, previousType),
"Expected $typeIfSuccess to be a subtype of $previousType.");
- ifTrue = _finishTypeTest(typeOperations, referenceWithType.reference,
- info, type, typeIfSuccess);
+ ifTrue = _finishTypeTest(typeOperations, referenceWithType, info, type,
+ typeIfSuccess, promotionKeyStore);
}
Type factoredType = typeOperations.factor(previousType, type);
@@ -2089,8 +2090,8 @@
} else {
typeIfFalse = factoredType;
}
- FlowModel<Type> ifFalse = _finishTypeTest(
- typeOperations, referenceWithType.reference, info, type, typeIfFalse);
+ FlowModel<Type> ifFalse = _finishTypeTest(typeOperations, referenceWithType,
+ info, type, typeIfFalse, promotionKeyStore);
return new ExpressionInfo<Type>(
after: this, ifTrue: ifTrue, ifFalse: ifFalse);
@@ -2135,8 +2136,7 @@
promoteToTypeOfInterest: promoteToTypeOfInterest);
if (identical(newInfoForVar, infoForVar)) return this;
- return _updateVariableInfo(
- new VariableReference(variable, variableKey), newInfoForVar);
+ return _updateVariableInfo(variableKey, newInfoForVar);
}
/// Common algorithm for [tryMarkNonNullable], [tryPromoteForTypeCast],
@@ -2151,12 +2151,12 @@
/// no redundant or side-promotions)
/// - The variable should not be write-captured.
FlowModel<Type> _finishTypeTest(
- TypeOperations<Type> typeOperations,
- Reference<Type> reference,
- VariableModel<Type> info,
- Type? testedType,
- Type? promotedType,
- ) {
+ TypeOperations<Type> typeOperations,
+ ReferenceWithType<Type> reference,
+ VariableModel<Type> info,
+ Type? testedType,
+ Type? promotedType,
+ PromotionKeyStore<Object> promotionKeyStore) {
List<Type> newTested = info.tested;
if (testedType != null) {
newTested = VariableModel._addTypeToUniqueList(
@@ -2168,7 +2168,7 @@
if (promotedType != null) {
newPromotedTypes =
VariableModel._addToPromotedTypes(info.promotedTypes, promotedType);
- if (reference is VariableReference<Object, Object> &&
+ if (reference.isPromotable(promotionKeyStore) &&
typeOperations.isNever(promotedType)) {
newReachable = reachable.setUnreachable();
}
@@ -2179,7 +2179,7 @@
newReachable == reachable
? this
: _updateVariableInfo(
- reference,
+ reference.promotionKey,
new VariableModel<Type>(
promotedTypes: newPromotedTypes,
tested: newTested,
@@ -2190,15 +2190,20 @@
reachable: newReachable);
}
+ /// Gets the info for [promotionKey] reference, creating it if it doesn't
+ /// exist.
+ VariableModel<Type> _getInfo(int promotionKey) =>
+ variableInfo[promotionKey] ?? new VariableModel<Type>.fresh();
+
/// Returns a new [FlowModel] where the information for [reference] is
/// replaced with [model].
FlowModel<Type> _updateVariableInfo(
- Reference<Type> reference, VariableModel<Type> model,
+ int promotionKey, VariableModel<Type> model,
{Reachability? reachable}) {
reachable ??= this.reachable;
Map<int, VariableModel<Type>> newVariableInfo =
new Map<int, VariableModel<Type>>.of(variableInfo);
- reference.storeInfo(newVariableInfo, model);
+ newVariableInfo[promotionKey] = model;
return new FlowModel<Type>.withInfo(reachable, newVariableInfo);
}
@@ -2445,7 +2450,7 @@
_variableKeys[variable] ??= _makeNewKey(variable);
@visibleForTesting
- Variable variableForKey(int variableKey) => _keyToVariable[variableKey]!;
+ Variable? variableForKey(int variableKey) => _keyToVariable[variableKey];
int _makeNewKey(Variable? variable) {
int key = _keyToVariable.length;
@@ -2626,60 +2631,20 @@
}
}
-/// Abstract base class representing a reference to a storage location that
-/// might be of interest to flow analysis to track. This could be a variable,
-/// `this`, or the result of a property access on some other reference.
-///
-/// Note that only variables can undergo promotion, but flow analysis may track
-/// other references in order to give useful error messages to the user about
-/// why promotion did not occur.
-@visibleForTesting
-abstract class Reference<Type extends Object> {
- /// The reference's corresponding key, as assigned by [PromotionKeyStore].
- final int promotionKey;
-
- Reference(this.promotionKey);
-
- /// Gets the info for this reference, creating it if it doesn't exist.
- VariableModel<Type> getInfo(Map<int, VariableModel<Type>> variableInfo) =>
- _getInfo(variableInfo) ?? new VariableModel<Type>.fresh();
-
- /// Gets a map of non-promotion reasons associated with this reference. This
- /// is the map that will be returned from [FlowAnalysis.whyNotPromoted].
- Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
- Map<int, VariableModel<Type>> variableInfo,
- Type staticType,
- TypeOperations<Type> operations);
-
- /// Creates a reference representing a get of a property called [propertyName]
- /// on the reference represented by `this`.
- Reference<Type> propertyGet(PromotionKeyStore promotionKeyStore,
- String propertyName, Object? propertyMember) =>
- new _PropertyGetReference<Type>(propertyName, propertyMember,
- promotionKeyStore.getProperty(promotionKey, propertyName));
-
- /// Stores info for this reference in [variableInfo].
- void storeInfo(Map<int, VariableModel<Type>> variableInfo,
- VariableModel<Type> variableModel) {
- variableInfo[promotionKey] = variableModel;
- }
-
- /// Gets the info for this reference, or `null` if it doesn't exist.
- VariableModel<Type>? _getInfo(Map<int, VariableModel<Type>> variableInfo) =>
- variableInfo[promotionKey];
-}
-
/// Container object combining a [Reference] object with its static type.
@visibleForTesting
class ReferenceWithType<Type extends Object> {
- final Reference<Type> reference;
+ int promotionKey;
final Type type;
- ReferenceWithType(this.reference, this.type);
+ ReferenceWithType(this.promotionKey, this.type);
+
+ bool isPromotable(PromotionKeyStore<Object> promotionKeyStore) =>
+ promotionKeyStore.variableForKey(promotionKey) != null;
@override
- String toString() => 'ReferenceWithType($reference, $type)';
+ String toString() => 'ReferenceWithType($promotionKey, $type)';
}
/// Data structure representing a unique value that a variable might take on
@@ -3352,46 +3317,6 @@
Type variableType(Variable variable);
}
-/// Specialization of [Reference] representing a reference to a local variable
-/// (or function parameter).
-@visibleForTesting
-class VariableReference<Variable extends Object, Type extends Object>
- extends Reference<Type> {
- /// The variable being referred to.
- final Variable variable;
-
- VariableReference(this.variable, super.promotionKey);
-
- @override
- Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
- Map<int, VariableModel<Type>> variableInfo,
- Type staticType,
- covariant Operations<Variable, Type> operations) {
- VariableModel<Type>? currentVariableInfo = variableInfo[promotionKey];
- if (currentVariableInfo == null) {
- return () => {};
- }
- return () {
- Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
- Type currentType = currentVariableInfo.promotedTypes?.last ??
- operations.variableType(variable);
- NonPromotionHistory? nonPromotionHistory =
- currentVariableInfo.nonPromotionHistory;
- while (nonPromotionHistory != null) {
- Type nonPromotedType = nonPromotionHistory.type;
- if (!operations.isSubtypeOf(currentType, nonPromotedType)) {
- result[nonPromotedType] ??= nonPromotionHistory.nonPromotionReason;
- }
- nonPromotionHistory = nonPromotionHistory.previous;
- }
- return result;
- };
- }
-
- @override
- String toString() => 'VariableReference($variable, $promotionKey)';
-}
-
class WhyNotPromotedInfo {}
/// [_FlowContext] representing an assert statement or assert initializer.
@@ -3526,8 +3451,7 @@
Set<int> implicitlyDeclaredVars = {...anywhere._read, ...anywhere._written};
implicitlyDeclaredVars.removeAll(anywhere._declared);
for (int variableKey in implicitlyDeclaredVars) {
- _current = _current.declare(
- _promotionKeyStore.variableForKey(variableKey), variableKey, true);
+ _current = _current.declare(variableKey, true);
}
}
@@ -3539,8 +3463,8 @@
ReferenceWithType<Type>? referenceWithType =
_getExpressionReference(subExpression);
if (referenceWithType == null) return;
- _current =
- _current.tryPromoteForTypeCast(operations, referenceWithType, type);
+ _current = _current.tryPromoteForTypeCast(
+ operations, referenceWithType, type, _promotionKeyStore);
}
@override
@@ -3613,7 +3537,7 @@
@override
void declare(Variable variable, bool initialized) {
_current = _current.declare(
- variable, _promotionKeyStore.keyForVariable(variable), initialized);
+ _promotionKeyStore.keyForVariable(variable), initialized);
}
@override
@@ -3676,14 +3600,14 @@
// either result is possible.
} else if (leftOperandInfo._expressionInfo is _NullInfo<Type> &&
rhsReference != null) {
- ExpressionInfo<Type> equalityInfo =
- _current.tryMarkNonNullable(operations, rhsReference);
+ ExpressionInfo<Type> equalityInfo = _current.tryMarkNonNullable(
+ operations, rhsReference, _promotionKeyStore);
_storeExpressionInfo(
wholeExpression, notEqual ? equalityInfo : equalityInfo.invert());
} else if (rightOperandInfo._expressionInfo is _NullInfo<Type> &&
lhsReference != null) {
- ExpressionInfo<Type> equalityInfo =
- _current.tryMarkNonNullable(operations, lhsReference);
+ ExpressionInfo<Type> equalityInfo = _current.tryMarkNonNullable(
+ operations, lhsReference, _promotionKeyStore);
_storeExpressionInfo(
wholeExpression, notEqual ? equalityInfo : equalityInfo.invert());
}
@@ -3821,8 +3745,8 @@
FlowModel<Type> promoted;
_current = _current.split();
if (lhsReference != null) {
- ExpressionInfo<Type> promotionInfo =
- _current.tryMarkNonNullable(operations, lhsReference);
+ ExpressionInfo<Type> promotionInfo = _current.tryMarkNonNullable(
+ operations, lhsReference, _promotionKeyStore);
_current = promotionInfo.ifFalse;
promoted = promotionInfo.ifTrue;
} else {
@@ -3893,10 +3817,10 @@
_current = _current
.tryPromoteForTypeCheck(
operations,
- new ReferenceWithType<Type>(
- new VariableReference<Variable, Type>(variable, variableKey),
+ new ReferenceWithType<Type>(variableKey,
promotedType(variable) ?? operations.variableType(variable)),
- initializerType)
+ initializerType,
+ _promotionKeyStore)
.ifTrue;
}
}
@@ -3915,7 +3839,7 @@
_getExpressionReference(subExpression);
if (subExpressionReference != null) {
ExpressionInfo<Type> expressionInfo = _current.tryPromoteForTypeCheck(
- operations, subExpressionReference, type);
+ operations, subExpressionReference, type, _promotionKeyStore);
_storeExpressionInfo(
isExpression, isNot ? expressionInfo.invert() : expressionInfo);
}
@@ -4011,8 +3935,9 @@
ReferenceWithType<Type>? operandReference =
_getExpressionReference(operand);
if (operandReference != null) {
- _current =
- _current.tryMarkNonNullable(operations, operandReference).ifTrue;
+ _current = _current
+ .tryMarkNonNullable(operations, operandReference, _promotionKeyStore)
+ .ifTrue;
}
}
@@ -4031,8 +3956,9 @@
_stack.add(new _NullAwareAccessContext<Type>(_current));
ReferenceWithType<Type>? targetReference = _getExpressionReference(target);
if (targetReference != null) {
- _current =
- _current.tryMarkNonNullable(operations, targetReference).ifTrue;
+ _current = _current
+ .tryMarkNonNullable(operations, targetReference, _promotionKeyStore)
+ .ifTrue;
}
}
@@ -4058,13 +3984,14 @@
@override
void propertyGet(Expression wholeExpression, Expression target,
String propertyName, Object? propertyMember, Type staticType) {
- Reference<Type>? reference = _getExpressionReference(target)?.reference;
- if (reference != null) {
+ int? targetKey = _getExpressionReference(target)?.promotionKey;
+ if (targetKey != null) {
_storeExpressionReference(
wholeExpression,
- new ReferenceWithType<Type>(
- reference.propertyGet(
- _promotionKeyStore, propertyName, propertyMember),
+ new _PropertyReferenceWithType<Type>(
+ propertyName,
+ propertyMember,
+ _promotionKeyStore.getProperty(targetKey, propertyName),
staticType));
}
}
@@ -4116,8 +4043,7 @@
_storeExpressionReference(
expression,
new ReferenceWithType<Type>(
- new _ThisReference<Type>(_promotionKeyStore.thisPromotionKey),
- staticType));
+ _promotionKeyStore.thisPromotionKey, staticType));
}
@override
@@ -4125,9 +4051,11 @@
Object? propertyMember, Type staticType) {
_storeExpressionReference(
expression,
- new ReferenceWithType<Type>(
- new _ThisReference<Type>(_promotionKeyStore.thisPromotionKey)
- .propertyGet(_promotionKeyStore, propertyName, propertyMember),
+ new _PropertyReferenceWithType<Type>(
+ propertyName,
+ propertyMember,
+ _promotionKeyStore.getProperty(
+ _promotionKeyStore.thisPromotionKey, propertyName),
staticType));
}
@@ -4160,14 +4088,12 @@
if (exceptionVariable != null) {
int exceptionVariableKey =
_promotionKeyStore.keyForVariable(exceptionVariable);
- _current =
- _current.declare(exceptionVariable, exceptionVariableKey, true);
+ _current = _current.declare(exceptionVariableKey, true);
}
if (stackTraceVariable != null) {
int stackTraceVariableKey =
_promotionKeyStore.keyForVariable(stackTraceVariable);
- _current =
- _current.declare(stackTraceVariable, stackTraceVariableKey, true);
+ _current = _current.declare(stackTraceVariableKey, true);
}
}
@@ -4210,14 +4136,11 @@
@override
Type? variableRead(Expression expression, Variable variable) {
int variableKey = _promotionKeyStore.keyForVariable(variable);
- VariableReference<Variable, Type> variableReference =
- new VariableReference<Variable, Type>(variable, variableKey);
- VariableModel<Type> variableModel =
- variableReference.getInfo(_current.variableInfo);
+ VariableModel<Type> variableModel = _current._getInfo(variableKey);
Type? promotedType = variableModel.promotedTypes?.last;
Type currentType = promotedType ?? operations.variableType(variable);
- _storeExpressionReference(expression,
- new ReferenceWithType<Type>(variableReference, currentType));
+ _storeExpressionReference(
+ expression, new ReferenceWithType<Type>(variableKey, currentType));
ExpressionInfo<Type>? expressionInfo = variableModel.ssaNode?.expressionInfo
?.rebaseForward(operations, _current);
if (expressionInfo != null) {
@@ -4256,8 +4179,12 @@
if (identical(target, _expressionWithReference)) {
ReferenceWithType<Type>? referenceWithType = _expressionReference;
if (referenceWithType != null) {
- return referenceWithType.reference.getNonPromotionReasons(
- _current.variableInfo, referenceWithType.type, operations);
+ VariableModel<Type>? currentVariableInfo =
+ _current.variableInfo[referenceWithType.promotionKey];
+ if (currentVariableInfo != null) {
+ return _getNonPromotionReasons(
+ referenceWithType, currentVariableInfo);
+ }
}
}
return () => {};
@@ -4266,8 +4193,15 @@
@override
Map<Type, NonPromotionReason> Function() whyNotPromotedImplicitThis(
Type staticType) {
- return new _ThisReference<Type>(_promotionKeyStore.thisPromotionKey)
- .getNonPromotionReasons(_current.variableInfo, staticType, operations);
+ VariableModel<Type>? currentThisInfo =
+ _current.variableInfo[_promotionKeyStore.thisPromotionKey];
+ if (currentThisInfo == null) {
+ return () => {};
+ }
+ return _getNonPromotionReasons(
+ new ReferenceWithType<Type>(
+ _promotionKeyStore.thisPromotionKey, staticType),
+ currentThisInfo);
}
@override
@@ -4335,6 +4269,57 @@
}
}
+ Map<Type, NonPromotionReason> Function() _getNonPromotionReasons(
+ ReferenceWithType<Type> reference,
+ VariableModel<Type> currentVariableInfo) {
+ if (reference is _PropertyReferenceWithType<Type>) {
+ List<Type>? promotedTypes = currentVariableInfo.promotedTypes;
+ if (promotedTypes != null) {
+ return () {
+ Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
+ for (Type type in promotedTypes) {
+ result[type] = new PropertyNotPromoted(reference.propertyName,
+ reference.propertyMember, reference.type);
+ }
+ return result;
+ };
+ }
+ } else {
+ Variable? variable =
+ _promotionKeyStore.variableForKey(reference.promotionKey);
+ if (variable == null) {
+ List<Type>? promotedTypes = currentVariableInfo.promotedTypes;
+ if (promotedTypes != null) {
+ return () {
+ Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
+ for (Type type in promotedTypes) {
+ result[type] = new ThisNotPromoted();
+ }
+ return result;
+ };
+ }
+ } else {
+ return () {
+ Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
+ Type currentType = currentVariableInfo.promotedTypes?.last ??
+ operations.variableType(variable);
+ NonPromotionHistory? nonPromotionHistory =
+ currentVariableInfo.nonPromotionHistory;
+ while (nonPromotionHistory != null) {
+ Type nonPromotedType = nonPromotionHistory.type;
+ if (!operations.isSubtypeOf(currentType, nonPromotedType)) {
+ result[nonPromotedType] ??=
+ nonPromotionHistory.nonPromotionReason;
+ }
+ nonPromotionHistory = nonPromotionHistory.previous;
+ }
+ return result;
+ };
+ }
+ }
+ return () => {};
+ }
+
FlowModel<Type> _join(FlowModel<Type>? first, FlowModel<Type>? second) =>
FlowModel.join(operations, first, second, _current._emptyVariableMap);
@@ -4991,41 +4976,24 @@
null;
}
-/// [Reference] object representing a property get applied to another reference.
-class _PropertyGetReference<Type extends Object> extends Reference<Type> {
+/// [ReferenceWithType] object representing a property get.
+class _PropertyReferenceWithType<Type extends Object>
+ extends ReferenceWithType<Type> {
/// The name of the property.
final String propertyName;
- /// The field or property being accessed. This matches a `propertyMember`
+ /// /// The field or property being accessed. This matches a `propertyMember`
/// value that was passed to either [FlowAnalysis.propertyGet] or
/// [FlowAnalysis.thisOrSuperPropertyGet].
final Object? propertyMember;
- _PropertyGetReference(
- this.propertyName, this.propertyMember, super.promotionKey);
-
- @override
- Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
- Map<int, VariableModel<Type>> variableInfo,
- Type staticType,
- TypeOperations<Type> typeOperations) {
- List<Type>? promotedTypes = _getInfo(variableInfo)?.promotedTypes;
- if (promotedTypes != null) {
- return () {
- Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
- for (Type type in promotedTypes) {
- result[type] =
- new PropertyNotPromoted(propertyName, propertyMember, staticType);
- }
- return result;
- };
- }
- return () => {};
- }
+ _PropertyReferenceWithType(
+ this.propertyName, this.propertyMember, super.promotionKey, super.type);
@override
String toString() =>
- '_PropertyGetReference($propertyName, $propertyMember, $promotionKey)';
+ '_PropertyReferenceWithType($propertyName, $propertyMember, '
+ '$promotionKey, $type)';
}
/// [_FlowContext] representing a language construct for which flow analysis
@@ -5061,29 +5029,6 @@
'checkpoint: $_checkpoint)';
}
-/// [Reference] object representing an implicit or explicit reference to `this`.
-class _ThisReference<Type extends Object> extends Reference<Type> {
- _ThisReference(super.promotionKey);
-
- @override
- Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
- Map<int, VariableModel<Type>> variableInfo,
- Type staticType,
- TypeOperations<Type> typeOperations) {
- List<Type>? promotedTypes = _getInfo(variableInfo)?.promotedTypes;
- if (promotedTypes != null) {
- return () {
- Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
- for (Type type in promotedTypes) {
- result[type] = new ThisNotPromoted();
- }
- return result;
- };
- }
- return () => {};
- }
-}
-
/// Specialization of [ExpressionInfo] for the case where the information we
/// have about the expression is trivial (meaning we know by construction that
/// the expression's [after], [ifTrue], and [ifFalse] models are all the same).
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
index d2195c0..e6ee94a 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
@@ -5923,21 +5923,21 @@
for (Var v in capturedVariables) _promotionKeyStore.keyForVariable(v)
]);
- FlowModel<Type> _declare(Var variable, bool initialized) => this.declare(
- variable, _promotionKeyStore.keyForVariable(variable), initialized);
+ FlowModel<Type> _declare(Var variable, bool initialized) =>
+ this.declare(_promotionKeyStore.keyForVariable(variable), initialized);
VariableModel<Type> _infoFor(Var variable) =>
infoFor(_promotionKeyStore.keyForVariable(variable));
ExpressionInfo<Type> _tryMarkNonNullable(Harness h, Var variable) =>
- tryMarkNonNullable(h, _varRefWithType(variable));
+ tryMarkNonNullable(h, _varRefWithType(variable), _promotionKeyStore);
ExpressionInfo<Type> _tryPromoteForTypeCheck(
Harness h, Var variable, String type) =>
- tryPromoteForTypeCheck(h, _varRefWithType(variable), Type(type));
+ tryPromoteForTypeCheck(
+ h, _varRefWithType(variable), Type(type), _promotionKeyStore);
- Reference<Type> _varRef(Var variable) => new VariableReference<Var, Type>(
- variable, _promotionKeyStore.keyForVariable(variable));
+ int _varRef(Var variable) => _promotionKeyStore.keyForVariable(variable);
ReferenceWithType<Type> _varRefWithType(Var variable) =>
new ReferenceWithType<Type>(
diff --git a/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart b/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart
index 5218d75..68b6ff4 100644
--- a/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart
@@ -2,7 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:analysis_server/src/protocol_server.dart' as protocol;
import 'package:analysis_server/src/search/element_references.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analyzer/dart/analysis/results.dart';
@@ -12,6 +11,7 @@
import 'package:analyzer/source/source_range.dart';
import 'package:analyzer/src/dart/ast/element_locator.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/element/element.dart';
/// A [CallHierarchyItem] and a set of ranges that call to or from it.
class CallHierarchyCalls {
@@ -45,30 +45,46 @@
final String file;
/// The range of the name at the declaration of this item.
- final SourceRange range;
+ final SourceRange nameRange;
- // TODO(dantup): This class will need to contain two ranges (codeRange +
- // selectionRange) for LSP.
+ /// The range of the code for the declaration of this item.
+ final SourceRange codeRange;
- CallHierarchyItem.forElement(
- Element element, {
- required this.range,
- }) : displayName = element is CompilationUnitElement
+ CallHierarchyItem.forElement(Element element)
+ : displayName = element is CompilationUnitElement
? element.source.shortName
: element is PropertyAccessorElement
? element.isGetter
? 'get ${element.displayName}'
: 'set ${element.displayName}'
: element.displayName,
+ nameRange = _nameRangeForElement(element),
+ codeRange = _codeRangeForElement(element),
file = element.source!.fullName,
kind = CallHierarchyKind.forElement(element);
- CallHierarchyItem.forProtocolElement(
- protocol.Element element, {
- required this.range,
- }) : displayName = element.name,
- file = element.location!.file,
- kind = CallHierarchyKind.forProtocolElement(element);
+ /// Returns the [SourceRange] of the code for [element].
+ static SourceRange _codeRangeForElement(Element element) {
+ // For synthetic items (like implicit constructors), use the nonSynthetic
+ // element for the location.
+ final elementImpl = element.nonSynthetic as ElementImpl;
+
+ // Non-synthetic elements should always have code locations.
+ return SourceRange(elementImpl.codeOffset!, elementImpl.codeLength!);
+ }
+
+ /// Returns the [SourceRange] of the name for [element].
+ static SourceRange _nameRangeForElement(Element element) {
+ // For synthetic items (like implicit constructors), use the nonSynthetic
+ // element for the location.
+ element = element.nonSynthetic;
+
+ // Compilation units will return -1 for nameOffset which is not valid, so
+ //use 0:0.
+ return element.nameOffset == -1
+ ? SourceRange(0, 0)
+ : SourceRange(element.nameOffset, element.nameLength);
+ }
}
/// Kinds of [CallHierarchyItem] that can make calls to other
@@ -95,23 +111,8 @@
ElementKind.SETTER: property,
};
- static const _protocolElementMapping = {
- protocol.ElementKind.CLASS: class_,
- protocol.ElementKind.COMPILATION_UNIT: file,
- protocol.ElementKind.CONSTRUCTOR: constructor,
- protocol.ElementKind.EXTENSION: extension,
- protocol.ElementKind.FUNCTION: function,
- protocol.ElementKind.GETTER: property,
- protocol.ElementKind.METHOD: method,
- protocol.ElementKind.MIXIN: mixin,
- protocol.ElementKind.SETTER: property,
- };
-
static CallHierarchyKind forElement(Element element) =>
_elementMapping[element.kind] ?? unknown;
-
- static CallHierarchyKind forProtocolElement(protocol.Element element) =>
- _protocolElementMapping[element.kind] ?? unknown;
}
/// A computer for Call Hierarchies.
@@ -143,7 +144,7 @@
SearchEngine searchEngine,
) async {
assert(target.file == _result.path);
- final node = _findTargetNode(target.range.offset);
+ final node = _findTargetNode(target.nameRange.offset);
var element = _getElementOfNode(node);
if (element == null) {
return [];
@@ -169,12 +170,12 @@
// Group results by their container, since we only want to return a single
// entry for a body, with a set of ranges within.
- final resultsByContainer = <protocol.Element, CallHierarchyCalls>{};
+ final resultsByContainer = <Element, CallHierarchyCalls>{};
// We may need to fetch parsed results for the other files, reuse them
// across calls.
final parsedUnits = <String, SomeParsedUnitResult?>{};
for (final reference in references) {
- final container = _getContainer(reference.path);
+ final container = _getContainer(reference.element);
if (container == null) {
continue;
}
@@ -182,14 +183,11 @@
// Create an item for a container the first time we see it.
final containerCalls = resultsByContainer.putIfAbsent(
container,
- () => CallHierarchyCalls(CallHierarchyItem.forProtocolElement(
- container,
- range: _rangeForProtocolElement(container),
- )),
+ () => CallHierarchyCalls(CallHierarchyItem.forElement(container)),
);
// Add this match to the containers results.
- final range = _rangeForSearchResult(reference, parsedUnits);
+ final range = _rangeForSearchMatch(reference, parsedUnits);
containerCalls.ranges.add(range);
}
@@ -202,7 +200,7 @@
CallHierarchyItem target,
) async {
assert(target.file == _result.path);
- final node = _findTargetNode(target.range.offset);
+ final node = _findTargetNode(target.nameRange.offset);
if (node == null) {
return [];
}
@@ -229,10 +227,7 @@
// Create an item for a target the first time we see it.
final calls = resultsByTarget.putIfAbsent(
target,
- () => CallHierarchyCalls(CallHierarchyItem.forElement(
- target,
- range: _rangeForElement(target),
- )),
+ () => CallHierarchyCalls(CallHierarchyItem.forElement(target)),
);
// Add this call to the targets results.
@@ -253,8 +248,7 @@
// We only return targets that are executable elements.
return element is ExecutableElement
- ? CallHierarchyItem.forElement(element,
- range: _rangeForElement(element))
+ ? CallHierarchyItem.forElement(element)
: null;
}
@@ -289,23 +283,26 @@
return node;
}
- /// Returns the enclosing element (class, function body, compliation unit) for
- /// the reference [element].
+ /// Returns the container for [element] that should be used in Call Hierarchy.
+ ///
+ /// Returns `null` if none of [elements] are valid containers.
///
/// This is used to construct (and group calls by) a [CallHierarchyItem] that
/// contains calls.
- protocol.Element? _getContainer(List<protocol.Element> elements) {
- return elements.firstWhere((parent) =>
- parent.kind == protocol.ElementKind.CLASS ||
- parent.kind == protocol.ElementKind.COMPILATION_UNIT ||
- parent.kind == protocol.ElementKind.CONSTRUCTOR ||
- parent.kind == protocol.ElementKind.ENUM ||
- parent.kind == protocol.ElementKind.EXTENSION ||
- parent.kind == protocol.ElementKind.FUNCTION ||
- parent.kind == protocol.ElementKind.GETTER ||
- parent.kind == protocol.ElementKind.METHOD ||
- parent.kind == protocol.ElementKind.MIXIN ||
- parent.kind == protocol.ElementKind.SETTER);
+ Element? _getContainer(Element element) {
+ const containerKinds = {
+ ElementKind.CLASS,
+ ElementKind.COMPILATION_UNIT,
+ ElementKind.CONSTRUCTOR,
+ ElementKind.ENUM,
+ ElementKind.EXTENSION,
+ ElementKind.FUNCTION,
+ ElementKind.GETTER,
+ ElementKind.METHOD,
+ ElementKind.SETTER,
+ };
+ return element.thisOrAncestorMatching(
+ (ancestor) => containerKinds.contains(ancestor.kind));
}
/// Return the [Element] of the given [node], or `null` if [node] is `null`,
@@ -338,17 +335,6 @@
return element;
}
- /// Returns the [SourceRange] to use for [element].
- ///
- /// The returned range covers only the name of the target and does not include
- /// any parameter list.
- SourceRange _rangeForElement(Element element) {
- // For synthetic items (like implicit constructors), use the nonSynthetic
- // element for the location.
- element = element.nonSynthetic;
- return SourceRange(element.nameOffset, element.nameLength);
- }
-
/// Returns the [SourceRange] to use for [node].
///
/// The returned range covers only the name of the target and does not include
@@ -373,14 +359,6 @@
return SourceRange(node.offset, node.length);
}
- /// Returns the [SourceRange] to use for [element].
- ///
- /// The returned range covers only the name of the target and does not include
- /// any parameter list.
- SourceRange _rangeForProtocolElement(protocol.Element element) {
- return SourceRange(element.location!.offset, element.location!.length);
- }
-
/// Returns the [SourceRange] for [match].
///
/// Usually this is the range returned from the search index, but sometimes it
@@ -388,13 +366,13 @@
/// for this call. For example, an unnamed constructor may be given a range
/// covering the type name (whereas the index has a zero-width range after the
/// type name).
- SourceRange _rangeForSearchResult(
- protocol.SearchResult match,
+ SourceRange _rangeForSearchMatch(
+ SearchMatch match,
Map<String, SomeParsedUnitResult?> parsedUnits,
) {
- var offset = match.location.offset;
- var length = match.location.length;
- final file = match.location.file;
+ var offset = match.sourceRange.offset;
+ var length = match.sourceRange.length;
+ final file = match.file;
final result = parsedUnits.putIfAbsent(
file,
() => _result.session.getParsedUnit(file),
diff --git a/pkg/analysis_server/lib/src/handler/legacy/search_find_element_references.dart b/pkg/analysis_server/lib/src/handler/legacy/search_find_element_references.dart
index a0bdfbb..d6effb9 100644
--- a/pkg/analysis_server/lib/src/handler/legacy/search_find_element_references.dart
+++ b/pkg/analysis_server/lib/src/handler/legacy/search_find_element_references.dart
@@ -7,6 +7,7 @@
import 'package:analysis_server/plugin/protocol/protocol_dart.dart' as protocol;
import 'package:analysis_server/protocol/protocol_generated.dart' as protocol;
import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
+import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/search/element_references.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -48,8 +49,8 @@
if (element != null) {
var computer = ElementReferencesComputer(searchEngine);
var results = await computer.compute(element, params.includePotential);
- sendSearchResults(
- protocol.SearchResultsParams(searchId, results.toList(), true));
+ sendSearchResults(protocol.SearchResultsParams(
+ searchId, results.map(newSearchResult_fromMatch).toList(), true));
}
}
}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
index 07fd4ff..2fe9d4d 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
@@ -5,9 +5,10 @@
import 'package:analysis_server/lsp_protocol/protocol.dart';
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
-import 'package:analysis_server/src/protocol_server.dart' show SearchResult;
import 'package:analysis_server/src/protocol_server.dart' show NavigationTarget;
import 'package:analysis_server/src/search/element_references.dart';
+import 'package:analysis_server/src/services/search/search_engine.dart'
+ show SearchMatch;
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -70,11 +71,22 @@
}
final computer = ElementReferencesComputer(server.searchEngine);
+ final session = element.session ?? unit.session;
final results = await computer.compute(element, false);
- Location? toLocation(SearchResult result) {
- final lineInfo = server.getLineInfo(result.location.file);
- return searchResultToLocation(result, lineInfo);
+ Location? toLocation(SearchMatch result) {
+ final file = session.getFile(result.file);
+ if (file is! FileResult) {
+ return null;
+ }
+ return Location(
+ uri: Uri.file(result.file).toString(),
+ range: toRange(
+ file.lineInfo,
+ result.sourceRange.offset,
+ result.sourceRange.length,
+ ),
+ );
}
final referenceResults =
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index a3c3c99..7e2c591 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -891,20 +891,6 @@
/// 0 -> 9999999 - 0 -> 9 999 999
String relevanceToSortText(int relevance) => (9999999 - relevance).toString();
-lsp.Location? searchResultToLocation(
- server.SearchResult result, server.LineInfo? lineInfo) {
- final location = result.location;
-
- if (lineInfo == null) {
- return null;
- }
-
- return lsp.Location(
- uri: Uri.file(result.location.file).toString(),
- range: toRange(lineInfo, location.offset, location.length),
- );
-}
-
/// Creates a SnippetTextEdit for a set of edits using Linked Edit Groups.
///
/// Edit groups offsets are based on the entire content being modified after all
diff --git a/pkg/analysis_server/lib/src/search/element_references.dart b/pkg/analysis_server/lib/src/search/element_references.dart
index f843776..afccf67 100644
--- a/pkg/analysis_server/lib/src/search/element_references.dart
+++ b/pkg/analysis_server/lib/src/search/element_references.dart
@@ -14,10 +14,9 @@
ElementReferencesComputer(this.searchEngine);
- /// Computes [SearchResult]s for [element] references.
- Future<List<SearchResult>> compute(
- Element element, bool withPotential) async {
- var results = <SearchResult>[];
+ /// Computes [SearchMatch]es for [element] references.
+ Future<List<SearchMatch>> compute(Element element, bool withPotential) async {
+ var results = <SearchMatch>[];
// Add element references.
results.addAll(await _findElementsReferences(element));
@@ -26,7 +25,7 @@
if (withPotential && _isMemberElement(element)) {
var name = element.displayName;
var matches = await searchEngine.searchMemberReferences(name);
- results.addAll(matches.where((match) => !match.isResolved).map(toResult));
+ results.addAll(matches.where((match) => !match.isResolved));
}
return results;
@@ -34,8 +33,8 @@
/// Returns a [Future] completing with a [List] of references to [element] or
/// to the corresponding hierarchy [Element]s.
- Future<List<SearchResult>> _findElementsReferences(Element element) async {
- var allResults = <SearchResult>[];
+ Future<List<SearchMatch>> _findElementsReferences(Element element) async {
+ var allResults = <SearchMatch>[];
var refElements = await _getRefElements(element);
for (var refElement in refElements) {
var elementResults = await _findSingleElementReferences(refElement);
@@ -45,10 +44,9 @@
}
/// Returns a [Future] completing with a [List] of references to [element].
- Future<List<SearchResult>> _findSingleElementReferences(
+ Future<List<SearchMatch>> _findSingleElementReferences(
Element element) async {
- var matches = await searchEngine.searchReferences(element);
- return matches.map(toResult).toList();
+ return searchEngine.searchReferences(element);
}
/// Returns a [Future] completing with [Element]s to search references to.
diff --git a/pkg/analysis_server/test/src/computer/call_hierarchy_computer_test.dart b/pkg/analysis_server/test/src/computer/call_hierarchy_computer_test.dart
index 6bc39cc..20e6cda 100644
--- a/pkg/analysis_server/test/src/computer/call_hierarchy_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/call_hierarchy_computer_test.dart
@@ -21,24 +21,34 @@
}
/// Matches a [CallHierarchyItem] with the given name/kind/file.
-Matcher _isItem(CallHierarchyKind kind, String displayName, String file,
- SourceRange range) =>
+Matcher _isItem(
+ CallHierarchyKind kind,
+ String displayName,
+ String file, {
+ required SourceRange nameRange,
+ required SourceRange codeRange,
+}) =>
TypeMatcher<CallHierarchyItem>()
.having((e) => e.kind, 'kind', kind)
.having((e) => e.displayName, 'displayName', displayName)
.having((e) => e.file, 'file', file)
- .having((e) => e.range, 'range', range);
+ .having((e) => e.nameRange, 'nameRange', nameRange)
+ .having((e) => e.codeRange, 'codeRange', codeRange);
/// Matches a [CallHierarchyCalls] result with the given element/ranges.
Matcher _isResult(
CallHierarchyKind kind,
String displayName,
- String file,
- SourceRange range, {
+ String file, {
+ required SourceRange nameRange,
+ required SourceRange codeRange,
List<SourceRange>? ranges,
}) {
- var matcher = TypeMatcher<CallHierarchyCalls>()
- .having((c) => c.item, 'item', _isItem(kind, displayName, file, range));
+ var matcher = TypeMatcher<CallHierarchyCalls>().having(
+ (c) => c.item,
+ 'item',
+ _isItem(kind, displayName, file,
+ nameRange: nameRange, codeRange: codeRange));
if (ranges != null) {
matcher = matcher.having((c) => c.ranges, 'ranges', ranges);
@@ -50,6 +60,10 @@
abstract class AbstractCallHierarchyTest extends AbstractSingleUnitTest {
final startOfFile = SourceRange(0, 0);
+ /// Gets the entire range for [code].
+ SourceRange entireRange(String code) =>
+ SourceRange(0, withoutMarkers(code).length);
+
// Gets the expected range that follows the string [prefix] in [code] with a
// length of [match.length].
SourceRange rangeAfterPrefix(String prefix, String code, String match) =>
@@ -64,6 +78,18 @@
return SourceRange(index, (match ?? search).length);
}
+ // Gets the code range between markers in the form `/*1*/` where `1` is
+ // [number].
+ SourceRange rangeNumbered(int number, String code) {
+ code = withoutMarkers(code);
+ final marker = '/*$number*/';
+ final start = code.indexOf(marker) + marker.length;
+ final end = code.lastIndexOf(marker);
+ expect(start, greaterThanOrEqualTo(0 + marker.length));
+ expect(end, greaterThan(start));
+ return SourceRange(start, end - start);
+ }
+
String withoutMarkers(String code) => code.replaceAll('^', '');
}
@@ -111,7 +137,7 @@
Future<void> test_constructor() async {
final contents = '''
class Foo {
- Fo^o(String a) {}
+ /*1*/Fo^o(String a) {}/*1*/
}
''';
@@ -122,7 +148,8 @@
CallHierarchyKind.constructor,
'Foo',
testFile,
- rangeAtSearch('Foo(', contents, 'Foo'),
+ nameRange: rangeAtSearch('Foo(', contents, 'Foo'),
+ codeRange: rangeNumbered(1, contents),
),
);
}
@@ -131,14 +158,14 @@
final contents = '''
import 'other.dart';
-f() {
+void f() {
final foo = Fo^o();
}
''';
final otherContents = '''
class Foo {
- Foo();
+ /*1*/Foo();/*1*/
}
''';
@@ -149,14 +176,15 @@
CallHierarchyKind.constructor,
'Foo',
otherFile,
- rangeAtSearch('Foo(', otherContents, 'Foo'),
+ nameRange: rangeAtSearch('Foo(', otherContents, 'Foo'),
+ codeRange: rangeNumbered(1, otherContents),
));
}
Future<void> test_extension_method() async {
final contents = '''
extension StringExtension on String {
- void myMet^hod() {}
+ /*1*/void myMet^hod() {}/*1*/
}
''';
@@ -166,7 +194,8 @@
CallHierarchyKind.method,
'myMethod',
testFile,
- rangeAtSearch('myMethod', contents),
+ nameRange: rangeAtSearch('myMethod', contents),
+ codeRange: rangeNumbered(1, contents),
));
}
@@ -174,14 +203,14 @@
final contents = '''
import 'other.dart';
-f() {
+void f() {
''.myMet^hod();
}
''';
final otherContents = '''
extension StringExtension on String {
- void myMethod() {}
+ /*1*/void myMethod() {}/*1*/
}
''';
@@ -192,13 +221,14 @@
CallHierarchyKind.method,
'myMethod',
otherFile,
- rangeAtSearch('myMethod', otherContents),
+ nameRange: rangeAtSearch('myMethod', otherContents),
+ codeRange: rangeNumbered(1, otherContents),
));
}
Future<void> test_function() async {
final contents = '''
-void myFun^ction() {}
+/*1*/void myFun^ction() {}/*1*/
''';
await expectTarget(
@@ -207,7 +237,8 @@
CallHierarchyKind.function,
'myFunction',
testFile,
- rangeAtSearch('myFunction', contents),
+ nameRange: rangeAtSearch('myFunction', contents),
+ codeRange: rangeNumbered(1, contents),
));
}
@@ -215,13 +246,13 @@
final contents = '''
import 'other.dart' as f;
-f() {
+void f() {
f.myFun^ction();
}
''';
final otherContents = '''
-void myFunction() {}
+/*1*/void myFunction() {}/*1*/
''';
addSource(otherFile, otherContents);
@@ -231,14 +262,15 @@
CallHierarchyKind.function,
'myFunction',
otherFile,
- rangeAtSearch('myFunction', otherContents),
+ nameRange: rangeAtSearch('myFunction', otherContents),
+ codeRange: rangeNumbered(1, otherContents),
));
}
Future<void> test_getter() async {
final contents = '''
class Foo {
- String get fo^o => '';
+ /*1*/String get fo^o => '';/*1*/
}
''';
@@ -248,7 +280,8 @@
CallHierarchyKind.property,
'get foo',
testFile,
- rangeAtSearch('foo', contents),
+ nameRange: rangeAtSearch('foo', contents),
+ codeRange: rangeNumbered(1, contents),
));
}
@@ -256,13 +289,13 @@
final contents = '''
import 'other.dart';
-f() {
+void f() {
final foo = ba^r;
}
''';
final otherContents = '''
-String get bar => '';
+/*1*/String get bar => '';/*1*/
''';
addSource(otherFile, otherContents);
@@ -272,7 +305,8 @@
CallHierarchyKind.property,
'get bar',
otherFile,
- rangeAtSearch('bar', otherContents),
+ nameRange: rangeAtSearch('bar', otherContents),
+ codeRange: rangeNumbered(1, otherContents),
));
}
@@ -283,13 +317,13 @@
final contents = '''
import 'other.dart';
-f() {
+void f() {
final foo = Fo^o();
}
''';
final otherContents = '''
-class Foo {}
+/*1*/class Foo {}/*1*/
''';
addSource(otherFile, otherContents);
@@ -299,14 +333,15 @@
CallHierarchyKind.constructor,
'Foo',
otherFile,
- rangeAtSearch('Foo {', otherContents, 'Foo'),
+ nameRange: rangeAtSearch('Foo {', otherContents, 'Foo'),
+ codeRange: rangeNumbered(1, otherContents),
));
}
Future<void> test_method() async {
final contents = '''
class Foo {
- void myMet^hod() {}
+ /*1*/void myMet^hod() {}/*1*/
}
''';
@@ -316,7 +351,8 @@
CallHierarchyKind.method,
'myMethod',
testFile,
- rangeAtSearch('myMethod', contents),
+ nameRange: rangeAtSearch('myMethod', contents),
+ codeRange: rangeNumbered(1, contents),
));
}
@@ -324,14 +360,14 @@
final contents = '''
import 'other.dart';
-f() {
+void f() {
Foo().myMet^hod();
}
''';
final otherContents = '''
class Foo {
- void myMethod() {}
+ /*1*/void myMethod() {}/*1*/
}
''';
@@ -342,14 +378,15 @@
CallHierarchyKind.method,
'myMethod',
otherFile,
- rangeAtSearch('myMethod', otherContents),
+ nameRange: rangeAtSearch('myMethod', otherContents),
+ codeRange: rangeNumbered(1, otherContents),
));
}
Future<void> test_mixin_method() async {
final contents = '''
mixin Bar {
- void myMet^hod() {}
+ /*1*/void myMet^hod() {}/*1*/
}
''';
@@ -359,7 +396,8 @@
CallHierarchyKind.method,
'myMethod',
testFile,
- rangeAtSearch('myMethod', contents),
+ nameRange: rangeAtSearch('myMethod', contents),
+ codeRange: rangeNumbered(1, contents),
));
}
@@ -367,14 +405,14 @@
final contents = '''
import 'other.dart';
-f() {
+void f() {
Foo().myMet^hod();
}
''';
final otherContents = '''
class Bar {
- void myMethod() {}
+ /*1*/void myMethod() {}/*1*/
}
class Foo with Bar {}
@@ -387,14 +425,15 @@
CallHierarchyKind.method,
'myMethod',
otherFile,
- rangeAtSearch('myMethod', otherContents),
+ nameRange: rangeAtSearch('myMethod', otherContents),
+ codeRange: rangeNumbered(1, otherContents),
));
}
Future<void> test_namedConstructor() async {
final contents = '''
class Foo {
- Foo.Ba^r(String a) {}
+ /*1*/Foo.Ba^r(String a) {}/*1*/
}
''';
@@ -404,7 +443,8 @@
CallHierarchyKind.constructor,
'Foo.Bar',
testFile,
- rangeAtSearch('Bar', contents),
+ nameRange: rangeAtSearch('Bar', contents),
+ codeRange: rangeNumbered(1, contents),
));
}
@@ -422,14 +462,14 @@
final contents = '''
import 'other.dart';
-f() {
+void f() {
final foo = Foo.Ba^r();
}
''';
final otherContents = '''
class Foo {
- Foo.Bar();
+ /*1*/Foo.Bar();/*1*/
}
''';
@@ -440,7 +480,8 @@
CallHierarchyKind.constructor,
'Foo.Bar',
otherFile,
- rangeAtSearch('Bar', otherContents),
+ nameRange: rangeAtSearch('Bar', otherContents),
+ codeRange: rangeNumbered(1, otherContents),
));
}
@@ -448,7 +489,7 @@
final contents = '''
import 'other.dart';
-f() {
+void f() {
final foo = Fo^o.Bar();
}
''';
@@ -466,7 +507,7 @@
Future<void> test_setter() async {
final contents = '''
class Foo {
- set fo^o(Strin value) {};
+ /*1*/set fo^o(String value) {}/*1*/
}
''';
@@ -476,7 +517,8 @@
CallHierarchyKind.property,
'set foo',
testFile,
- rangeAtSearch('foo', contents),
+ nameRange: rangeAtSearch('foo', contents),
+ codeRange: rangeNumbered(1, contents),
));
}
@@ -484,13 +526,13 @@
final contents = '''
import 'other.dart';
-f() {
+void f() {
ba^r = '';
}
''';
final otherContents = '''
-set bar(String value) {}
+/*1*/set bar(String value) {}/*1*/
''';
addSource(otherFile, otherContents);
@@ -500,12 +542,13 @@
CallHierarchyKind.property,
'set bar',
otherFile,
- rangeAtSearch('bar', otherContents),
+ nameRange: rangeAtSearch('bar', otherContents),
+ codeRange: rangeNumbered(1, otherContents),
));
}
Future<void> test_whitespace() async {
- await expectNoTarget(' ^ f() {}');
+ await expectNoTarget(' ^ void f() {}');
}
}
@@ -556,17 +599,17 @@
import 'test.dart';
final foo1 = Foo();
-class Bar {
+/*1*/class Bar {
final foo2 = Foo();
- Foo get foo3 => Foo();
- Bar() {
+ /*2*/Foo get foo3 => Foo();/*2*/
+ /*3*/Bar() {
final foo4 = Foo();
- }
- void bar() {
+ }/*3*/
+ /*4*/void bar() {
final foo5 = Foo();
final foo6 = Foo();
- }
-}
+ }/*4*/
+}/*1*/
''';
// Gets the expected range that follows the string [prefix].
@@ -578,27 +621,33 @@
expect(
calls,
unorderedEquals([
- _isResult(CallHierarchyKind.file, 'other.dart', otherFile, startOfFile,
+ _isResult(CallHierarchyKind.file, 'other.dart', otherFile,
+ nameRange: startOfFile,
+ codeRange: entireRange(otherContents),
ranges: [
rangeAfter('foo1 = '),
]),
_isResult(CallHierarchyKind.class_, 'Bar', otherFile,
- rangeAtSearch('Bar {', otherContents, 'Bar'),
+ nameRange: rangeAtSearch('Bar {', otherContents, 'Bar'),
+ codeRange: rangeNumbered(1, otherContents),
ranges: [
rangeAfter('foo2 = '),
]),
- _isResult(CallHierarchyKind.property, 'foo3', otherFile,
- rangeAtSearch('foo3', otherContents),
+ _isResult(CallHierarchyKind.property, 'get foo3', otherFile,
+ nameRange: rangeAtSearch('foo3', otherContents),
+ codeRange: rangeNumbered(2, otherContents),
ranges: [
rangeAfter('foo3 => '),
]),
_isResult(CallHierarchyKind.constructor, 'Bar', otherFile,
- rangeAtSearch('Bar() {', otherContents, 'Bar'),
+ nameRange: rangeAtSearch('Bar() {', otherContents, 'Bar'),
+ codeRange: rangeNumbered(3, otherContents),
ranges: [
rangeAfter('foo4 = '),
]),
_isResult(CallHierarchyKind.method, 'bar', otherFile,
- rangeAtSearch('bar() {', otherContents, 'bar'),
+ nameRange: rangeAtSearch('bar() {', otherContents, 'bar'),
+ codeRange: rangeNumbered(4, otherContents),
ranges: [
rangeAfter('foo5 = '),
rangeAfter('foo6 = '),
@@ -617,9 +666,9 @@
final otherContents = '''
import 'test.dart';
-void f() {
+/*1*/void f() {
''.myMethod();
-}
+}/*1*/
''';
// Gets the expected range that follows the string [prefix].
@@ -632,7 +681,8 @@
calls,
unorderedEquals([
_isResult(CallHierarchyKind.function, 'f', otherFile,
- rangeAtSearch('f() {', otherContents, 'f'),
+ nameRange: rangeAtSearch('f() {', otherContents, 'f'),
+ codeRange: rangeNumbered(1, otherContents),
ranges: [
rangeAfter("''."),
]),
@@ -650,17 +700,17 @@
final foo1 = myFunction();
-class Bar {
+/*1*/class Bar {
final foo2 = myFunction();
- String get foo3 => myFunction();
- Bar() {
+ /*2*/String get foo3 => myFunction();/*2*/
+ /*3*/Bar() {
final foo4 = myFunction();
- }
- void bar() {
+ }/*3*/
+ /*4*/void bar() {
final foo5 = myFunction();
final foo6 = myFunction();
- }
-}
+ }/*4*/
+}/*1*/
''';
// Gets the expected range that follows the string [prefix].
@@ -672,27 +722,33 @@
expect(
calls,
unorderedEquals([
- _isResult(CallHierarchyKind.file, 'other.dart', otherFile, startOfFile,
+ _isResult(CallHierarchyKind.file, 'other.dart', otherFile,
+ nameRange: startOfFile,
+ codeRange: entireRange(otherContents),
ranges: [
rangeAfter('foo1 = '),
]),
_isResult(CallHierarchyKind.class_, 'Bar', otherFile,
- rangeAtSearch('Bar {', otherContents, 'Bar'),
+ nameRange: rangeAtSearch('Bar {', otherContents, 'Bar'),
+ codeRange: rangeNumbered(1, otherContents),
ranges: [
rangeAfter('foo2 = '),
]),
- _isResult(CallHierarchyKind.property, 'foo3', otherFile,
- rangeAtSearch('foo3', otherContents),
+ _isResult(CallHierarchyKind.property, 'get foo3', otherFile,
+ nameRange: rangeAtSearch('foo3', otherContents),
+ codeRange: rangeNumbered(2, otherContents),
ranges: [
rangeAfter('foo3 => '),
]),
_isResult(CallHierarchyKind.constructor, 'Bar', otherFile,
- rangeAtSearch('Bar() {', otherContents, 'Bar'),
+ nameRange: rangeAtSearch('Bar() {', otherContents, 'Bar'),
+ codeRange: rangeNumbered(3, otherContents),
ranges: [
rangeAfter('foo4 = '),
]),
_isResult(CallHierarchyKind.method, 'bar', otherFile,
- rangeAtSearch('bar() {', otherContents, 'bar'),
+ nameRange: rangeAtSearch('bar() {', otherContents, 'bar'),
+ codeRange: rangeNumbered(4, otherContents),
ranges: [
rangeAfter('foo5 = '),
rangeAfter('foo6 = '),
@@ -710,17 +766,17 @@
import 'test.dart';
final foo1 = foo;
-class Bar {
+/*1*/class Bar {
final foo2 = foo;
- Foo get foo3 => foo;
- Bar() {
+ /*2*/Foo get foo3 => foo;/*2*/
+ /*3*/Bar() {
final foo4 = foo;
- }
- void bar() {
+ }/*3*/
+ /*4*/void bar() {
final foo5 = foo;
final foo6 = foo;
- }
-}
+ }/*4*/
+}/*1*/
''';
// Gets the expected range that follows the string [prefix].
@@ -732,27 +788,33 @@
expect(
calls,
unorderedEquals([
- _isResult(CallHierarchyKind.file, 'other.dart', otherFile, startOfFile,
+ _isResult(CallHierarchyKind.file, 'other.dart', otherFile,
+ nameRange: startOfFile,
+ codeRange: entireRange(otherContents),
ranges: [
rangeAfter('foo1 = '),
]),
_isResult(CallHierarchyKind.class_, 'Bar', otherFile,
- rangeAtSearch('Bar {', otherContents, 'Bar'),
+ nameRange: rangeAtSearch('Bar {', otherContents, 'Bar'),
+ codeRange: rangeNumbered(1, otherContents),
ranges: [
rangeAfter('foo2 = '),
]),
- _isResult(CallHierarchyKind.property, 'foo3', otherFile,
- rangeAtSearch('foo3', otherContents),
+ _isResult(CallHierarchyKind.property, 'get foo3', otherFile,
+ nameRange: rangeAtSearch('foo3', otherContents),
+ codeRange: rangeNumbered(2, otherContents),
ranges: [
rangeAfter('foo3 => '),
]),
_isResult(CallHierarchyKind.constructor, 'Bar', otherFile,
- rangeAtSearch('Bar() {', otherContents, 'Bar'),
+ nameRange: rangeAtSearch('Bar() {', otherContents, 'Bar'),
+ codeRange: rangeNumbered(3, otherContents),
ranges: [
rangeAfter('foo4 = '),
]),
_isResult(CallHierarchyKind.method, 'bar', otherFile,
- rangeAtSearch('bar() {', otherContents, 'bar'),
+ nameRange: rangeAtSearch('bar() {', otherContents, 'bar'),
+ codeRange: rangeNumbered(4, otherContents),
ranges: [
rangeAfter('foo5 = '),
rangeAfter('foo6 = '),
@@ -768,9 +830,9 @@
// ignore_for_file: unused_local_variable
import 'other.dart';
-f() {
+/*1*/void f() {
final foo1 = Fo^o();
-}
+}/*1*/
''';
final otherContents = '''
@@ -789,11 +851,14 @@
calls,
unorderedEquals([
_isResult(CallHierarchyKind.function, 'f', testFile,
- rangeAtSearch('f() {', contents, 'f'),
+ nameRange: rangeAtSearch('f() {', contents, 'f'),
+ codeRange: rangeNumbered(1, contents),
ranges: [
rangeAfter('foo1 = ', contents),
]),
- _isResult(CallHierarchyKind.file, 'other.dart', otherFile, startOfFile,
+ _isResult(CallHierarchyKind.file, 'other.dart', otherFile,
+ nameRange: startOfFile,
+ codeRange: entireRange(otherContents),
ranges: [
rangeAfter('foo2 = ', otherContents),
]),
@@ -811,10 +876,10 @@
final otherContents = '''
import 'test.dart';
-void f() {
+/*1*/void f() {
Foo().myMethod();
final tearoff = Foo().myMethod;
-}
+}/*1*/
''';
// Gets the expected range that follows the string [prefix].
@@ -827,7 +892,8 @@
calls,
unorderedEquals([
_isResult(CallHierarchyKind.function, 'f', otherFile,
- rangeAtSearch('f() {', otherContents, 'f'),
+ nameRange: rangeAtSearch('f() {', otherContents, 'f'),
+ codeRange: rangeNumbered(1, otherContents),
ranges: [
rangeAfter('Foo().'),
rangeAfter('tearoff = Foo().'),
@@ -848,9 +914,9 @@
final otherContents = '''
import 'test.dart';
-void f() {
+/*1*/void f() {
Foo().myMethod();
-}
+}/*1*/
''';
// Gets the expected range that follows the string [prefix].
@@ -863,7 +929,8 @@
calls,
unorderedEquals([
_isResult(CallHierarchyKind.function, 'f', otherFile,
- rangeAtSearch('f() {', otherContents, 'f'),
+ nameRange: rangeAtSearch('f() {', otherContents, 'f'),
+ codeRange: rangeNumbered(1, otherContents),
ranges: [
rangeAfter('Foo().'),
]),
@@ -881,9 +948,9 @@
final otherContents = '''
import 'test.dart';
-f() {
+/*1*/void f() {
final foo = Foo.Bar();
-}
+}/*1*/
''';
// Gets the expected range that follows the string [prefix].
@@ -896,7 +963,8 @@
calls,
unorderedEquals([
_isResult(CallHierarchyKind.function, 'f', otherFile,
- rangeAtSearch('f() {', otherContents, 'f'),
+ nameRange: rangeAtSearch('f() {', otherContents, 'f'),
+ codeRange: rangeNumbered(1, otherContents),
ranges: [
rangeAfter('foo = Foo.'),
]),
@@ -913,13 +981,13 @@
import 'test.dart';
class Bar {
- Bar() {
- /*1*/foo = '';
- }
- void bar() {
- /*2*/foo = '';
- /*3*/foo = '';
- }
+ /*1*/Bar() {
+ /*a*/foo = '';
+ }/*1*/
+ /*2*/void bar() {
+ /*b*/foo = '';
+ /*c*/foo = '';
+ }/*2*/
}
''';
@@ -933,15 +1001,17 @@
calls,
unorderedEquals([
_isResult(CallHierarchyKind.constructor, 'Bar', otherFile,
- rangeAtSearch('Bar() {', otherContents, 'Bar'),
+ nameRange: rangeAtSearch('Bar() {', otherContents, 'Bar'),
+ codeRange: rangeNumbered(1, otherContents),
ranges: [
- rangeAfter('/*1*/'),
+ rangeAfter('/*a*/'),
]),
_isResult(CallHierarchyKind.method, 'bar', otherFile,
- rangeAtSearch('bar() {', otherContents, 'bar'),
+ nameRange: rangeAtSearch('bar() {', otherContents, 'bar'),
+ codeRange: rangeNumbered(2, otherContents),
ranges: [
- rangeAfter('/*2*/'),
- rangeAfter('/*3*/'),
+ rangeAfter('/*b*/'),
+ rangeAfter('/*c*/'),
]),
]),
);
@@ -997,11 +1067,11 @@
final otherContents = '''
class A {
- A();
+ /*1*/A();/*1*/
}
-class B {
-}
+/*2*/class B {
+}/*2*/
''';
addSource(otherFile, otherContents);
@@ -1010,13 +1080,15 @@
calls,
unorderedEquals([
_isResult(CallHierarchyKind.constructor, 'A', otherFile,
- rangeAtSearch('A();', otherContents, 'A'),
+ nameRange: rangeAtSearch('A();', otherContents, 'A'),
+ codeRange: rangeNumbered(1, otherContents),
ranges: [
rangeAtSearch('A()', contents, 'A'),
rangeAfterPrefix('constructorTearoffA = A.', contents, 'new'),
]),
_isResult(CallHierarchyKind.constructor, 'B', otherFile,
- rangeAtSearch('B {', otherContents, 'B'),
+ nameRange: rangeAtSearch('B {', otherContents, 'B'),
+ codeRange: rangeNumbered(2, otherContents),
ranges: [
rangeAtSearch('B()', contents, 'B'),
rangeAfterPrefix('constructorTearoffB = B.', contents, 'new'),
@@ -1040,7 +1112,7 @@
final otherContents = '''
extension StringExtension on String {
- bar() {}
+ /*1*/void bar() {}/*1*/
}
''';
@@ -1050,7 +1122,8 @@
calls,
unorderedEquals([
_isResult(CallHierarchyKind.method, 'bar', otherFile,
- rangeAtSearch('bar() {', otherContents, 'bar'),
+ nameRange: rangeAtSearch('bar() {', otherContents, 'bar'),
+ codeRange: rangeNumbered(1, otherContents),
ranges: [
rangeAtSearch('bar();', contents, 'bar'),
rangeAtSearch('bar;', contents, 'bar'),
@@ -1065,9 +1138,9 @@
import 'other.dart';
void fo^o() {
- void nested() {
+ /*1*/void nested() {
f(); // not a call of 'foo'
- }
+ }/*1*/
f(); // 1
final tearoff = f;
nested();
@@ -1076,7 +1149,7 @@
''';
final otherContents = '''
-void f() {}
+/*1*/void f() {}/*1*/
''';
addSource(otherFile, otherContents);
@@ -1085,13 +1158,15 @@
calls,
unorderedEquals([
_isResult(CallHierarchyKind.function, 'f', otherFile,
- rangeAtSearch('f() {', otherContents, 'f'),
+ nameRange: rangeAtSearch('f() {', otherContents, 'f'),
+ codeRange: rangeNumbered(1, otherContents),
ranges: [
rangeAtSearch('f(); // 1', contents, 'f'),
rangeAfterPrefix('tearoff = ', contents, 'f'),
]),
_isResult(CallHierarchyKind.function, 'nested', testFile,
- rangeAtSearch('nested() {', contents, 'nested'),
+ nameRange: rangeAtSearch('nested() {', contents, 'nested'),
+ codeRange: rangeNumbered(1, contents),
ranges: [
rangeAtSearch('nested();', contents, 'nested'),
rangeAfterPrefix('nestedTearoff = ', contents, 'nested'),
@@ -1114,9 +1189,9 @@
''';
final otherContents = '''
-class A {
- String get b => '';
-}
+/*1*/class A {
+ /*2*/String get b => '';/*2*/
+}/*1*/
''';
addSource(otherFile, otherContents);
@@ -1124,10 +1199,16 @@
expect(
calls,
unorderedEquals([
- _isResult(CallHierarchyKind.constructor, 'A', otherFile,
- rangeAtSearch('A {', otherContents, 'A')),
+ _isResult(
+ CallHierarchyKind.constructor,
+ 'A',
+ otherFile,
+ nameRange: rangeAtSearch('A {', otherContents, 'A'),
+ codeRange: rangeNumbered(1, otherContents),
+ ),
_isResult(CallHierarchyKind.property, 'get b', otherFile,
- rangeAtSearch('b => ', otherContents, 'b'),
+ nameRange: rangeAtSearch('b => ', otherContents, 'b'),
+ codeRange: rangeNumbered(2, otherContents),
ranges: [
rangeAfterPrefix('a.', contents, 'b'),
rangeAfterPrefix('A().', contents, 'b'),
@@ -1144,7 +1225,7 @@
// ignore_for_file: unused_local_variable
import 'other.dart';
-f() {
+void f() {
final foo1 = Fo^o();
}
''';
@@ -1177,10 +1258,10 @@
''';
final otherContents = '''
-class A {
+/*1*/class A {
String field;
- void bar() {}
-}
+ /*2*/void bar() {}/*2*/
+}/*1*/
''';
addSource(otherFile, otherContents);
@@ -1188,10 +1269,16 @@
expect(
calls,
unorderedEquals([
- _isResult(CallHierarchyKind.constructor, 'A', otherFile,
- rangeAtSearch('A {', otherContents, 'A')),
+ _isResult(
+ CallHierarchyKind.constructor,
+ 'A',
+ otherFile,
+ nameRange: rangeAtSearch('A {', otherContents, 'A'),
+ codeRange: rangeNumbered(1, otherContents),
+ ),
_isResult(CallHierarchyKind.method, 'bar', otherFile,
- rangeAtSearch('bar() {', otherContents, 'bar'),
+ nameRange: rangeAtSearch('bar() {', otherContents, 'bar'),
+ codeRange: rangeNumbered(2, otherContents),
ranges: [
rangeAfterPrefix('a.', contents, 'bar'),
rangeAfterPrefix('tearoff = a.', contents, 'bar'),
@@ -1217,10 +1304,10 @@
final otherContents = '''
mixin OtherMixin {
- void foo() {}
+ /*2*/void foo() {}/*2*/
}
-class A with OtherMixin {}
+/*1*/class A with OtherMixin {}/*1*/
''';
addSource(otherFile, otherContents);
@@ -1228,10 +1315,16 @@
expect(
calls,
unorderedEquals([
- _isResult(CallHierarchyKind.constructor, 'A', otherFile,
- rangeAtSearch('A with', otherContents, 'A')),
+ _isResult(
+ CallHierarchyKind.constructor,
+ 'A',
+ otherFile,
+ nameRange: rangeAtSearch('A with', otherContents, 'A'),
+ codeRange: rangeNumbered(1, otherContents),
+ ),
_isResult(CallHierarchyKind.method, 'foo', otherFile,
- rangeAtSearch('foo() {', otherContents, 'foo'),
+ nameRange: rangeAtSearch('foo() {', otherContents, 'foo'),
+ codeRange: rangeNumbered(2, otherContents),
ranges: [
rangeAfterPrefix('a.', contents, 'foo'),
rangeAfterPrefix('A().', contents, 'foo'),
@@ -1257,7 +1350,7 @@
final otherContents = '''
void f() {}
class A {
- A.named();
+ /*1*/A.named();/*1*/
}
''';
@@ -1267,7 +1360,8 @@
calls,
unorderedEquals([
_isResult(CallHierarchyKind.constructor, 'A.named', otherFile,
- rangeAtSearch('named', otherContents),
+ nameRange: rangeAtSearch('named', otherContents),
+ codeRange: rangeNumbered(1, otherContents),
ranges: [
rangeAfterPrefix('a = A.', contents, 'named'),
rangeAfterPrefix('constructorTearoff = A.', contents, 'named'),
@@ -1288,9 +1382,9 @@
''';
final otherContents = '''
-class A {
- set b(String value) {}
-}
+/*1*/class A {
+ /*2*/set b(String value) {}/*2*/
+}/*1*/
''';
addSource(otherFile, otherContents);
@@ -1298,10 +1392,16 @@
expect(
calls,
unorderedEquals([
- _isResult(CallHierarchyKind.constructor, 'A', otherFile,
- rangeAtSearch('A {', otherContents, 'A')),
+ _isResult(
+ CallHierarchyKind.constructor,
+ 'A',
+ otherFile,
+ nameRange: rangeAtSearch('A {', otherContents, 'A'),
+ codeRange: rangeNumbered(1, otherContents),
+ ),
_isResult(CallHierarchyKind.property, 'set b', otherFile,
- rangeAtSearch('b(String ', otherContents, 'b'),
+ nameRange: rangeAtSearch('b(String ', otherContents, 'b'),
+ codeRange: rangeNumbered(2, otherContents),
ranges: [
rangeAfterPrefix('a.', contents, 'b'),
rangeAfterPrefix('A().', contents, 'b'),
diff --git a/sdk/lib/developer/profiler.dart b/sdk/lib/developer/profiler.dart
index bf6ae6b..b134de7 100644
--- a/sdk/lib/developer/profiler.dart
+++ b/sdk/lib/developer/profiler.dart
@@ -10,9 +10,9 @@
/// The maximum number of UserTag instances that can be created by a program.
static const maxUserTags = 64;
- @deprecated
- // TODO: We shouldn't be using SCREAMING_CAPS for constants, so this should
- // be removed for Dart 3.0.
+ @Deprecated("Use 'maxUserTags' instead. Will be removed in Dart 3.0.")
+ // TODO(bkonyi): We shouldn't be using SCREAMING_CAPS for constants, so this
+ // should be removed for Dart 3.0.
static const MAX_USER_TAGS = maxUserTags;
external factory UserTag(String label);
diff --git a/tools/VERSION b/tools/VERSION
index 6c8c0b4..a271db8 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 277
+PRERELEASE 278
PRERELEASE_PATCH 0
\ No newline at end of file