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:
Konstantin Shcheglov 2022-08-01 17:32:04 +00:00 committed by Commit Bot
parent d7d15aa5b8
commit 33b672f789
41 changed files with 419 additions and 251 deletions

View file

@ -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;
}
}

View file

@ -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) {

View file

@ -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();
}

View file

@ -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,

View file

@ -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);

View file

@ -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),

View file

@ -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);

View file

@ -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));
});

View file

@ -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),
);
});
}
}

View file

@ -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.');
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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`.

View file

@ -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.

View file

@ -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);

View file

@ -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;

View file

@ -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,

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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,

View file

@ -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);

View file

@ -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

View file

@ -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 {

View file

@ -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,

View file

@ -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);

View file

@ -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!);

View file

@ -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);
}

View file

@ -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) {

View file

@ -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);

View file

@ -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,
],
);

View file

@ -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);
}
}

View file

@ -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() {

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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();
}

View file

@ -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.

View file

@ -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;
}

View file

@ -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),