Deprecate AstVisitor.visitTypeName(), add visitNamedType().

Change-Id: I736a568068c2acfdc7074bb16b11fd38b656a13a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/214135
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov 2021-09-22 19:15:54 +00:00 committed by commit-bot@chromium.org
parent cb7c932f7b
commit 1c125b4868
35 changed files with 436 additions and 378 deletions

View file

@ -966,6 +966,18 @@ class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor<void> {
super.visitMixinDeclaration(node);
}
@override
void visitNamedType(NamedType node) {
var type = node.type;
if (type != null) {
if (type.isDynamic && node.name.name == 'dynamic') {
computer._addRegion_node(node, HighlightRegionType.TYPE_NAME_DYNAMIC);
return null;
}
}
super.visitNamedType(node);
}
@override
void visitNativeClause(NativeClause node) {
computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN);
@ -1117,18 +1129,6 @@ class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor<void> {
super.visitTryStatement(node);
}
@override
void visitTypeName(TypeName node) {
var type = node.type;
if (type != null) {
if (type.isDynamic && node.name.name == 'dynamic') {
computer._addRegion_node(node, HighlightRegionType.TYPE_NAME_DYNAMIC);
return null;
}
}
super.visitTypeName(node);
}
@override
void visitVariableDeclarationList(VariableDeclarationList node) {
computer._addRegion_token(node.lateKeyword, HighlightRegionType.KEYWORD);

View file

@ -158,11 +158,11 @@ class _ReferenceFinder extends RecursiveAstVisitor {
_ReferenceFinder(this.typeName);
@override
void visitTypeName(TypeName node) {
void visitNamedType(NamedType node) {
if (node.name.name == typeName) {
reference ??= node;
count++;
}
super.visitTypeName(node);
super.visitNamedType(node);
}
}

View file

@ -965,6 +965,14 @@ class _ExtractMethodAnalyzer extends StatementAnalyzer {
}
}
@override
void visitNamedType(NamedType node) {
super.visitNamedType(node);
if (_isFirstSelectedNode(node)) {
invalidSelection('Cannot extract a single type reference.');
}
}
@override
void visitSimpleIdentifier(SimpleIdentifier node) {
super.visitSimpleIdentifier(node);
@ -986,14 +994,6 @@ class _ExtractMethodAnalyzer extends StatementAnalyzer {
}
}
@override
void visitTypeName(TypeName node) {
super.visitTypeName(node);
if (_isFirstSelectedNode(node)) {
invalidSelection('Cannot extract a single type reference.');
}
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
super.visitVariableDeclaration(node);

View file

@ -953,6 +953,16 @@ class CodeShapeDataCollector extends RecursiveAstVisitor<void> {
super.visitNamedExpression(node);
}
@override
void visitNamedType(NamedType node) {
_visitChildren(node, {
'name': node.name,
'typeArguments': node.typeArguments,
'question': node.question,
});
super.visitNamedType(node);
}
@override
void visitNativeClause(NativeClause node) {
_visitChildren(node, {
@ -1219,16 +1229,6 @@ class CodeShapeDataCollector extends RecursiveAstVisitor<void> {
super.visitTypeArgumentList(node);
}
@override
void visitTypeName(TypeName node) {
_visitChildren(node, {
'name': node.name,
'typeArguments': node.typeArguments,
'question': node.question,
});
super.visitTypeName(node);
}
@override
void visitTypeParameter(TypeParameter node) {
_visitChildren(node, {

View file

@ -1042,6 +1042,12 @@ class RelevanceDataCollector extends RecursiveAstVisitor<void> {
super.visitNamedExpression(node);
}
@override
void visitNamedType(NamedType node) {
// There are no completions.
super.visitNamedType(node);
}
@override
void visitNativeClause(NativeClause node) {
// There are no completions.
@ -1298,12 +1304,6 @@ class RelevanceDataCollector extends RecursiveAstVisitor<void> {
super.visitTypeArgumentList(node);
}
@override
void visitTypeName(TypeName node) {
// There are no completions.
super.visitTypeName(node);
}
@override
void visitTypeParameter(TypeParameter node) {
if (node.bound != null) {

View file

@ -972,6 +972,12 @@ class RelevanceDataCollector extends RecursiveAstVisitor<void> {
super.visitNamedExpression(node);
}
@override
void visitNamedType(NamedType node) {
// There are no completions.
super.visitNamedType(node);
}
@override
void visitNativeClause(NativeClause node) {
// There are no completions.
@ -1198,12 +1204,6 @@ class RelevanceDataCollector extends RecursiveAstVisitor<void> {
super.visitTypeArgumentList(node);
}
@override
void visitTypeName(TypeName node) {
// There are no completions.
super.visitTypeName(node);
}
@override
void visitTypeParameter(TypeParameter node) {
if (node.bound != null) {

View file

@ -513,6 +513,8 @@ abstract class AstVisitor<R> {
R? visitNamedExpression(NamedExpression node);
R? visitNamedType(NamedType node);
R? visitNativeClause(NativeClause node);
R? visitNativeFunctionBody(NativeFunctionBody node);
@ -586,6 +588,7 @@ abstract class AstVisitor<R> {
R? visitTypeLiteral(TypeLiteral node);
@Deprecated('Override visitNamedType instead')
R? visitTypeName(TypeName node);
R? visitTypeParameter(TypeParameter node);

View file

@ -449,6 +449,10 @@ class GeneralizingAstVisitor<R> implements AstVisitor<R> {
@override
R? visitNamedExpression(NamedExpression node) => visitExpression(node);
@override
// ignore: deprecated_member_use_from_same_package
R? visitNamedType(NamedType node) => visitTypeName(node as TypeName);
R? visitNamespaceDirective(NamespaceDirective node) =>
visitUriBasedDirective(node);
@ -592,6 +596,7 @@ class GeneralizingAstVisitor<R> implements AstVisitor<R> {
@override
R? visitTypeLiteral(TypeLiteral node) => visitExpression(node);
@Deprecated('Override visitNamedType instead')
@override
R? visitTypeName(TypeName node) => visitNode(node);
@ -1131,6 +1136,12 @@ class RecursiveAstVisitor<R> implements AstVisitor<R> {
return null;
}
@override
R? visitNamedType(NamedType node) {
// ignore: deprecated_member_use_from_same_package
return visitTypeName(node as TypeName);
}
@override
R? visitNativeClause(NativeClause node) {
node.visitChildren(this);
@ -1348,6 +1359,7 @@ class RecursiveAstVisitor<R> implements AstVisitor<R> {
return null;
}
@Deprecated('Override visitNamedType instead')
@override
R? visitTypeName(TypeName node) {
node.visitChildren(this);
@ -1662,6 +1674,10 @@ class SimpleAstVisitor<R> implements AstVisitor<R> {
@override
R? visitNamedExpression(NamedExpression node) => null;
@override
// ignore: deprecated_member_use_from_same_package
R? visitNamedType(NamedType node) => visitTypeName(node as TypeName);
@override
R? visitNativeClause(NativeClause node) => null;
@ -1772,6 +1788,7 @@ class SimpleAstVisitor<R> implements AstVisitor<R> {
@override
R? visitTypeLiteral(TypeLiteral node) => null;
@Deprecated('Override visitNamedType instead')
@override
R? visitTypeName(TypeName node) => null;
@ -2066,6 +2083,10 @@ class ThrowingAstVisitor<R> implements AstVisitor<R> {
@override
R? visitNamedExpression(NamedExpression node) => _throw(node);
@override
// ignore: deprecated_member_use_from_same_package
R? visitNamedType(NamedType node) => visitTypeName(node as TypeName);
@override
R? visitNativeClause(NativeClause node) => _throw(node);
@ -2178,6 +2199,7 @@ class ThrowingAstVisitor<R> implements AstVisitor<R> {
@override
R? visitTypeLiteral(TypeLiteral node) => _throw(node);
@Deprecated('Override visitNamedType instead')
@override
R? visitTypeName(TypeName node) => _throw(node);
@ -2882,6 +2904,14 @@ class TimedAstVisitor<T> implements AstVisitor<T> {
return result;
}
@override
T? visitNamedType(NamedType node) {
stopwatch.start();
T? result = _baseVisitor.visitNamedType(node);
stopwatch.stop();
return result;
}
@override
T? visitNativeClause(NativeClause node) {
stopwatch.start();
@ -3171,6 +3201,7 @@ class TimedAstVisitor<T> implements AstVisitor<T> {
return result;
}
@Deprecated('Override visitNamedType instead')
@override
T? visitTypeName(TypeName node) {
stopwatch.start();
@ -3519,6 +3550,10 @@ class UnifyingAstVisitor<R> implements AstVisitor<R> {
@override
R? visitNamedExpression(NamedExpression node) => visitNode(node);
@override
// ignore: deprecated_member_use_from_same_package
R? visitNamedType(NamedType node) => visitTypeName(node as TypeName);
@override
R? visitNativeClause(NativeClause node) => visitNode(node);
@ -3637,6 +3672,7 @@ class UnifyingAstVisitor<R> implements AstVisitor<R> {
@override
R? visitTypeLiteral(TypeLiteral node) => visitNode(node);
@Deprecated('Override visitNamedType instead')
@override
R? visitTypeName(TypeName node) => visitNode(node);

View file

@ -711,6 +711,16 @@ class _IndexContributor extends GeneralizingAstVisitor {
super.visitMixinDeclaration(node);
}
@override
void visitNamedType(NamedType node) {
AstNode parent = node.parent!;
if (parent is ClassTypeAlias && parent.superclass == node) {
recordSuperType(node, IndexRelationKind.IS_EXTENDED_BY);
} else {
super.visitNamedType(node);
}
}
@override
void visitOnClause(OnClause node) {
for (NamedType namedType in node.superclassConstraints2) {
@ -818,16 +828,6 @@ class _IndexContributor extends GeneralizingAstVisitor {
node.argumentList.accept(this);
}
@override
void visitTypeName(TypeName node) {
AstNode parent = node.parent!;
if (parent is ClassTypeAlias && parent.superclass == node) {
recordSuperType(node, IndexRelationKind.IS_EXTENDED_BY);
} else {
super.visitTypeName(node);
}
}
@override
void visitWithClause(WithClause node) {
for (NamedType namedType in node.mixinTypes2) {

View file

@ -10304,7 +10304,7 @@ class TypeNameImpl extends TypeAnnotationImpl implements TypeName {
}
@override
E? accept<E>(AstVisitor<E> visitor) => visitor.visitTypeName(this);
E? accept<E>(AstVisitor<E> visitor) => visitor.visitNamedType(this);
@override
void visitChildren(AstVisitor visitor) {

View file

@ -755,6 +755,15 @@ class ToSourceVisitor implements AstVisitor<void> {
_visitNode(node.expression, prefix: ' ');
}
@override
void visitNamedType(NamedType node) {
_visitNode(node.name);
_visitNode(node.typeArguments);
if (node.question != null) {
sink.write('?');
}
}
@override
void visitNativeClause(NativeClause node) {
sink.write('native ');
@ -1012,11 +1021,7 @@ class ToSourceVisitor implements AstVisitor<void> {
@override
void visitTypeName(TypeName node) {
_visitNode(node.name);
_visitNode(node.typeArguments);
if (node.question != null) {
sink.write('?');
}
throw StateError('Should not be invoked');
}
@override

View file

@ -882,6 +882,14 @@ class AstComparator implements AstVisitor<bool> {
isEqualNodes(node.expression, other.expression);
}
@override
bool? visitNamedType(NamedType node) {
TypeName other = _other as TypeName;
return isEqualNodes(node.name, other.name) &&
isEqualNodes(node.typeArguments, other.typeArguments) &&
isEqualTokens(node.question, other.question);
}
@override
bool visitNativeClause(NativeClause node) {
NativeClause other = _other as NativeClause;
@ -1174,10 +1182,7 @@ class AstComparator implements AstVisitor<bool> {
@override
bool visitTypeName(TypeName node) {
var other = _other as NamedType;
return isEqualNodes(node.name, other.name) &&
isEqualNodes(node.typeArguments, other.typeArguments) &&
isEqualTokens(node.question, other.question);
throw StateError('Should not be invoked');
}
@override
@ -2520,6 +2525,18 @@ class NodeReplacer implements AstVisitor<bool> {
return visitNode(node);
}
@override
bool? visitNamedType(covariant TypeNameImpl node) {
if (identical(node.name, _oldNode)) {
node.name = _newNode as Identifier;
return true;
} else if (identical(node.typeArguments, _oldNode)) {
node.typeArguments = _newNode as TypeArgumentList;
return true;
}
return visitNode(node);
}
bool visitNamespaceDirective(covariant NamespaceDirectiveImpl node) {
if (_replaceInList(node.combinators)) {
return true;
@ -2847,14 +2864,7 @@ class NodeReplacer implements AstVisitor<bool> {
@override
bool visitTypeName(covariant TypeNameImpl node) {
if (identical(node.name, _oldNode)) {
node.name = _newNode as Identifier;
return true;
} else if (identical(node.typeArguments, _oldNode)) {
node.typeArguments = _newNode as TypeArgumentList;
return true;
}
return visitNode(node);
throw StateError('Should not be invoked');
}
@override

View file

@ -1296,6 +1296,29 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
DartObjectImpl? visitNamedExpression(NamedExpression node) =>
node.expression.accept(this);
@override
DartObjectImpl? visitNamedType(NamedType node) {
var type = node.type;
if (type == null) {
return null;
}
if (!_isNonNullableByDefault && hasTypeParameterReference(type)) {
return super.visitNamedType(node);
}
if (_substitution != null) {
type = _substitution!.substituteType(type);
}
return DartObjectImpl(
typeSystem,
_typeProvider.typeType,
TypeState(type),
);
}
@override
DartObjectImpl? visitNode(AstNode node) {
// TODO(https://github.com/dart-lang/sdk/issues/47061): Use a specific
@ -1484,29 +1507,6 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
);
}
@override
DartObjectImpl? visitTypeName(TypeName node) {
var type = node.type;
if (type == null) {
return null;
}
if (!_isNonNullableByDefault && hasTypeParameterReference(type)) {
return super.visitTypeName(node);
}
if (_substitution != null) {
type = _substitution!.substituteType(type);
}
return DartObjectImpl(
typeSystem,
_typeProvider.typeType,
TypeState(type),
);
}
/// Add the entries produced by evaluating the given collection [element] to
/// the given [list]. Return `true` if the evaluation of one or more of the
/// elements failed.

View file

@ -442,6 +442,9 @@ class ExitDetector extends GeneralizingAstVisitor<bool> {
bool visitNamedExpression(NamedExpression node) =>
node.expression.accept(this)!;
@override
bool visitNamedType(NamedType node) => false;
@override
bool visitNode(AstNode node) {
throw StateError(
@ -556,9 +559,6 @@ class ExitDetector extends GeneralizingAstVisitor<bool> {
@override
bool visitTypeLiteral(TypeLiteral node) => _nodeExits(node.typeName);
@override
bool visitTypeName(TypeName node) => false;
@override
bool visitVariableDeclaration(VariableDeclaration node) {
var initializer = node.initializer;

View file

@ -97,15 +97,15 @@ class LegacyTypeAsserter extends GeneralizingAstVisitor<void> {
}
@override
void visitTypeAnnotation(TypeAnnotation node) {
void visitNamedType(NamedType node) {
_assertLegacyType(node.type);
super.visitTypeAnnotation(node);
super.visitNamedType(node);
}
@override
void visitTypeName(TypeName node) {
void visitTypeAnnotation(TypeAnnotation node) {
_assertLegacyType(node.type);
super.visitTypeName(node);
super.visitTypeAnnotation(node);
}
@override

View file

@ -881,6 +881,18 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
});
}
@override
void visitNamedType(covariant TypeNameImpl node) {
node.typeArguments?.accept(this);
_typeNameResolver.nameScope = _nameScope;
_typeNameResolver.resolve(node);
if (_typeNameResolver.rewriteResult != null) {
_typeNameResolver.rewriteResult!.accept(this);
}
}
@override
void visitPartDirective(PartDirective node) {
_withElementWalker(null, () {
@ -987,18 +999,6 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
});
}
@override
void visitTypeName(covariant TypeNameImpl node) {
node.typeArguments?.accept(this);
_typeNameResolver.nameScope = _nameScope;
_typeNameResolver.resolve(node);
if (_typeNameResolver.rewriteResult != null) {
_typeNameResolver.rewriteResult!.accept(this);
}
}
@override
void visitTypeParameter(TypeParameter node) {
var element = node.declaredElement as TypeParameterElementImpl;
@ -1259,7 +1259,7 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
void _resolveType(TypeNameImpl namedType, ErrorCode errorCode,
{bool asClass = false}) {
_typeNameResolver.classHierarchy_namedType = namedType;
visitTypeName(namedType);
visitNamedType(namedType);
_typeNameResolver.classHierarchy_namedType = null;
if (_typeNameResolver.hasErrorReported) {
@ -1276,7 +1276,7 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
return;
}
// If the type is not an InterfaceType, then visitTypeName() sets the type
// If the type is not an InterfaceType, then visitNamedType() sets the type
// to be a DynamicTypeImpl
Identifier name = namedType.name;
if (!_libraryElement.shouldIgnoreUndefinedIdentifier(name)) {

View file

@ -697,6 +697,24 @@ class BestPracticesVerifier extends RecursiveAstVisitor<void> {
}
}
@override
void visitNamedType(NamedType node) {
var question = node.question;
if (question != null) {
var name = node.name.name;
var type = node.typeOrThrow;
// Only report non-aliased, non-user-defined `Null?` and `dynamic?`. Do
// not report synthetic `dynamic` in place of an unresolved type.
if ((type.element == _nullType.element ||
(type.isDynamic && name == 'dynamic')) &&
type.alias == null) {
_errorReporter.reportErrorForToken(
HintCode.UNNECESSARY_QUESTION_MARK, question, [name]);
}
}
super.visitNamedType(node);
}
@override
void visitPostfixExpression(PostfixExpression node) {
_deprecatedVerifier.postfixExpression(node);
@ -771,24 +789,6 @@ class BestPracticesVerifier extends RecursiveAstVisitor<void> {
}
}
@override
void visitTypeName(TypeName node) {
var question = node.question;
if (question != null) {
var name = node.name.name;
var type = node.typeOrThrow;
// Only report non-aliased, non-user-defined `Null?` and `dynamic?`. Do
// not report synthetic `dynamic` in place of an unresolved type.
if ((type.element == _nullType.element ||
(type.isDynamic && name == 'dynamic')) &&
type.alias == null) {
_errorReporter.reportErrorForToken(
HintCode.UNNECESSARY_QUESTION_MARK, question, [name]);
}
}
super.visitTypeName(node);
}
/// Check for the passed is expression for the unnecessary type check hint
/// codes as well as null checks expressed using an is expression.
///

View file

@ -1000,6 +1000,12 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
}
}
@override
void visitNamedType(NamedType node) {
_typeArgumentsVerifier.checkNamedType(node);
super.visitNamedType(node);
}
@override
void visitNativeClause(NativeClause node) {
// TODO(brianwilkerson) Figure out the right rule for when 'native' is
@ -1217,12 +1223,6 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
super.visitTypeArgumentList(node);
}
@override
void visitTypeName(TypeName node) {
_typeArgumentsVerifier.checkNamedType(node);
super.visitTypeName(node);
}
@override
void visitTypeParameter(TypeParameter node) {
_checkForBuiltInIdentifierAsName(node.name,
@ -5126,7 +5126,7 @@ class _UninstantiatedBoundChecker extends RecursiveAstVisitor<void> {
_UninstantiatedBoundChecker(this._errorReporter);
@override
void visitTypeName(TypeName node) {
void visitNamedType(NamedType node) {
var typeArgs = node.typeArguments;
if (typeArgs != null) {
typeArgs.accept(this);

View file

@ -1736,6 +1736,15 @@ class ResolverVisitor extends ResolverBase with ErrorDetectionHelpers {
flowAnalysis.flow?.forwardExpression(node, node.expression);
}
@override
void visitNamedType(NamedType node) {
// All TypeName(s) are already resolved, so we don't resolve it here.
// But there might be type arguments with Expression(s), such as default
// values for formal parameters of GenericFunctionType(s). These are
// invalid, but if they exist, they should be resolved.
node.typeArguments?.accept(this);
}
@override
void visitNode(AstNode node) {
checkUnreachableNode(node);
@ -2002,15 +2011,6 @@ class ResolverVisitor extends ResolverBase with ErrorDetectionHelpers {
}
}
@override
void visitTypeName(TypeName node) {
// All TypeName(s) are already resolved, so we don't resolve it here.
// But there might be type arguments with Expression(s), such as default
// values for formal parameters of GenericFunctionType(s). These are
// invalid, but if they exist, they should be resolved.
node.typeArguments?.accept(this);
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
_variableDeclarationResolver.resolve(node as VariableDeclarationImpl);
@ -2931,6 +2931,14 @@ class ScopeResolverVisitor extends ResolverBase {
node.members.accept(this);
}
@override
void visitNamedType(NamedType node) {
// All TypeName(s) are already resolved, so we don't resolve it here.
// But there might be type arguments with Expression(s), such as
// annotations on formal parameters of GenericFunctionType(s).
node.typeArguments?.accept(this);
}
@override
void visitPrefixedIdentifier(PrefixedIdentifier node) {
// Do not visit the identifier after the `.`, since it is not meant to be
@ -3051,14 +3059,6 @@ class ScopeResolverVisitor extends ResolverBase {
super.visitSwitchStatement(node);
}
@override
void visitTypeName(TypeName node) {
// All TypeName(s) are already resolved, so we don't resolve it here.
// But there might be type arguments with Expression(s), such as
// annotations on formal parameters of GenericFunctionType(s).
node.typeArguments?.accept(this);
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
super.visitVariableDeclaration(node);

View file

@ -495,6 +495,12 @@ class LinterVisitor extends RecursiveAstVisitor<void> {
super.visitNamedExpression(node);
}
@override
void visitNamedType(NamedType node) {
_runSubscriptions(node, registry._forNamedType);
super.visitNamedType(node);
}
@override
void visitNativeClause(NativeClause node) {
_runSubscriptions(node, registry._forNativeClause);
@ -694,12 +700,6 @@ class LinterVisitor extends RecursiveAstVisitor<void> {
super.visitTypeArgumentList(node);
}
@override
void visitTypeName(TypeName node) {
_runSubscriptions(node, registry._forTypeName);
super.visitTypeName(node);
}
@override
void visitTypeParameter(TypeParameter node) {
_runSubscriptions(node, registry._forTypeParameter);
@ -861,6 +861,7 @@ class NodeLintRegistry {
final List<_Subscription<MethodInvocation>> _forMethodInvocation = [];
final List<_Subscription<MixinDeclaration>> _forMixinDeclaration = [];
final List<_Subscription<NamedExpression>> _forNamedExpression = [];
final List<_Subscription<NamedType>> _forNamedType = [];
final List<_Subscription<NativeClause>> _forNativeClause = [];
final List<_Subscription<NativeFunctionBody>> _forNativeFunctionBody = [];
final List<_Subscription<NullLiteral>> _forNullLiteral = [];
@ -899,7 +900,6 @@ class NodeLintRegistry {
_forTopLevelVariableDeclaration = [];
final List<_Subscription<TryStatement>> _forTryStatement = [];
final List<_Subscription<TypeArgumentList>> _forTypeArgumentList = [];
final List<_Subscription<TypeName>> _forTypeName = [];
final List<_Subscription<TypeParameter>> _forTypeParameter = [];
final List<_Subscription<TypeParameterList>> _forTypeParameterList = [];
final List<_Subscription<VariableDeclaration>> _forVariableDeclaration = [];
@ -1263,6 +1263,10 @@ class NodeLintRegistry {
_forNamedExpression.add(_Subscription(linter, visitor, _getTimer(linter)));
}
void addNamedType(LintRule linter, AstVisitor visitor) {
_forNamedType.add(_Subscription(linter, visitor, _getTimer(linter)));
}
void addNativeClause(LintRule linter, AstVisitor visitor) {
_forNativeClause.add(_Subscription(linter, visitor, _getTimer(linter)));
}
@ -1407,8 +1411,9 @@ class NodeLintRegistry {
_forTypeArgumentList.add(_Subscription(linter, visitor, _getTimer(linter)));
}
@Deprecated('Use addNamedType() instead')
void addTypeName(LintRule linter, AstVisitor visitor) {
_forTypeName.add(_Subscription(linter, visitor, _getTimer(linter)));
addNamedType(linter, visitor);
}
void addTypeParameter(LintRule linter, AstVisitor visitor) {

View file

@ -165,8 +165,8 @@ class AstBinaryReader {
return _readTypeArgumentList();
case Tag.TypeLiteral:
return _readTypeLiteral();
case Tag.TypeName:
return _readTypeName();
case Tag.NamedType:
return _readNamedType();
case Tag.TypeParameter:
return _readTypeParameter();
case Tag.TypeParameterList:
@ -864,6 +864,20 @@ class AstBinaryReader {
return node;
}
TypeName _readNamedType() {
var flags = _readByte();
var name = readNode() as Identifier;
var typeArguments = _readOptionalNode() as TypeArgumentList?;
var node = astFactory.namedType(
name: name,
typeArguments: typeArguments,
question: AstBinaryFlags.hasQuestion(flags) ? Tokens.question() : null,
);
node.type = _reader.readType();
return node;
}
List<T> _readNodeList<T>() {
var length = _reader.readUInt30();
return List.generate(length, (_) => readNode() as T);
@ -1154,20 +1168,6 @@ class AstBinaryReader {
return node;
}
TypeName _readTypeName() {
var flags = _readByte();
var name = readNode() as Identifier;
var typeArguments = _readOptionalNode() as TypeArgumentList?;
var node = astFactory.typeName(
name,
typeArguments,
question: AstBinaryFlags.hasQuestion(flags) ? Tokens.question() : null,
);
node.type = _reader.readType();
return node;
}
TypeParameter _readTypeParameter() {
var name = _readDeclarationName();
var bound = _readOptionalNode() as TypeAnnotation?;

View file

@ -72,6 +72,7 @@ class Tag {
static const int MethodInvocation = 59;
static const int MixinDeclaration = 67;
static const int NamedExpression = 60;
static const int NamedType = 39;
static const int NullLiteral = 49;
static const int ParenthesizedExpression = 53;
static const int PostfixExpression = 94;
@ -93,7 +94,6 @@ class Tag {
static const int ThrowExpression = 81;
static const int TypeArgumentList = 38;
static const int TypeLiteral = 102;
static const int TypeName = 39;
static const int TypeParameter = 40;
static const int TypeParameterList = 41;
static const int VariableDeclaration = 42;

View file

@ -512,6 +512,23 @@ class AstBinaryWriter extends ThrowingAstVisitor<void> {
_writeNode(node.expression);
}
@override
void visitNamedType(NamedType node) {
_writeByte(Tag.NamedType);
_writeByte(
AstBinaryFlags.encode(
hasQuestion: node.question != null,
hasTypeArguments: node.typeArguments != null,
),
);
_writeNode(node.name);
_writeOptionalNode(node.typeArguments);
_sink.writeType(node.type);
}
@override
void visitNullLiteral(NullLiteral node) {
_writeByte(Tag.NullLiteral);
@ -731,23 +748,6 @@ class AstBinaryWriter extends ThrowingAstVisitor<void> {
_storeExpression(node);
}
@override
void visitTypeName(TypeName node) {
_writeByte(Tag.TypeName);
_writeByte(
AstBinaryFlags.encode(
hasQuestion: node.question != null,
hasTypeArguments: node.typeArguments != null,
),
);
_writeNode(node.name);
_writeOptionalNode(node.typeArguments);
_sink.writeType(node.type);
}
@override
void visitTypeParameter(TypeParameter node) {
_writeByte(Tag.TypeParameter);

View file

@ -710,6 +710,13 @@ class AstTextPrinter extends ThrowingAstVisitor<void> {
node.expression.accept(this);
}
@override
void visitNamedType(NamedType node) {
node.name.accept(this);
node.typeArguments?.accept(this);
_token(node.question);
}
@override
void visitNativeClause(NativeClause node) {
_token(node.nativeKeyword);
@ -943,13 +950,6 @@ class AstTextPrinter extends ThrowingAstVisitor<void> {
_token(node.rightBracket);
}
@override
void visitTypeName(TypeName node) {
node.name.accept(this);
node.typeArguments?.accept(this);
_token(node.question);
}
@override
void visitTypeParameter(TypeParameter node) {
_declaration(node);

View file

@ -744,6 +744,11 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
_buildClassOrMixin(node);
}
@override
void visitNamedType(NamedType node) {
node.typeArguments?.accept(this);
}
@override
void visitOnClause(OnClause node) {
node.superclassConstraints2.accept(this);
@ -867,11 +872,6 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
node.arguments.accept(this);
}
@override
void visitTypeName(TypeName node) {
node.typeArguments?.accept(this);
}
@override
void visitTypeParameter(covariant TypeParameterImpl node) {
var nameNode = node.name;

View file

@ -315,28 +315,7 @@ class ReferenceResolver extends ThrowingAstVisitor<void> {
}
@override
void visitOnClause(OnClause node) {
node.superclassConstraints2.accept(this);
}
@override
void visitSimpleFormalParameter(SimpleFormalParameter node) {
node.type?.accept(this);
nodesToBuildType.addDeclaration(node);
}
@override
void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
node.variables.accept(this);
}
@override
void visitTypeArgumentList(TypeArgumentList node) {
node.arguments.accept(this);
}
@override
void visitTypeName(covariant TypeNameImpl node) {
void visitNamedType(covariant TypeNameImpl node) {
var typeIdentifier = node.name;
Element? element;
@ -389,6 +368,27 @@ class ReferenceResolver extends ThrowingAstVisitor<void> {
}
}
@override
void visitOnClause(OnClause node) {
node.superclassConstraints2.accept(this);
}
@override
void visitSimpleFormalParameter(SimpleFormalParameter node) {
node.type?.accept(this);
nodesToBuildType.addDeclaration(node);
}
@override
void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
node.variables.accept(this);
}
@override
void visitTypeArgumentList(TypeArgumentList node) {
node.arguments.accept(this);
}
@override
void visitTypeParameter(TypeParameter node) {
var bound = node.bound;

View file

@ -198,6 +198,19 @@ class StaticTypeVerifier extends GeneralizingAstVisitor<void> {
@override
void visitLibraryIdentifier(LibraryIdentifier node) {}
@override
void visitNamedType(NamedType node) {
// Note: do not visit children from this node, the child SimpleIdentifier in
// TypeName (i.e. "String") does not have a static type defined.
// TODO(brianwilkerson) Not visiting the children means that we won't catch
// type arguments that were not resolved.
if (node.type == null) {
_unresolvedTypes.add(node);
} else {
_resolvedTypeCount++;
}
}
@override
void visitPrefixedIdentifier(PrefixedIdentifier node) {
// In cases where we have a prefixed identifier where the prefix is dynamic,
@ -243,19 +256,6 @@ class StaticTypeVerifier extends GeneralizingAstVisitor<void> {
super.visitTypeAnnotation(node);
}
@override
void visitTypeName(TypeName node) {
// Note: do not visit children from this node, the child SimpleIdentifier in
// TypeName (i.e. "String") does not have a static type defined.
// TODO(brianwilkerson) Not visiting the children means that we won't catch
// type arguments that were not resolved.
if (node.type == null) {
_unresolvedTypes.add(node);
} else {
_resolvedTypeCount++;
}
}
String _getFileName(AstNode? node) {
// TODO (jwren) there are two copies of this method, one here and one in
// ResolutionVerifier, they should be resolved into a single method

View file

@ -84,7 +84,7 @@ class _AvoidIntRule extends LintRule {
void registerNodeProcessors(
NodeLintRegistry registry, LinterContext context) {
final visitor = _AvoidIntVisitor(this);
registry.addTypeName(this, visitor);
registry.addNamedType(this, visitor);
}
}
@ -94,7 +94,7 @@ class _AvoidIntVisitor extends SimpleAstVisitor {
_AvoidIntVisitor(this.rule);
@override
void visitTypeName(TypeName node) {
void visitNamedType(NamedType node) {
if (node.name.name == 'int') {
rule.reportLint(node.name);
}

View file

@ -1033,6 +1033,18 @@ class ResolvedAstPrinter extends ThrowingAstVisitor<void> {
});
}
@override
void visitNamedType(NamedType node) {
_writeNextCodeLine(node);
// TODO(scheglov) Change to NamedType.
_writeln('TypeName');
_withIndent(() {
_writeNode('name', node.name);
_writeType('type', node.type);
_writeNode('typeArguments', node.typeArguments);
});
}
@override
void visitNullLiteral(NullLiteral node) {
_writeNextCodeLine(node);
@ -1427,17 +1439,6 @@ class ResolvedAstPrinter extends ThrowingAstVisitor<void> {
});
}
@override
void visitTypeName(TypeName node) {
_writeNextCodeLine(node);
_writeln('TypeName');
_withIndent(() {
_writeNode('name', node.name);
_writeType('type', node.type);
_writeNode('typeArguments', node.typeArguments);
});
}
@override
void visitTypeParameter(TypeParameter node) {
_writeNextCodeLine(node);

View file

@ -1072,6 +1072,16 @@ class _OpTypeAstVisitor extends GeneralizingAstVisitor<void> {
}
}
@override
void visitNamedType(NamedType node) {
// The entity won't be the first child entity (node.name), since
// CompletionTarget would have chosen an edge higher in the parse tree. So
// it must be node.typeArguments, meaning that the cursor is between the
// type name and the "<" that starts the type arguments. In this case,
// we have no completions to offer.
assert(identical(entity, node.typeArguments));
}
@override
void visitNode(AstNode node) {
// no suggestion by default
@ -1352,16 +1362,6 @@ class _OpTypeAstVisitor extends GeneralizingAstVisitor<void> {
optype.includeTypeNameSuggestions = true;
}
@override
void visitTypeName(TypeName node) {
// The entity won't be the first child entity (node.name), since
// CompletionTarget would have chosen an edge higher in the parse tree. So
// it must be node.typeArguments, meaning that the cursor is between the
// type name and the "<" that starts the type arguments. In this case,
// we have no completions to offer.
assert(identical(entity, node.typeArguments));
}
@override
void visitTypeParameter(TypeParameter node) {
if (entity == node.bound) {

View file

@ -221,7 +221,7 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
/// initializer in the constructor declaration.
Set<FieldElement?>? _fieldsNotInitializedByConstructor;
/// Current nesting depth of [visitTypeName]
/// Current nesting depth of [visitNamedType]
int _typeNameNesting = 0;
final Set<PromotableElement> _lateHintedLocals = {};
@ -1411,6 +1411,82 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
return null;
}
@override
DecoratedType? visitNamedType(NamedType node) {
try {
_typeNameNesting++;
var typeArguments = node.typeArguments?.arguments;
var element = node.name.staticElement;
if (element is TypeAliasElement) {
var aliasedElement =
element.aliasedElement as GenericFunctionTypeElement;
final typedefType = _variables!.decoratedElementType(aliasedElement);
final typeNameType = _variables!.decoratedTypeAnnotation(source, node);
Map<TypeParameterElement, DecoratedType> substitutions;
if (node.typeArguments == null) {
// TODO(mfairhurst): substitute instantiations to bounds
substitutions = {};
} else {
substitutions =
Map<TypeParameterElement, DecoratedType>.fromIterables(
element.typeParameters,
node.typeArguments!.arguments.map(
(t) => _variables!.decoratedTypeAnnotation(source, t)));
}
final decoratedType = typedefType.substitute(substitutions);
final origin = TypedefReferenceOrigin(source, node);
_linkDecoratedTypeParameters(decoratedType, typeNameType, origin,
isUnion: true);
_linkDecoratedTypes(
decoratedType.returnType!, typeNameType.returnType, origin,
isUnion: true);
} else if (element is TypeParameterizedElement) {
if (typeArguments == null) {
var instantiatedType =
_variables!.decoratedTypeAnnotation(source, node);
var origin = InstantiateToBoundsOrigin(source, node);
for (int i = 0; i < instantiatedType.typeArguments.length; i++) {
_linkDecoratedTypes(
instantiatedType.typeArguments[i]!,
_variables!
.decoratedTypeParameterBound(element.typeParameters[i]),
origin,
isUnion: false);
}
} else {
for (int i = 0; i < typeArguments.length; i++) {
DecoratedType? bound;
bound = _variables!
.decoratedTypeParameterBound(element.typeParameters[i]);
assert(bound != null);
var argumentType =
_variables!.decoratedTypeAnnotation(source, typeArguments[i]);
_checkAssignment(
TypeParameterInstantiationOrigin(source, typeArguments[i]),
FixReasonTarget.root,
source: argumentType,
destination: bound!,
hard: true);
}
}
}
node.visitChildren(this);
// If the type name is followed by a `/*!*/` comment, it is considered to
// apply to the type and not to the "as" expression. In order to prevent
// a future call to _handleNullCheck from interpreting it as applying to
// the "as" expression, we need to store the `/*!*/` comment in
// _nullCheckHints.
var token = node.endToken;
_nullCheckHints[token] = getPostfixHint(token);
namedTypeVisited(node); // Note this has been visited to TypeNameTracker.
return null;
} finally {
_typeNameNesting--;
}
}
@override
DecoratedType? visitNamespaceDirective(NamespaceDirective node) {
// skip directives, but not their metadata
@ -1864,84 +1940,6 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
return null;
}
@override
DecoratedType? visitTypeName(TypeName typeName) {
try {
_typeNameNesting++;
var typeArguments = typeName.typeArguments?.arguments;
var element = typeName.name.staticElement;
if (element is TypeAliasElement) {
var aliasedElement =
element.aliasedElement as GenericFunctionTypeElement;
final typedefType = _variables!.decoratedElementType(aliasedElement);
final typeNameType =
_variables!.decoratedTypeAnnotation(source, typeName);
Map<TypeParameterElement, DecoratedType> substitutions;
if (typeName.typeArguments == null) {
// TODO(mfairhurst): substitute instantiations to bounds
substitutions = {};
} else {
substitutions =
Map<TypeParameterElement, DecoratedType>.fromIterables(
element.typeParameters,
typeName.typeArguments!.arguments.map(
(t) => _variables!.decoratedTypeAnnotation(source, t)));
}
final decoratedType = typedefType.substitute(substitutions);
final origin = TypedefReferenceOrigin(source, typeName);
_linkDecoratedTypeParameters(decoratedType, typeNameType, origin,
isUnion: true);
_linkDecoratedTypes(
decoratedType.returnType!, typeNameType.returnType, origin,
isUnion: true);
} else if (element is TypeParameterizedElement) {
if (typeArguments == null) {
var instantiatedType =
_variables!.decoratedTypeAnnotation(source, typeName);
var origin = InstantiateToBoundsOrigin(source, typeName);
for (int i = 0; i < instantiatedType.typeArguments.length; i++) {
_linkDecoratedTypes(
instantiatedType.typeArguments[i]!,
_variables!
.decoratedTypeParameterBound(element.typeParameters[i]),
origin,
isUnion: false);
}
} else {
for (int i = 0; i < typeArguments.length; i++) {
DecoratedType? bound;
bound = _variables!
.decoratedTypeParameterBound(element.typeParameters[i]);
assert(bound != null);
var argumentType =
_variables!.decoratedTypeAnnotation(source, typeArguments[i]);
_checkAssignment(
TypeParameterInstantiationOrigin(source, typeArguments[i]),
FixReasonTarget.root,
source: argumentType,
destination: bound!,
hard: true);
}
}
}
typeName.visitChildren(this);
// If the type name is followed by a `/*!*/` comment, it is considered to
// apply to the type and not to the "as" expression. In order to prevent
// a future call to _handleNullCheck from interpreting it as applying to
// the "as" expression, we need to store the `/*!*/` comment in
// _nullCheckHints.
var token = typeName.endToken;
_nullCheckHints[token] = getPostfixHint(token);
namedTypeVisited(
typeName); // Note this has been visited to TypeNameTracker.
return null;
} finally {
_typeNameNesting--;
}
}
@override
DecoratedType? visitVariableDeclarationList(VariableDeclarationList node) {
var parent = node.parent;

View file

@ -1458,6 +1458,9 @@ class _NodeChangeVisitor extends GeneralizingAstVisitor<NodeChange<AstNode>> {
NodeChange visitMethodInvocation(MethodInvocation node) =>
NodeChangeForMethodInvocation();
@override
NodeChange visitNamedType(NamedType node) => NodeChangeForTypeAnnotation();
@override
NodeChange visitNode(AstNode node) =>
throw StateError('Unexpected node type: ${node.runtimeType}');
@ -1492,9 +1495,6 @@ class _NodeChangeVisitor extends GeneralizingAstVisitor<NodeChange<AstNode>> {
}
}
@override
NodeChange visitTypeName(TypeName node) => NodeChangeForTypeAnnotation();
@override
NodeChange visitVariableDeclarationList(VariableDeclarationList node) =>
NodeChangeForVariableDeclarationList();

View file

@ -1223,7 +1223,7 @@ class _FixBuilderPreVisitor extends GeneralizingAstVisitor<void>
}
@override
void visitTypeName(TypeName node) {
void visitNamedType(NamedType node) {
var decoratedType = _fixBuilder._variables!
.decoratedTypeAnnotation(_fixBuilder.source, node);
if (!typeIsNonNullableByContext(node)) {
@ -1233,7 +1233,7 @@ class _FixBuilderPreVisitor extends GeneralizingAstVisitor<void>
}
(node as TypeNameImpl).type =
_fixBuilder._variables!.toFinalType(decoratedType);
super.visitTypeName(node);
super.visitNamedType(node);
}
void _addRequiredKeyword(DefaultFormalParameter parameter,

View file

@ -498,6 +498,12 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
return null;
}
@override
DecoratedType visitNamedType(NamedType node) {
namedTypeVisited(node); // Note this has been visited to NamedTypeTracker.
return visitTypeAnnotation(node);
}
@override
DecoratedType? visitSetOrMapLiteral(SetOrMapLiteral node) {
var typeArguments = node.typeArguments;
@ -619,12 +625,6 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
return decoratedType;
}
@override
DecoratedType visitTypeName(TypeName node) {
namedTypeVisited(node); // Note this has been visited to TypeNameTracker.
return visitTypeAnnotation(node);
}
@override
DecoratedType? visitTypeParameter(TypeParameter node) {
var element = node.declaredElement!;

View file

@ -9,6 +9,24 @@ import 'package:analyzer/dart/ast/visitor.dart';
class NamedTypeTracker extends RecursiveAstVisitor<void> {
final Set<NamedType> _nodes = {};
void finalize() {
assert(_nodes.isEmpty, 'Annotation nodes not visited: $_nodes');
}
void nodeVisited(NamedType node) {
if (_isTrueNamedType(node) && !_nodes.remove(node)) {
throw StateError('Visited unexpected type name $node');
}
}
@override
void visitNamedType(NamedType node) {
if (_isTrueNamedType(node)) {
_nodes.add(node);
}
super.visitNamedType(node);
}
bool _isTrueNamedType(NamedType node) {
final parent = node.parent;
if (parent is ConstructorName) {
@ -18,22 +36,4 @@ class NamedTypeTracker extends RecursiveAstVisitor<void> {
return true;
}
@override
void visitTypeName(TypeName node) {
if (_isTrueNamedType(node)) {
_nodes.add(node);
}
super.visitTypeName(node);
}
void nodeVisited(NamedType node) {
if (_isTrueNamedType(node) && !_nodes.remove(node)) {
throw StateError('Visited unexpected type name $node');
}
}
void finalize() {
assert(_nodes.isEmpty, 'Annotation nodes not visited: $_nodes');
}
}