mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
Use CatchClauseParameter instead of SimpleIdentifier.
Change-Id: Ib254d05954548d4101fef9c2545d18b2611b59dd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/253100 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
d7d15aa5b8
commit
33b672f789
41 changed files with 419 additions and 251 deletions
|
@ -391,8 +391,8 @@ class FeatureComputer {
|
|||
}
|
||||
}
|
||||
} else if (node is CatchClause) {
|
||||
if (node.exceptionParameter?.staticElement == variable ||
|
||||
node.stackTraceParameter?.staticElement == variable) {
|
||||
if (node.exceptionParameter2?.declaredElement == variable ||
|
||||
node.stackTraceParameter2?.declaredElement == variable) {
|
||||
return distance;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import 'package:analysis_server/src/provisional/completion/dart/completion_dart.
|
|||
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
|
||||
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/dart/ast/token.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
|
||||
|
@ -362,11 +363,10 @@ class _LocalVisitor extends LocalDeclarationVisitor {
|
|||
}
|
||||
|
||||
@override
|
||||
void declaredParam(SimpleIdentifier name, TypeAnnotation? type) {
|
||||
var element = name.staticElement;
|
||||
void declaredParam(Token name, Element? element, TypeAnnotation? type) {
|
||||
if (visibilityTracker._isVisible(element) &&
|
||||
opType.includeReturnValueSuggestions) {
|
||||
if (_isUnused(name.name)) {
|
||||
if (_isUnused(name.lexeme)) {
|
||||
return;
|
||||
}
|
||||
if (element is ParameterElement) {
|
||||
|
|
|
@ -8,6 +8,7 @@ import 'package:analysis_server/src/protocol_server.dart' as protocol;
|
|||
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
|
||||
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/dart/ast/token.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor.dart';
|
||||
|
@ -205,8 +206,8 @@ class _LocalBestTypeVisitor extends LocalDeclarationVisitor {
|
|||
}
|
||||
|
||||
@override
|
||||
void declaredParam(SimpleIdentifier name, TypeAnnotation? type) {
|
||||
if (name.name == targetName) {
|
||||
void declaredParam(Token name, Element? element, TypeAnnotation? type) {
|
||||
if (name.lexeme == targetName) {
|
||||
// Type provided by the element in computeFull above.
|
||||
finished();
|
||||
}
|
||||
|
|
|
@ -1013,7 +1013,7 @@ class StatementCompletionProcessor {
|
|||
var struct = _KeywordConditionBlockStructure(
|
||||
catchKeyword,
|
||||
catchNode.leftParenthesis!,
|
||||
catchNode.exceptionParameter!,
|
||||
catchNode.exceptionParameter2!,
|
||||
catchNode.rightParenthesis!,
|
||||
catchNode.body);
|
||||
if (sb != null) {
|
||||
|
@ -1126,7 +1126,7 @@ class StatementCompletionProcessor {
|
|||
p?.parent?.parent is! Statement;
|
||||
}
|
||||
|
||||
bool _isSyntheticExpression(Expression? expr) {
|
||||
bool _isSyntheticExpression(AstNode? expr) {
|
||||
return expr is SimpleIdentifier && expr.isSynthetic;
|
||||
}
|
||||
|
||||
|
@ -1229,7 +1229,7 @@ class StatementCompletionProcessor {
|
|||
class _KeywordConditionBlockStructure {
|
||||
final Token keyword;
|
||||
final Token leftParenthesis, rightParenthesis;
|
||||
final Expression condition;
|
||||
final AstNode condition;
|
||||
final Statement? block;
|
||||
|
||||
_KeywordConditionBlockStructure(this.keyword, this.leftParenthesis,
|
||||
|
|
|
@ -57,7 +57,7 @@ class AssignToLocalVariable extends CorrectionProducer {
|
|||
var excluded = <String>{};
|
||||
var scopedNameFinder = ScopedNameFinder(offset);
|
||||
expression.accept(scopedNameFinder);
|
||||
excluded.addAll(scopedNameFinder.locals.keys.toSet());
|
||||
excluded.addAll(scopedNameFinder.locals);
|
||||
var suggestions =
|
||||
getVariableNameSuggestionsForExpression(type, expression, excluded);
|
||||
|
||||
|
|
|
@ -20,18 +20,18 @@ class ConvertToOnType extends CorrectionProducer {
|
|||
Future<void> compute(ChangeBuilder builder) async {
|
||||
var exceptionParameter = node;
|
||||
if (exceptionParameter is SimpleIdentifier) {
|
||||
var catchClause = exceptionParameter.parent;
|
||||
var catchClause = exceptionParameter.parent?.parent;
|
||||
if (catchClause is CatchClause) {
|
||||
var catchKeyword = catchClause.catchKeyword;
|
||||
var rightParenthesis = catchClause.rightParenthesis;
|
||||
if (catchKeyword != null &&
|
||||
catchClause.exceptionType == null &&
|
||||
catchClause.exceptionParameter == exceptionParameter &&
|
||||
catchClause.exceptionParameter2?.name == exceptionParameter.token &&
|
||||
rightParenthesis != null) {
|
||||
var exceptionTypeName = exceptionParameter.name;
|
||||
fixArguments.add(exceptionTypeName);
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
var stackTraceParameter = catchClause.stackTraceParameter;
|
||||
var stackTraceParameter = catchClause.stackTraceParameter2;
|
||||
if (stackTraceParameter != null) {
|
||||
builder.addSimpleReplacement(
|
||||
range.startStart(catchKeyword, stackTraceParameter),
|
||||
|
|
|
@ -42,7 +42,7 @@ class IntroduceLocalCastType extends CorrectionProducer {
|
|||
var excluded = <String>{};
|
||||
var scopedNameFinder = ScopedNameFinder(offset);
|
||||
isExpression.accept(scopedNameFinder);
|
||||
excluded.addAll(scopedNameFinder.locals.keys.toSet());
|
||||
excluded.addAll(scopedNameFinder.locals);
|
||||
// name(s)
|
||||
var suggestions =
|
||||
getVariableNameSuggestionsForExpression(castType, null, excluded);
|
||||
|
|
|
@ -24,7 +24,12 @@ class RemoveUnusedCatchClause extends CorrectionProducer {
|
|||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
var catchClause = node.parent;
|
||||
final exceptionParameter = node.parent;
|
||||
if (exceptionParameter is! CatchClauseParameter) {
|
||||
return;
|
||||
}
|
||||
|
||||
final catchClause = exceptionParameter.parent;
|
||||
if (catchClause is! CatchClause) {
|
||||
return;
|
||||
}
|
||||
|
@ -34,7 +39,7 @@ class RemoveUnusedCatchClause extends CorrectionProducer {
|
|||
return;
|
||||
}
|
||||
|
||||
if (catchClause.exceptionParameter == node) {
|
||||
if (catchClause.exceptionParameter2 == exceptionParameter) {
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addDeletion(range.startStart(catchKeyword, catchClause.body));
|
||||
});
|
||||
|
|
|
@ -24,19 +24,26 @@ class RemoveUnusedCatchStack extends CorrectionProducer {
|
|||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
var catchClause = node.parent;
|
||||
final stackTraceParameter = node.parent;
|
||||
if (stackTraceParameter is! CatchClauseParameter) {
|
||||
return;
|
||||
}
|
||||
|
||||
final catchClause = stackTraceParameter.parent;
|
||||
if (catchClause is! CatchClause) {
|
||||
return;
|
||||
}
|
||||
|
||||
var exceptionParameter = catchClause.exceptionParameter;
|
||||
final exceptionParameter = catchClause.exceptionParameter2;
|
||||
if (exceptionParameter == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (catchClause.stackTraceParameter == node) {
|
||||
if (catchClause.stackTraceParameter2 == stackTraceParameter) {
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addDeletion(range.endEnd(exceptionParameter, node));
|
||||
builder.addDeletion(
|
||||
range.endEnd(exceptionParameter, stackTraceParameter),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ class StatementAnalyzer extends SelectionAnalyzer {
|
|||
for (var catchClause in catchClauses) {
|
||||
if (firstSelectedNode == catchClause ||
|
||||
firstSelectedNode == catchClause.body ||
|
||||
firstSelectedNode == catchClause.exceptionParameter) {
|
||||
firstSelectedNode == catchClause.exceptionParameter2) {
|
||||
invalidSelection(
|
||||
'Selection must either cover whole try statement or parts of try, catch, or finally block.');
|
||||
}
|
||||
|
|
|
@ -929,6 +929,14 @@ class _ExtractMethodAnalyzer extends StatementAnalyzer {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visitCatchClauseParameter(CatchClauseParameter node) {
|
||||
super.visitCatchClauseParameter(node);
|
||||
if (_isFirstSelectedNode(node)) {
|
||||
invalidSelection('Cannot extract the name part of a declaration.');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visitConstructorInitializer(ConstructorInitializer node) {
|
||||
super.visitConstructorInitializer(node);
|
||||
|
|
|
@ -14,8 +14,8 @@ class VisibleRangesComputer extends GeneralizingAstVisitor<void> {
|
|||
|
||||
@override
|
||||
void visitCatchClause(CatchClause node) {
|
||||
_addLocalVariable(node, node.exceptionParameter?.staticElement);
|
||||
_addLocalVariable(node, node.stackTraceParameter?.staticElement);
|
||||
_addLocalVariable(node, node.exceptionParameter2?.declaredElement);
|
||||
_addLocalVariable(node, node.stackTraceParameter2?.declaredElement);
|
||||
node.body.accept(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -294,8 +294,8 @@ class CodeShapeDataCollector extends RecursiveAstVisitor<void> {
|
|||
void visitCatchClause(CatchClause node) {
|
||||
_visitChildren(node, {
|
||||
'exceptionType': node.exceptionType,
|
||||
'exceptionParameter': node.exceptionParameter,
|
||||
'stackTraceParameter': node.stackTraceParameter,
|
||||
'exceptionParameter': node.exceptionParameter2,
|
||||
'stackTraceParameter': node.stackTraceParameter2,
|
||||
'body': node.body,
|
||||
});
|
||||
super.visitCatchClause(node);
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
Use `Directive.element2.uri` instead.
|
||||
* Deprecated `NamespaceDirective.selectedSource`, use `element2.uri` with `DirectiveUriWithSource` instead.
|
||||
* Deprecated `Configuration.uriSource`, use `resolvedUri` instead.
|
||||
* Deprecated `CatchClause.exceptionParameter` and `CatchClause.stackTraceParameter`.
|
||||
Use `exceptionParameter2` and `stackTraceParameter2` instead.
|
||||
|
||||
## 4.3.1
|
||||
* Fix `identifier` for `LibraryExportElement` and `LibraryImportElement`.
|
||||
|
|
|
@ -383,6 +383,8 @@ abstract class AstVisitor<R> {
|
|||
|
||||
R? visitCatchClause(CatchClause node);
|
||||
|
||||
R? visitCatchClauseParameter(CatchClauseParameter node);
|
||||
|
||||
R? visitClassDeclaration(ClassDeclaration node);
|
||||
|
||||
R? visitClassTypeAlias(ClassTypeAlias node);
|
||||
|
@ -804,8 +806,13 @@ abstract class CatchClause implements AstNode {
|
|||
|
||||
/// Return the parameter whose value will be the exception that was thrown, or
|
||||
/// `null` if there is no 'catch' keyword.
|
||||
@Deprecated('Use exceptionParameter2 instead')
|
||||
SimpleIdentifier? get exceptionParameter;
|
||||
|
||||
/// Return the parameter whose value will be the exception that was thrown, or
|
||||
/// `null` if there is no 'catch' keyword.
|
||||
CatchClauseParameter? get exceptionParameter2;
|
||||
|
||||
/// Return the type of exceptions caught by this catch clause, or `null` if
|
||||
/// this catch clause catches every type of exception.
|
||||
TypeAnnotation? get exceptionType;
|
||||
|
@ -822,7 +829,23 @@ abstract class CatchClause implements AstNode {
|
|||
|
||||
/// Return the parameter whose value will be the stack trace associated with
|
||||
/// the exception, or `null` if there is no stack trace parameter.
|
||||
@Deprecated('Use stackTraceParameter2 instead')
|
||||
SimpleIdentifier? get stackTraceParameter;
|
||||
|
||||
/// Return the parameter whose value will be the stack trace associated with
|
||||
/// the exception, or `null` if there is no stack trace parameter.
|
||||
CatchClauseParameter? get stackTraceParameter2;
|
||||
}
|
||||
|
||||
/// The 'exception' or 'stackTrace' parameter in [CatchClause].
|
||||
///
|
||||
/// Clients may not extend, implement or mix-in this class.
|
||||
abstract class CatchClauseParameter extends AstNode {
|
||||
/// The declared element, or `null` if the AST has not been resolved.
|
||||
LocalVariableElement? get declaredElement;
|
||||
|
||||
/// The name of the parameter.
|
||||
Token get name;
|
||||
}
|
||||
|
||||
/// The declaration of a class.
|
||||
|
|
|
@ -181,6 +181,9 @@ class GeneralizingAstVisitor<R> implements AstVisitor<R> {
|
|||
@override
|
||||
R? visitCatchClause(CatchClause node) => visitNode(node);
|
||||
|
||||
@override
|
||||
R? visitCatchClauseParameter(CatchClauseParameter node) => visitNode(node);
|
||||
|
||||
@override
|
||||
R? visitClassDeclaration(ClassDeclaration node) =>
|
||||
visitNamedCompilationUnitMember(node);
|
||||
|
@ -755,6 +758,12 @@ class RecursiveAstVisitor<R> implements AstVisitor<R> {
|
|||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
R? visitCatchClauseParameter(CatchClauseParameter node) {
|
||||
node.visitChildren(this);
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
R? visitClassDeclaration(ClassDeclaration node) {
|
||||
node.visitChildren(this);
|
||||
|
@ -1517,6 +1526,9 @@ class SimpleAstVisitor<R> implements AstVisitor<R> {
|
|||
@override
|
||||
R? visitCatchClause(CatchClause node) => null;
|
||||
|
||||
@override
|
||||
R? visitCatchClauseParameter(CatchClauseParameter node) => null;
|
||||
|
||||
@override
|
||||
R? visitClassDeclaration(ClassDeclaration node) => null;
|
||||
|
||||
|
@ -1937,6 +1949,9 @@ class ThrowingAstVisitor<R> implements AstVisitor<R> {
|
|||
@override
|
||||
R? visitCatchClause(CatchClause node) => _throw(node);
|
||||
|
||||
@override
|
||||
R? visitCatchClauseParameter(CatchClauseParameter node) => _throw(node);
|
||||
|
||||
@override
|
||||
R? visitClassDeclaration(ClassDeclaration node) => _throw(node);
|
||||
|
||||
|
@ -2451,6 +2466,14 @@ class TimedAstVisitor<T> implements AstVisitor<T> {
|
|||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
T? visitCatchClauseParameter(CatchClauseParameter node) {
|
||||
stopwatch.start();
|
||||
T? result = _baseVisitor.visitCatchClauseParameter(node);
|
||||
stopwatch.stop();
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
T? visitClassDeclaration(ClassDeclaration node) {
|
||||
stopwatch.start();
|
||||
|
@ -3453,6 +3476,9 @@ class UnifyingAstVisitor<R> implements AstVisitor<R> {
|
|||
@override
|
||||
R? visitCatchClause(CatchClause node) => visitNode(node);
|
||||
|
||||
@override
|
||||
R? visitCatchClauseParameter(CatchClauseParameter node) => visitNode(node);
|
||||
|
||||
@override
|
||||
R? visitClassDeclaration(ClassDeclaration node) => visitNode(node);
|
||||
|
||||
|
|
|
@ -1411,7 +1411,7 @@ class CatchClauseImpl extends AstNodeImpl implements CatchClause {
|
|||
|
||||
/// The parameter whose value will be the exception that was thrown, or `null`
|
||||
/// if there is no 'catch' keyword.
|
||||
SimpleIdentifierImpl? _exceptionParameter;
|
||||
CatchClauseParameterImpl? _exceptionParameter;
|
||||
|
||||
/// The comma separating the exception parameter from the stack trace
|
||||
/// parameter, or `null` if there is no stack trace parameter.
|
||||
|
@ -1420,7 +1420,7 @@ class CatchClauseImpl extends AstNodeImpl implements CatchClause {
|
|||
|
||||
/// The parameter whose value will be the stack trace associated with the
|
||||
/// exception, or `null` if there is no stack trace parameter.
|
||||
SimpleIdentifierImpl? _stackTraceParameter;
|
||||
CatchClauseParameterImpl? _stackTraceParameter;
|
||||
|
||||
/// The right parenthesis, or `null` if there is no 'catch' keyword.
|
||||
@override
|
||||
|
@ -1431,7 +1431,7 @@ class CatchClauseImpl extends AstNodeImpl implements CatchClause {
|
|||
|
||||
/// Initialize a newly created catch clause. The [onKeyword] and
|
||||
/// [exceptionType] can be `null` if the clause will catch all exceptions. The
|
||||
/// [comma] and [stackTraceParameter] can be `null` if the stack trace
|
||||
/// [comma] and [_stackTraceParameter] can be `null` if the stack trace
|
||||
/// parameter is not defined.
|
||||
CatchClauseImpl(
|
||||
this.onKeyword,
|
||||
|
@ -1468,11 +1468,20 @@ class CatchClauseImpl extends AstNodeImpl implements CatchClause {
|
|||
@override
|
||||
Token get endToken => _body.endToken;
|
||||
|
||||
@Deprecated('Use exceptionParameter2 instead')
|
||||
@override
|
||||
SimpleIdentifierImpl? get exceptionParameter => _exceptionParameter;
|
||||
SimpleIdentifierImpl? get exceptionParameter {
|
||||
return _exceptionParameter?.nameNode;
|
||||
}
|
||||
|
||||
set exceptionParameter(SimpleIdentifier? parameter) {
|
||||
_exceptionParameter = _becomeParentOf(parameter as SimpleIdentifierImpl?);
|
||||
@override
|
||||
CatchClauseParameterImpl? get exceptionParameter2 {
|
||||
return _exceptionParameter;
|
||||
}
|
||||
|
||||
set exceptionParameter2(CatchClauseParameterImpl? parameter) {
|
||||
_exceptionParameter = parameter;
|
||||
_becomeParentOf(parameter);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1482,11 +1491,20 @@ class CatchClauseImpl extends AstNodeImpl implements CatchClause {
|
|||
_exceptionType = _becomeParentOf(exceptionType as TypeAnnotationImpl?);
|
||||
}
|
||||
|
||||
@Deprecated('Use stackTraceParameter2 instead')
|
||||
@override
|
||||
SimpleIdentifierImpl? get stackTraceParameter => _stackTraceParameter;
|
||||
SimpleIdentifierImpl? get stackTraceParameter {
|
||||
return _stackTraceParameter?.nameNode;
|
||||
}
|
||||
|
||||
set stackTraceParameter(SimpleIdentifier? parameter) {
|
||||
_stackTraceParameter = _becomeParentOf(parameter as SimpleIdentifierImpl?);
|
||||
@override
|
||||
CatchClauseParameterImpl? get stackTraceParameter2 {
|
||||
return _stackTraceParameter;
|
||||
}
|
||||
|
||||
set stackTraceParameter2(CatchClauseParameterImpl? parameter) {
|
||||
_stackTraceParameter = parameter;
|
||||
_becomeParentOf(parameter);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1495,9 +1513,9 @@ class CatchClauseImpl extends AstNodeImpl implements CatchClause {
|
|||
..addNode('exceptionType', exceptionType)
|
||||
..addToken('catchKeyword', catchKeyword)
|
||||
..addToken('leftParenthesis', leftParenthesis)
|
||||
..addNode('exceptionParameter', exceptionParameter)
|
||||
..addNode('exceptionParameter', exceptionParameter2)
|
||||
..addToken('comma', comma)
|
||||
..addNode('stackTraceParameter', stackTraceParameter)
|
||||
..addNode('stackTraceParameter', stackTraceParameter2)
|
||||
..addToken('rightParenthesis', rightParenthesis)
|
||||
..addNode('body', body);
|
||||
|
||||
|
@ -1513,6 +1531,40 @@ class CatchClauseImpl extends AstNodeImpl implements CatchClause {
|
|||
}
|
||||
}
|
||||
|
||||
class CatchClauseParameterImpl extends AstNodeImpl
|
||||
implements CatchClauseParameter {
|
||||
/// TODO(scheglov) Eventually replace with [Token].
|
||||
final SimpleIdentifierImpl nameNode;
|
||||
|
||||
@override
|
||||
LocalVariableElement? declaredElement;
|
||||
|
||||
CatchClauseParameterImpl({
|
||||
required this.nameNode,
|
||||
}) {
|
||||
_becomeParentOf(nameNode);
|
||||
}
|
||||
|
||||
@override
|
||||
Token get beginToken => name;
|
||||
|
||||
@override
|
||||
Token get endToken => name;
|
||||
|
||||
@override
|
||||
Token get name => nameNode.token;
|
||||
|
||||
@override
|
||||
E? accept<E>(AstVisitor<E> visitor) {
|
||||
return visitor.visitCatchClauseParameter(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitChildren(AstVisitor visitor) {
|
||||
nameNode.accept(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper class to allow iteration of child entities of an AST node.
|
||||
class ChildEntities {
|
||||
/// The list of child entities to be iterated over.
|
||||
|
@ -9958,6 +10010,9 @@ class SimpleIdentifierImpl extends IdentifierImpl implements SimpleIdentifier {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (parent is CatchClauseParameterImpl && parent.nameNode == this) {
|
||||
return false;
|
||||
}
|
||||
if (parent is ConstructorFieldInitializer &&
|
||||
identical(parent.fieldName, target)) {
|
||||
return false;
|
||||
|
|
|
@ -53,27 +53,6 @@ class AstFactoryImpl {
|
|||
Expression target, List<Expression> cascadeSections) =>
|
||||
CascadeExpressionImpl(target as ExpressionImpl, cascadeSections);
|
||||
|
||||
CatchClauseImpl catchClause(
|
||||
Token? onKeyword,
|
||||
TypeAnnotation? exceptionType,
|
||||
Token? catchKeyword,
|
||||
Token? leftParenthesis,
|
||||
SimpleIdentifier? exceptionParameter,
|
||||
Token? comma,
|
||||
SimpleIdentifier? stackTraceParameter,
|
||||
Token? rightParenthesis,
|
||||
Block body) =>
|
||||
CatchClauseImpl(
|
||||
onKeyword,
|
||||
exceptionType as TypeAnnotationImpl?,
|
||||
catchKeyword,
|
||||
leftParenthesis,
|
||||
exceptionParameter as SimpleIdentifierImpl?,
|
||||
comma,
|
||||
stackTraceParameter as SimpleIdentifierImpl?,
|
||||
rightParenthesis,
|
||||
body as BlockImpl);
|
||||
|
||||
ClassDeclarationImpl classDeclaration(
|
||||
Comment? comment,
|
||||
List<Annotation>? metadata,
|
||||
|
|
|
@ -146,8 +146,8 @@ class ToSourceVisitor implements AstVisitor<void> {
|
|||
sink.write(' ');
|
||||
}
|
||||
sink.write('catch (');
|
||||
_visitNode(node.exceptionParameter);
|
||||
_visitNode(node.stackTraceParameter, prefix: ', ');
|
||||
_visitNode(node.exceptionParameter2);
|
||||
_visitNode(node.stackTraceParameter2, prefix: ', ');
|
||||
sink.write(') ');
|
||||
} else {
|
||||
sink.write(' ');
|
||||
|
@ -155,6 +155,11 @@ class ToSourceVisitor implements AstVisitor<void> {
|
|||
_visitNode(node.body);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitCatchClauseParameter(CatchClauseParameter node) {
|
||||
_visitToken(node.name);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitClassDeclaration(covariant ClassDeclarationImpl node) {
|
||||
_visitNodeList(node.metadata, separator: ' ', suffix: ' ');
|
||||
|
@ -1184,8 +1189,9 @@ class ToSourceVisitor implements AstVisitor<void> {
|
|||
}
|
||||
|
||||
/// Print the given [token].
|
||||
void _visitToken(Token? token, {String suffix = ''}) {
|
||||
void _visitToken(Token? token, {String prefix = '', String suffix = ''}) {
|
||||
if (token != null) {
|
||||
sink.write(prefix);
|
||||
sink.write(token.lexeme);
|
||||
sink.write(suffix);
|
||||
}
|
||||
|
|
|
@ -2,8 +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 'dart:collection';
|
||||
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/dart/ast/token.dart';
|
||||
import 'package:analyzer/dart/ast/visitor.dart';
|
||||
|
@ -230,13 +228,19 @@ class AstComparator implements AstVisitor<bool> {
|
|||
isEqualNodes(node.exceptionType, other.exceptionType) &&
|
||||
isEqualTokens(node.catchKeyword, other.catchKeyword) &&
|
||||
isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
|
||||
isEqualNodes(node.exceptionParameter, other.exceptionParameter) &&
|
||||
isEqualNodes(node.exceptionParameter2, other.exceptionParameter2) &&
|
||||
isEqualTokens(node.comma, other.comma) &&
|
||||
isEqualNodes(node.stackTraceParameter, other.stackTraceParameter) &&
|
||||
isEqualNodes(node.stackTraceParameter2, other.stackTraceParameter2) &&
|
||||
isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
|
||||
isEqualNodes(node.body, other.body);
|
||||
}
|
||||
|
||||
@override
|
||||
bool visitCatchClauseParameter(CatchClauseParameter node) {
|
||||
CatchClauseParameter other = _other as CatchClauseParameter;
|
||||
return isEqualTokens(node.name, other.name);
|
||||
}
|
||||
|
||||
@override
|
||||
bool visitClassDeclaration(ClassDeclaration node) {
|
||||
ClassDeclaration other = _other as ClassDeclaration;
|
||||
|
@ -1781,11 +1785,11 @@ class NodeReplacer implements AstVisitor<bool> {
|
|||
if (identical(node.exceptionType, _oldNode)) {
|
||||
node.exceptionType = _newNode as TypeAnnotation;
|
||||
return true;
|
||||
} else if (identical(node.exceptionParameter, _oldNode)) {
|
||||
node.exceptionParameter = _newNode as SimpleIdentifier;
|
||||
} else if (identical(node.exceptionParameter2, _oldNode)) {
|
||||
node.exceptionParameter2 = _newNode as CatchClauseParameterImpl;
|
||||
return true;
|
||||
} else if (identical(node.stackTraceParameter, _oldNode)) {
|
||||
node.stackTraceParameter = _newNode as SimpleIdentifier;
|
||||
} else if (identical(node.stackTraceParameter2, _oldNode)) {
|
||||
node.stackTraceParameter2 = _newNode as CatchClauseParameterImpl;
|
||||
return true;
|
||||
} else if (identical(node.body, _oldNode)) {
|
||||
node.body = _newNode as Block;
|
||||
|
@ -1794,6 +1798,11 @@ class NodeReplacer implements AstVisitor<bool> {
|
|||
return visitNode(node);
|
||||
}
|
||||
|
||||
@override
|
||||
bool? visitCatchClauseParameter(CatchClauseParameter node) {
|
||||
return visitNode(node);
|
||||
}
|
||||
|
||||
@override
|
||||
bool visitClassDeclaration(covariant ClassDeclarationImpl node) {
|
||||
if (identical(node.name, _oldNode)) {
|
||||
|
@ -3144,8 +3153,7 @@ class ScopedNameFinder extends GeneralizingAstVisitor<void> {
|
|||
|
||||
AstNode? _immediateChild;
|
||||
|
||||
final Map<String, SimpleIdentifier> _locals =
|
||||
HashMap<String, SimpleIdentifier>();
|
||||
final Set<String> _locals = {};
|
||||
|
||||
final int _position;
|
||||
|
||||
|
@ -3155,7 +3163,7 @@ class ScopedNameFinder extends GeneralizingAstVisitor<void> {
|
|||
|
||||
Declaration? get declaration => _declarationNode;
|
||||
|
||||
Map<String, SimpleIdentifier> get locals => _locals;
|
||||
Set<String> get locals => _locals;
|
||||
|
||||
@override
|
||||
void visitBlock(Block node) {
|
||||
|
@ -3165,8 +3173,8 @@ class ScopedNameFinder extends GeneralizingAstVisitor<void> {
|
|||
|
||||
@override
|
||||
void visitCatchClause(CatchClause node) {
|
||||
_addToScope(node.exceptionParameter);
|
||||
_addToScope(node.stackTraceParameter);
|
||||
_addToScope2(node.exceptionParameter2?.name);
|
||||
_addToScope2(node.stackTraceParameter2?.name);
|
||||
super.visitCatchClause(node);
|
||||
}
|
||||
|
||||
|
@ -3258,10 +3266,16 @@ class ScopedNameFinder extends GeneralizingAstVisitor<void> {
|
|||
|
||||
void _addToScope(SimpleIdentifier? identifier) {
|
||||
if (identifier != null && _isInRange(identifier)) {
|
||||
String name = identifier.name;
|
||||
if (!_locals.containsKey(name)) {
|
||||
_locals[name] = identifier;
|
||||
}
|
||||
_locals.add(identifier.name);
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO(scheglov) If we still have [_addToScope] after:
|
||||
/// https://dart-review.googlesource.com/c/sdk/+/252566,
|
||||
/// rename to `_addNodeToScope` and `_addTokenToScope`.
|
||||
void _addToScope2(Token? identifier) {
|
||||
if (identifier != null && _isInRange2(identifier)) {
|
||||
_locals.add(identifier.lexeme);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3296,4 +3310,13 @@ class ScopedNameFinder extends GeneralizingAstVisitor<void> {
|
|||
}
|
||||
return node.end < _position;
|
||||
}
|
||||
|
||||
bool _isInRange2(Token token) {
|
||||
if (_position < 0) {
|
||||
// if source position is not set then all nodes are in range
|
||||
return true;
|
||||
// not reached
|
||||
}
|
||||
return token.end < _position;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -466,12 +466,11 @@ class _AssignedVariablesVisitor extends RecursiveAstVisitor<void> {
|
|||
@override
|
||||
void visitCatchClause(CatchClause node) {
|
||||
for (var identifier in [
|
||||
node.exceptionParameter,
|
||||
node.stackTraceParameter
|
||||
node.exceptionParameter2,
|
||||
node.stackTraceParameter2,
|
||||
]) {
|
||||
if (identifier != null) {
|
||||
assignedVariables
|
||||
.declare(identifier.staticElement as PromotableElement);
|
||||
assignedVariables.declare(identifier.declaredElement!);
|
||||
}
|
||||
}
|
||||
super.visitCatchClause(node);
|
||||
|
|
|
@ -181,16 +181,17 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
|
|||
exceptionTypeNode?.accept(this);
|
||||
|
||||
_withNameScope(() {
|
||||
var exceptionNode = node.exceptionParameter;
|
||||
var exceptionNode = node.exceptionParameter2;
|
||||
if (exceptionNode != null) {
|
||||
var element = LocalVariableElementImpl(
|
||||
exceptionNode.name,
|
||||
exceptionNode.offset,
|
||||
exceptionNode.name.lexeme,
|
||||
exceptionNode.name.offset,
|
||||
);
|
||||
_elementHolder.enclose(element);
|
||||
_define(element);
|
||||
|
||||
exceptionNode.staticElement = element;
|
||||
exceptionNode.declaredElement = element;
|
||||
exceptionNode.nameNode.staticElement = element;
|
||||
|
||||
element.isFinal = true;
|
||||
if (exceptionTypeNode == null) {
|
||||
|
@ -198,31 +199,38 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
|
|||
var type =
|
||||
_isNonNullableByDefault ? _typeProvider.objectType : _dynamicType;
|
||||
element.type = type;
|
||||
exceptionNode.staticType = type;
|
||||
exceptionNode.nameNode.staticType = type;
|
||||
} else {
|
||||
element.type = exceptionTypeNode.typeOrThrow;
|
||||
exceptionNode.staticType = exceptionTypeNode.type;
|
||||
exceptionNode.nameNode.staticType = exceptionTypeNode.type;
|
||||
}
|
||||
|
||||
_setCodeRange(element, exceptionNode);
|
||||
element.setCodeRange(
|
||||
exceptionNode.name.offset,
|
||||
exceptionNode.name.length,
|
||||
);
|
||||
}
|
||||
|
||||
var stackTraceNode = node.stackTraceParameter;
|
||||
var stackTraceNode = node.stackTraceParameter2;
|
||||
if (stackTraceNode != null) {
|
||||
var element = LocalVariableElementImpl(
|
||||
stackTraceNode.name,
|
||||
stackTraceNode.offset,
|
||||
stackTraceNode.name.lexeme,
|
||||
stackTraceNode.name.offset,
|
||||
);
|
||||
_elementHolder.enclose(element);
|
||||
_define(element);
|
||||
|
||||
stackTraceNode.staticElement = element;
|
||||
stackTraceNode.declaredElement = element;
|
||||
stackTraceNode.nameNode.staticElement = element;
|
||||
|
||||
element.isFinal = true;
|
||||
element.type = _typeProvider.stackTraceType;
|
||||
stackTraceNode.staticType = _typeProvider.stackTraceType;
|
||||
stackTraceNode.nameNode.staticType = _typeProvider.stackTraceType;
|
||||
|
||||
_setCodeRange(element, stackTraceNode);
|
||||
element.setCodeRange(
|
||||
stackTraceNode.name.offset,
|
||||
stackTraceNode.name.length,
|
||||
);
|
||||
}
|
||||
|
||||
node.body.accept(this);
|
||||
|
|
|
@ -25,11 +25,11 @@ class DuplicateDefinitionVerifier {
|
|||
|
||||
/// Check that the exception and stack trace parameters have different names.
|
||||
void checkCatchClause(CatchClause node) {
|
||||
var exceptionParameter = node.exceptionParameter;
|
||||
var stackTraceParameter = node.stackTraceParameter;
|
||||
var exceptionParameter = node.exceptionParameter2;
|
||||
var stackTraceParameter = node.stackTraceParameter2;
|
||||
if (exceptionParameter != null && stackTraceParameter != null) {
|
||||
String exceptionName = exceptionParameter.name;
|
||||
if (exceptionName == stackTraceParameter.name) {
|
||||
String exceptionName = exceptionParameter.name.lexeme;
|
||||
if (exceptionName == stackTraceParameter.name.lexeme) {
|
||||
_errorReporter.reportErrorForNode(
|
||||
CompileTimeErrorCode.DUPLICATE_DEFINITION,
|
||||
stackTraceParameter,
|
||||
|
|
|
@ -52,17 +52,17 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor<void> {
|
|||
|
||||
@override
|
||||
void visitCatchClause(CatchClause node) {
|
||||
var exceptionParameter = node.exceptionParameter;
|
||||
var stackTraceParameter = node.stackTraceParameter;
|
||||
var exceptionParameter = node.exceptionParameter2;
|
||||
var stackTraceParameter = node.stackTraceParameter2;
|
||||
if (exceptionParameter != null) {
|
||||
var element = exceptionParameter.staticElement;
|
||||
var element = exceptionParameter.declaredElement;
|
||||
usedElements.addCatchException(element);
|
||||
if (stackTraceParameter != null || node.onKeyword == null) {
|
||||
usedElements.addElement(element);
|
||||
}
|
||||
}
|
||||
if (stackTraceParameter != null) {
|
||||
var element = stackTraceParameter.staticElement;
|
||||
var element = stackTraceParameter.declaredElement;
|
||||
usedElements.addCatchStackTrace(element);
|
||||
}
|
||||
super.visitCatchClause(node);
|
||||
|
|
|
@ -2745,16 +2745,27 @@ class AstBuilder extends StackListener {
|
|||
stackTrace = catchParameters[1].identifier;
|
||||
}
|
||||
}
|
||||
push(ast.catchClause(
|
||||
push(
|
||||
CatchClauseImpl(
|
||||
onKeyword,
|
||||
type,
|
||||
type as TypeAnnotationImpl?,
|
||||
catchKeyword,
|
||||
catchParameterList?.leftParenthesis,
|
||||
exception,
|
||||
exception != null
|
||||
? CatchClauseParameterImpl(
|
||||
nameNode: exception as SimpleIdentifierImpl,
|
||||
)
|
||||
: null,
|
||||
comma,
|
||||
stackTrace,
|
||||
stackTrace != null
|
||||
? CatchClauseParameterImpl(
|
||||
nameNode: stackTrace as SimpleIdentifierImpl,
|
||||
)
|
||||
: null,
|
||||
catchParameterList?.rightParenthesis,
|
||||
body));
|
||||
body as BlockImpl,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -1130,6 +1130,11 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
|
|||
node.visitChildren(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitCatchClauseParameter(CatchClauseParameter node) {
|
||||
node.visitChildren(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitClassDeclaration(ClassDeclaration node) {
|
||||
//
|
||||
|
@ -2440,8 +2445,8 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
|
|||
var catchClause = catchClauses[i];
|
||||
nullSafetyDeadCodeVerifier.verifyCatchClause(catchClause);
|
||||
flow.tryCatchStatement_catchBegin(
|
||||
catchClause.exceptionParameter?.staticElement as PromotableElement?,
|
||||
catchClause.stackTraceParameter?.staticElement as PromotableElement?,
|
||||
catchClause.exceptionParameter2?.declaredElement,
|
||||
catchClause.stackTraceParameter2?.declaredElement,
|
||||
);
|
||||
catchClause.accept(this);
|
||||
flow.tryCatchStatement_catchEnd();
|
||||
|
@ -2990,15 +2995,15 @@ class ScopeResolverVisitor extends UnifyingAstVisitor<void> {
|
|||
|
||||
@override
|
||||
void visitCatchClause(CatchClause node) {
|
||||
var exception = node.exceptionParameter;
|
||||
var exception = node.exceptionParameter2;
|
||||
if (exception != null) {
|
||||
Scope outerScope = nameScope;
|
||||
try {
|
||||
nameScope = LocalScope(nameScope);
|
||||
_define(exception.staticElement!);
|
||||
var stackTrace = node.stackTraceParameter;
|
||||
_define(exception.declaredElement!);
|
||||
var stackTrace = node.stackTraceParameter2;
|
||||
if (stackTrace != null) {
|
||||
_define(stackTrace.staticElement!);
|
||||
_define(stackTrace.declaredElement!);
|
||||
}
|
||||
super.visitCatchClause(node);
|
||||
} finally {
|
||||
|
|
|
@ -159,48 +159,6 @@ class AstTestFactory {
|
|||
return cascade;
|
||||
}
|
||||
|
||||
static CatchClauseImpl catchClause(String exceptionParameter,
|
||||
[List<Statement> statements = const []]) =>
|
||||
catchClause5(null, exceptionParameter, null, statements);
|
||||
|
||||
static CatchClauseImpl catchClause2(
|
||||
String exceptionParameter, String stackTraceParameter,
|
||||
[List<Statement> statements = const []]) =>
|
||||
catchClause5(null, exceptionParameter, stackTraceParameter, statements);
|
||||
|
||||
static CatchClauseImpl catchClause3(TypeAnnotation exceptionType,
|
||||
[List<Statement> statements = const []]) =>
|
||||
catchClause5(exceptionType, null, null, statements);
|
||||
|
||||
static CatchClauseImpl catchClause4(
|
||||
TypeAnnotation exceptionType, String exceptionParameter,
|
||||
[List<Statement> statements = const []]) =>
|
||||
catchClause5(exceptionType, exceptionParameter, null, statements);
|
||||
|
||||
static CatchClauseImpl catchClause5(TypeAnnotation? exceptionType,
|
||||
String? exceptionParameter, String? stackTraceParameter,
|
||||
[List<Statement> statements = const []]) =>
|
||||
astFactory.catchClause(
|
||||
exceptionType == null
|
||||
? null
|
||||
: TokenFactory.tokenFromTypeAndString(TokenType.IDENTIFIER, "on"),
|
||||
exceptionType,
|
||||
exceptionParameter == null
|
||||
? null
|
||||
: TokenFactory.tokenFromKeyword(Keyword.CATCH),
|
||||
exceptionParameter == null
|
||||
? null
|
||||
: TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
|
||||
exceptionParameter == null ? null : identifier3(exceptionParameter),
|
||||
stackTraceParameter == null
|
||||
? null
|
||||
: TokenFactory.tokenFromType(TokenType.COMMA),
|
||||
stackTraceParameter == null ? null : identifier3(stackTraceParameter),
|
||||
exceptionParameter == null
|
||||
? null
|
||||
: TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
|
||||
block(statements));
|
||||
|
||||
static ClassDeclarationImpl classDeclaration(
|
||||
Keyword? abstractKeyword,
|
||||
String name,
|
||||
|
|
|
@ -134,13 +134,18 @@ class AstTextPrinter extends ThrowingAstVisitor<void> {
|
|||
node.exceptionType?.accept(this);
|
||||
_token(node.catchKeyword);
|
||||
_token(node.leftParenthesis);
|
||||
node.exceptionParameter?.accept(this);
|
||||
node.exceptionParameter2?.accept(this);
|
||||
_token(node.comma);
|
||||
node.stackTraceParameter?.accept(this);
|
||||
node.stackTraceParameter2?.accept(this);
|
||||
_token(node.rightParenthesis);
|
||||
node.body.accept(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitCatchClauseParameter(CatchClauseParameter node) {
|
||||
_token(node.name);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitClassDeclaration(covariant ClassDeclarationImpl node) {
|
||||
_compilationUnitMember(node);
|
||||
|
|
|
@ -133,13 +133,11 @@ class FindElement extends _FindElementBase {
|
|||
}
|
||||
|
||||
unit.accept(FunctionAstVisitor(
|
||||
declaredIdentifier: (node) {
|
||||
catchClauseParameter: (node) {
|
||||
updateResult(node.declaredElement!);
|
||||
},
|
||||
simpleIdentifier: (node) {
|
||||
if (node.parent is CatchClause) {
|
||||
updateResult(node.staticElement!);
|
||||
}
|
||||
declaredIdentifier: (node) {
|
||||
updateResult(node.declaredElement!);
|
||||
},
|
||||
variableDeclaration: (node) {
|
||||
updateResult(node.declaredElement!);
|
||||
|
|
|
@ -91,6 +91,10 @@ class FindNode {
|
|||
return _node(search, (n) => n is CatchClause);
|
||||
}
|
||||
|
||||
CatchClauseParameter catchClauseParameter(String search) {
|
||||
return _node(search, (n) => n is CatchClauseParameter);
|
||||
}
|
||||
|
||||
ClassDeclaration classDeclaration(String search) {
|
||||
return _node(search, (n) => n is ClassDeclaration);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:analyzer/dart/ast/visitor.dart';
|
|||
|
||||
/// [RecursiveAstVisitor] that delegates visit methods to functions.
|
||||
class FunctionAstVisitor extends RecursiveAstVisitor<void> {
|
||||
final void Function(CatchClauseParameter)? catchClauseParameter;
|
||||
final void Function(DeclaredIdentifier)? declaredIdentifier;
|
||||
final void Function(FunctionDeclarationStatement)?
|
||||
functionDeclarationStatement;
|
||||
|
@ -17,6 +18,7 @@ class FunctionAstVisitor extends RecursiveAstVisitor<void> {
|
|||
final void Function(VariableDeclaration)? variableDeclaration;
|
||||
|
||||
FunctionAstVisitor({
|
||||
this.catchClauseParameter,
|
||||
this.declaredIdentifier,
|
||||
this.functionDeclarationStatement,
|
||||
this.functionExpression,
|
||||
|
@ -26,6 +28,12 @@ class FunctionAstVisitor extends RecursiveAstVisitor<void> {
|
|||
this.variableDeclaration,
|
||||
});
|
||||
|
||||
@override
|
||||
void visitCatchClauseParameter(CatchClauseParameter node) {
|
||||
catchClauseParameter?.call(node);
|
||||
super.visitCatchClauseParameter(node);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitDeclaredIdentifier(DeclaredIdentifier node) {
|
||||
if (declaredIdentifier != null) {
|
||||
|
|
|
@ -1407,9 +1407,9 @@ main() {
|
|||
expect(clause.onKeyword, isNull);
|
||||
expect(clause.exceptionType, isNull);
|
||||
expect(clause.catchKeyword, isNotNull);
|
||||
expect(clause.exceptionParameter, isNotNull);
|
||||
expect(clause.exceptionParameter2, isNotNull);
|
||||
expect(clause.comma, isNull);
|
||||
expect(clause.stackTraceParameter, isNull);
|
||||
expect(clause.stackTraceParameter2, isNull);
|
||||
expect(clause.body, isNotNull);
|
||||
expect(statement.finallyKeyword, isNull);
|
||||
expect(statement.finallyBlock, isNull);
|
||||
|
@ -1430,9 +1430,9 @@ main() {
|
|||
expect(clause.onKeyword, isNull);
|
||||
expect(clause.exceptionType, isNull);
|
||||
expect(clause.catchKeyword, isNotNull);
|
||||
expect(clause.exceptionParameter!.name, 'int');
|
||||
expect(clause.exceptionParameter2!.name.lexeme, 'int');
|
||||
expect(clause.comma, isNotNull);
|
||||
expect(clause.stackTraceParameter!.name, 'e');
|
||||
expect(clause.stackTraceParameter2!.name.lexeme, 'e');
|
||||
expect(clause.body, isNotNull);
|
||||
expect(statement.finallyKeyword, isNull);
|
||||
expect(statement.finallyBlock, isNull);
|
||||
|
@ -1449,9 +1449,9 @@ main() {
|
|||
expect(clause.onKeyword, isNull);
|
||||
expect(clause.exceptionType, isNull);
|
||||
expect(clause.catchKeyword, isNotNull);
|
||||
expect(clause.exceptionParameter, isNotNull);
|
||||
expect(clause.exceptionParameter2, isNotNull);
|
||||
expect(clause.comma, isNull);
|
||||
expect(clause.stackTraceParameter, isNull);
|
||||
expect(clause.stackTraceParameter2, isNull);
|
||||
expect(clause.body, isNotNull);
|
||||
expect(statement.finallyKeyword, isNull);
|
||||
expect(statement.finallyBlock, isNull);
|
||||
|
@ -1468,9 +1468,9 @@ main() {
|
|||
expect(clause.onKeyword, isNull);
|
||||
expect(clause.exceptionType, isNull);
|
||||
expect(clause.catchKeyword, isNotNull);
|
||||
expect(clause.exceptionParameter, isNotNull);
|
||||
expect(clause.exceptionParameter2, isNotNull);
|
||||
expect(clause.comma, isNull);
|
||||
expect(clause.stackTraceParameter, isNull);
|
||||
expect(clause.stackTraceParameter2, isNull);
|
||||
expect(clause.body, isNotNull);
|
||||
expect(statement.finallyKeyword, isNull);
|
||||
expect(statement.finallyBlock, isNull);
|
||||
|
@ -1487,9 +1487,9 @@ main() {
|
|||
expect(clause.onKeyword, isNull);
|
||||
expect(clause.exceptionType, isNull);
|
||||
expect(clause.catchKeyword, isNotNull);
|
||||
expect(clause.exceptionParameter, isNotNull);
|
||||
expect(clause.exceptionParameter2, isNotNull);
|
||||
expect(clause.comma, isNotNull);
|
||||
expect(clause.stackTraceParameter, isNotNull);
|
||||
expect(clause.stackTraceParameter2, isNotNull);
|
||||
expect(clause.body, isNotNull);
|
||||
expect(statement.finallyKeyword, isNull);
|
||||
expect(statement.finallyBlock, isNull);
|
||||
|
@ -1507,9 +1507,9 @@ main() {
|
|||
expect(clause.onKeyword, isNull);
|
||||
expect(clause.exceptionType, isNull);
|
||||
expect(clause.catchKeyword, isNotNull);
|
||||
expect(clause.exceptionParameter, isNotNull);
|
||||
expect(clause.exceptionParameter2, isNotNull);
|
||||
expect(clause.comma, isNotNull);
|
||||
expect(clause.stackTraceParameter, isNotNull);
|
||||
expect(clause.stackTraceParameter2, isNotNull);
|
||||
expect(clause.body, isNotNull);
|
||||
expect(statement.finallyKeyword, isNotNull);
|
||||
expect(statement.finallyBlock, isNotNull);
|
||||
|
@ -1548,9 +1548,9 @@ main() {
|
|||
expect(clause.onKeyword, isNotNull);
|
||||
expect(clause.exceptionType, isNotNull);
|
||||
expect(clause.catchKeyword, isNull);
|
||||
expect(clause.exceptionParameter, isNull);
|
||||
expect(clause.exceptionParameter2, isNull);
|
||||
expect(clause.comma, isNull);
|
||||
expect(clause.stackTraceParameter, isNull);
|
||||
expect(clause.stackTraceParameter2, isNull);
|
||||
expect(clause.body, isNotNull);
|
||||
expect(statement.finallyKeyword, isNull);
|
||||
expect(statement.finallyBlock, isNull);
|
||||
|
@ -1568,9 +1568,9 @@ main() {
|
|||
expect(clause.onKeyword, isNotNull);
|
||||
expect(clause.exceptionType, isNotNull);
|
||||
expect(clause.catchKeyword, isNotNull);
|
||||
expect(clause.exceptionParameter, isNotNull);
|
||||
expect(clause.exceptionParameter2, isNotNull);
|
||||
expect(clause.comma, isNotNull);
|
||||
expect(clause.stackTraceParameter, isNotNull);
|
||||
expect(clause.stackTraceParameter2, isNotNull);
|
||||
expect(clause.body, isNotNull);
|
||||
expect(statement.finallyKeyword, isNull);
|
||||
expect(statement.finallyBlock, isNull);
|
||||
|
@ -1588,9 +1588,9 @@ main() {
|
|||
expect(clause.onKeyword, isNotNull);
|
||||
expect(clause.exceptionType, isNotNull);
|
||||
expect(clause.catchKeyword, isNotNull);
|
||||
expect(clause.exceptionParameter, isNotNull);
|
||||
expect(clause.exceptionParameter2, isNotNull);
|
||||
expect(clause.comma, isNotNull);
|
||||
expect(clause.stackTraceParameter, isNotNull);
|
||||
expect(clause.stackTraceParameter2, isNotNull);
|
||||
expect(clause.body, isNotNull);
|
||||
expect(statement.finallyKeyword, isNotNull);
|
||||
expect(statement.finallyBlock, isNotNull);
|
||||
|
|
|
@ -416,8 +416,8 @@ void f() {
|
|||
source: findNode.catchClause('(e2,'),
|
||||
childAccessors: [
|
||||
(node) => node.exceptionType!,
|
||||
(node) => node.exceptionParameter!,
|
||||
(node) => node.stackTraceParameter!,
|
||||
(node) => node.exceptionParameter2!,
|
||||
(node) => node.stackTraceParameter2!,
|
||||
(node) => node.body,
|
||||
],
|
||||
);
|
||||
|
|
|
@ -7653,13 +7653,12 @@ void main() {
|
|||
CatchClause catchClause = statement.catchClauses[0];
|
||||
expect(catchClause.exceptionType, isNull);
|
||||
|
||||
var exceptionNode = catchClause.exceptionParameter as SimpleIdentifier;
|
||||
var exceptionElement =
|
||||
exceptionNode.staticElement as LocalVariableElement;
|
||||
var exceptionNode = catchClause.exceptionParameter2!;
|
||||
var exceptionElement = exceptionNode.declaredElement!;
|
||||
expect(exceptionElement.type, typeProvider.objectType);
|
||||
|
||||
var stackNode = catchClause.stackTraceParameter as SimpleIdentifier;
|
||||
var stackElement = stackNode.staticElement as LocalVariableElement;
|
||||
var stackNode = catchClause.stackTraceParameter2!;
|
||||
var stackElement = stackNode.declaredElement!;
|
||||
expect(stackElement.type, typeProvider.stackTraceType);
|
||||
|
||||
List<Statement> catchStatements = catchClause.body.statements;
|
||||
|
@ -7683,13 +7682,12 @@ void main() {
|
|||
_assertNamedTypeSimple(
|
||||
catchClause.exceptionType as NamedType, typeProvider.intType);
|
||||
|
||||
var exceptionNode = catchClause.exceptionParameter as SimpleIdentifier;
|
||||
var exceptionElement =
|
||||
exceptionNode.staticElement as LocalVariableElement;
|
||||
var exceptionNode = catchClause.exceptionParameter2!;
|
||||
var exceptionElement = exceptionNode.declaredElement!;
|
||||
expect(exceptionElement.type, typeProvider.intType);
|
||||
|
||||
var stackNode = catchClause.stackTraceParameter as SimpleIdentifier;
|
||||
var stackElement = stackNode.staticElement as LocalVariableElement;
|
||||
var stackNode = catchClause.stackTraceParameter2!;
|
||||
var stackElement = stackNode.declaredElement!;
|
||||
expect(stackElement.type, typeProvider.stackTraceType);
|
||||
|
||||
List<Statement> catchStatements = catchClause.body.statements;
|
||||
|
@ -7711,11 +7709,10 @@ void main() {
|
|||
var statement = statements[2] as TryStatement;
|
||||
CatchClause catchClause = statement.catchClauses[0];
|
||||
expect(catchClause.exceptionType, isNull);
|
||||
expect(catchClause.stackTraceParameter, isNull);
|
||||
expect(catchClause.stackTraceParameter2, isNull);
|
||||
|
||||
var exceptionNode = catchClause.exceptionParameter as SimpleIdentifier;
|
||||
var exceptionElement =
|
||||
exceptionNode.staticElement as LocalVariableElement;
|
||||
var exceptionNode = catchClause.exceptionParameter2!;
|
||||
var exceptionElement = exceptionNode.declaredElement!;
|
||||
expect(exceptionElement.type, typeProvider.objectType);
|
||||
}
|
||||
|
||||
|
@ -7724,11 +7721,10 @@ void main() {
|
|||
var statement = statements[3] as TryStatement;
|
||||
CatchClause catchClause = statement.catchClauses[0];
|
||||
_assertNamedTypeSimple(catchClause.exceptionType!, typeProvider.intType);
|
||||
expect(catchClause.stackTraceParameter, isNull);
|
||||
expect(catchClause.stackTraceParameter2, isNull);
|
||||
|
||||
var exceptionNode = catchClause.exceptionParameter as SimpleIdentifier;
|
||||
var exceptionElement =
|
||||
exceptionNode.staticElement as LocalVariableElement;
|
||||
var exceptionNode = catchClause.exceptionParameter2!;
|
||||
var exceptionElement = exceptionNode.declaredElement!;
|
||||
expect(exceptionElement.type, typeProvider.intType);
|
||||
}
|
||||
|
||||
|
@ -7738,8 +7734,8 @@ void main() {
|
|||
CatchClause catchClause = statement.catchClauses[0];
|
||||
_assertNamedTypeSimple(
|
||||
catchClause.exceptionType as NamedType, typeProvider.intType);
|
||||
expect(catchClause.exceptionParameter, isNull);
|
||||
expect(catchClause.stackTraceParameter, isNull);
|
||||
expect(catchClause.exceptionParameter2, isNull);
|
||||
expect(catchClause.stackTraceParameter2, isNull);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -223,21 +223,47 @@ var v = a * (b + c);
|
|||
}
|
||||
|
||||
void test_visitCatchClause_catch_noStack() {
|
||||
_assertSource("catch (e) {}", AstTestFactory.catchClause("e"));
|
||||
final code = 'catch (e) {}';
|
||||
final findNode = _parseStringToFindNode('''
|
||||
void f() {
|
||||
try {}
|
||||
$code
|
||||
}
|
||||
''');
|
||||
_assertSource(code, findNode.catchClause(code));
|
||||
}
|
||||
|
||||
void test_visitCatchClause_catch_stack() {
|
||||
_assertSource("catch (e, s) {}", AstTestFactory.catchClause2("e", "s"));
|
||||
final code = 'catch (e, s) {}';
|
||||
final findNode = _parseStringToFindNode('''
|
||||
void f() {
|
||||
try {}
|
||||
$code
|
||||
}
|
||||
''');
|
||||
_assertSource(code, findNode.catchClause(code));
|
||||
}
|
||||
|
||||
void test_visitCatchClause_on() {
|
||||
_assertSource(
|
||||
"on E {}", AstTestFactory.catchClause3(AstTestFactory.namedType4("E")));
|
||||
final code = 'on E {}';
|
||||
final findNode = _parseStringToFindNode('''
|
||||
void f() {
|
||||
try {}
|
||||
$code
|
||||
}
|
||||
''');
|
||||
_assertSource(code, findNode.catchClause(code));
|
||||
}
|
||||
|
||||
void test_visitCatchClause_on_catch() {
|
||||
_assertSource("on E catch (e) {}",
|
||||
AstTestFactory.catchClause4(AstTestFactory.namedType4("E"), "e"));
|
||||
final code = 'on E catch (e) {}';
|
||||
final findNode = _parseStringToFindNode('''
|
||||
void f() {
|
||||
try {}
|
||||
$code
|
||||
}
|
||||
''');
|
||||
_assertSource(code, findNode.catchClause(code));
|
||||
}
|
||||
|
||||
void test_visitClassDeclaration_abstract() {
|
||||
|
@ -3333,28 +3359,33 @@ var v = !(a == b);
|
|||
}
|
||||
|
||||
void test_visitTryStatement_catch() {
|
||||
_assertSource(
|
||||
"try {} on E {}",
|
||||
AstTestFactory.tryStatement2(AstTestFactory.block(),
|
||||
[AstTestFactory.catchClause3(AstTestFactory.namedType4("E"))]));
|
||||
final code = 'try {} on E {}';
|
||||
final findNode = _parseStringToFindNode('''
|
||||
void f() {
|
||||
$code
|
||||
}
|
||||
''');
|
||||
_assertSource(code, findNode.tryStatement(code));
|
||||
}
|
||||
|
||||
void test_visitTryStatement_catches() {
|
||||
_assertSource(
|
||||
"try {} on E {} on F {}",
|
||||
AstTestFactory.tryStatement2(AstTestFactory.block(), [
|
||||
AstTestFactory.catchClause3(AstTestFactory.namedType4("E")),
|
||||
AstTestFactory.catchClause3(AstTestFactory.namedType4("F"))
|
||||
]));
|
||||
final code = 'try {} on E {} on F {}';
|
||||
final findNode = _parseStringToFindNode('''
|
||||
void f() {
|
||||
$code
|
||||
}
|
||||
''');
|
||||
_assertSource(code, findNode.tryStatement(code));
|
||||
}
|
||||
|
||||
void test_visitTryStatement_catchFinally() {
|
||||
_assertSource(
|
||||
"try {} on E {} finally {}",
|
||||
AstTestFactory.tryStatement3(
|
||||
AstTestFactory.block(),
|
||||
[AstTestFactory.catchClause3(AstTestFactory.namedType4("E"))],
|
||||
AstTestFactory.block()));
|
||||
final code = 'try {} on E {} finally {}';
|
||||
final findNode = _parseStringToFindNode('''
|
||||
void f() {
|
||||
$code
|
||||
}
|
||||
''');
|
||||
_assertSource(code, findNode.tryStatement(code));
|
||||
}
|
||||
|
||||
void test_visitTryStatement_finally() {
|
||||
|
|
|
@ -36,8 +36,8 @@ main() {
|
|||
assertType(st.type, 'StackTrace');
|
||||
|
||||
var node = findNode.catchClause('catch');
|
||||
expect(node.exceptionParameter!.staticElement, e);
|
||||
expect(node.stackTraceParameter!.staticElement, st);
|
||||
expect(node.exceptionParameter2!.declaredElement, e);
|
||||
expect(node.stackTraceParameter2!.declaredElement, st);
|
||||
}
|
||||
|
||||
test_catch_withType() async {
|
||||
|
@ -58,7 +58,7 @@ main() {
|
|||
assertType(st.type, 'StackTrace');
|
||||
|
||||
var node = findNode.catchClause('catch');
|
||||
expect(node.exceptionParameter!.staticElement, e);
|
||||
expect(node.stackTraceParameter!.staticElement, st);
|
||||
expect(node.exceptionParameter2!.declaredElement, e);
|
||||
expect(node.stackTraceParameter2!.declaredElement, st);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/dart/ast/token.dart';
|
||||
import 'package:analyzer/dart/ast/visitor.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
|
||||
/// A visitor that visits an [AstNode] and its parent recursively along with any
|
||||
/// declarations in those nodes. Consumers typically call [visit] which catches
|
||||
|
@ -39,7 +41,7 @@ abstract class LocalDeclarationVisitor extends GeneralizingAstVisitor {
|
|||
|
||||
void declaredMixin(MixinDeclaration declaration) {}
|
||||
|
||||
void declaredParam(SimpleIdentifier name, TypeAnnotation? type) {}
|
||||
void declaredParam(Token name, Element? element, TypeAnnotation? type) {}
|
||||
|
||||
void declaredTopLevelVar(
|
||||
VariableDeclarationList varList, VariableDeclaration varDecl) {}
|
||||
|
@ -72,14 +74,22 @@ abstract class LocalDeclarationVisitor extends GeneralizingAstVisitor {
|
|||
|
||||
@override
|
||||
void visitCatchClause(CatchClause node) {
|
||||
var exceptionParameter = node.exceptionParameter;
|
||||
var exceptionParameter = node.exceptionParameter2;
|
||||
if (exceptionParameter != null) {
|
||||
declaredParam(exceptionParameter, node.exceptionType);
|
||||
declaredParam(
|
||||
exceptionParameter.name,
|
||||
exceptionParameter.declaredElement,
|
||||
node.exceptionType,
|
||||
);
|
||||
}
|
||||
|
||||
var stackTraceParameter = node.stackTraceParameter;
|
||||
var stackTraceParameter = node.stackTraceParameter2;
|
||||
if (stackTraceParameter != null) {
|
||||
declaredParam(stackTraceParameter, null);
|
||||
declaredParam(
|
||||
stackTraceParameter.name,
|
||||
stackTraceParameter.declaredElement,
|
||||
null,
|
||||
);
|
||||
}
|
||||
|
||||
visitNode(node);
|
||||
|
@ -292,8 +302,7 @@ abstract class LocalDeclarationVisitor extends GeneralizingAstVisitor {
|
|||
} else if (normalParam is SimpleFormalParameter) {
|
||||
type = normalParam.type;
|
||||
}
|
||||
var name = param.identifier;
|
||||
declaredParam(name!, type);
|
||||
declaredParam(param.identifier!.token, param.declaredElement, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
import 'dart:collection';
|
||||
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/dart/ast/token.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:analyzer/file_system/file_system.dart';
|
||||
|
@ -226,8 +227,8 @@ class _LocalBestTypeVisitor extends LocalDeclarationVisitor {
|
|||
}
|
||||
|
||||
@override
|
||||
void declaredParam(SimpleIdentifier name, TypeAnnotation? type) {
|
||||
if (name.name == targetName) {
|
||||
void declaredParam(Token name, Element? element, TypeAnnotation? type) {
|
||||
if (name.lexeme == targetName) {
|
||||
// Type provided by the element in computeFull above
|
||||
finished();
|
||||
}
|
||||
|
|
|
@ -642,8 +642,8 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
|
|||
@override
|
||||
DecoratedType? visitCatchClause(CatchClause node) {
|
||||
_flowAnalysis!.tryCatchStatement_catchBegin(
|
||||
node.exceptionParameter?.staticElement as PromotableElement?,
|
||||
node.stackTraceParameter?.staticElement as PromotableElement?);
|
||||
node.exceptionParameter2?.declaredElement,
|
||||
node.stackTraceParameter2?.declaredElement);
|
||||
_dispatch(node.exceptionType);
|
||||
// The catch clause may not execute, so create a new scope for
|
||||
// post-dominators.
|
||||
|
|
|
@ -90,37 +90,37 @@ class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
|
|||
|
||||
@override
|
||||
DecoratedType? visitCatchClause(CatchClause node) {
|
||||
var exceptionElement = node.exceptionParameter?.staticElement;
|
||||
var exceptionElement = node.exceptionParameter2?.declaredElement;
|
||||
var target = exceptionElement == null
|
||||
? NullabilityNodeTarget.text('exception type')
|
||||
: NullabilityNodeTarget.element(exceptionElement);
|
||||
DecoratedType? exceptionType = _pushNullabilityNodeTarget(
|
||||
target, () => node.exceptionType?.accept(this));
|
||||
if (node.exceptionParameter != null) {
|
||||
if (node.exceptionParameter2 != null) {
|
||||
// If there is no `on Type` part of the catch clause, the type is dynamic.
|
||||
if (exceptionType == null) {
|
||||
exceptionType = DecoratedType.forImplicitType(_typeProvider,
|
||||
_typeProvider.dynamicType, _graph, target.withCodeRef(node));
|
||||
instrumentation?.implicitType(
|
||||
source, node.exceptionParameter, exceptionType);
|
||||
source, node.exceptionParameter2, exceptionType);
|
||||
}
|
||||
_variables!.recordDecoratedElementType(
|
||||
node.exceptionParameter!.staticElement, exceptionType);
|
||||
node.exceptionParameter2?.declaredElement, exceptionType);
|
||||
}
|
||||
if (node.stackTraceParameter != null) {
|
||||
if (node.stackTraceParameter2 != null) {
|
||||
// The type of stack traces is always StackTrace (non-nullable).
|
||||
var target = NullabilityNodeTarget.text('stack trace').withCodeRef(node);
|
||||
var nullabilityNode = NullabilityNode.forInferredType(target);
|
||||
_graph.makeNonNullableUnion(nullabilityNode,
|
||||
StackTraceTypeOrigin(source, node.stackTraceParameter));
|
||||
StackTraceTypeOrigin(source, node.stackTraceParameter2));
|
||||
var stackTraceType =
|
||||
DecoratedType(_typeProvider.stackTraceType, nullabilityNode);
|
||||
_variables!.recordDecoratedElementType(
|
||||
node.stackTraceParameter!.staticElement, stackTraceType);
|
||||
node.stackTraceParameter2?.declaredElement, stackTraceType);
|
||||
instrumentation?.implicitType(
|
||||
source, node.stackTraceParameter, stackTraceType);
|
||||
source, node.stackTraceParameter2, stackTraceType);
|
||||
}
|
||||
node.stackTraceParameter?.accept(this);
|
||||
node.stackTraceParameter2?.accept(this);
|
||||
node.body.accept(this);
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -868,7 +868,7 @@ void f() {
|
|||
}
|
||||
''');
|
||||
var oNode = explicitTypeNullability[findNode.typeAnnotation('Object')];
|
||||
var eNode = implicitType[findNode.simple('e)')]!.node;
|
||||
var eNode = implicitType[findNode.catchClauseParameter('e)')]!.node;
|
||||
expect(
|
||||
edges.where((e) => e.sourceNode == eNode && e.destinationNode == oNode),
|
||||
hasLength(1));
|
||||
|
@ -883,7 +883,7 @@ void f() {
|
|||
}
|
||||
''');
|
||||
var oNode = explicitTypeNullability[findNode.typeAnnotation('Object')];
|
||||
var stNode = implicitType[findNode.simple('st)')]!.node;
|
||||
var stNode = implicitType[findNode.catchClauseParameter('st)')]!.node;
|
||||
expect(
|
||||
edges
|
||||
.where((e) => e.sourceNode == stNode && e.destinationNode == oNode),
|
||||
|
|
Loading…
Reference in a new issue