Use textual dumps in SuperFormalParameterTest.

Verify that the declared element of SuperFormalParameter is in the
list of ParameterElement(s) for all dumps, not only in some tests.

Change-Id: I45e92a1a7ff71c6768bb3559423604543d932741
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/260447
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov 2022-09-22 01:25:46 +00:00 committed by Commit Bot
parent 182742a61c
commit c86158bf81
2 changed files with 148 additions and 52 deletions

View file

@ -68,27 +68,45 @@ class A {
}
class B extends A {
B(super.a<T>(int b));
B(T super.a<T>(int b));
}
''');
var B = findElement.unnamedConstructor('B');
var element = B.superFormalParameter('a');
assertElement(
findNode.superFormalParameter('super.a'),
element,
);
assertElement(
findNode.typeParameter('T>'),
element.typeParameters[0],
);
assertElement(
findNode.simpleFormalParameter('b));'),
element.parameters[0],
);
final node = findNode.superFormalParameter('super.');
assertResolvedNodeText(node, r'''
SuperFormalParameter
type: NamedType
name: SimpleIdentifier
token: T
staticElement: T@62
staticType: null
type: T
superKeyword: super
period: .
name: a
typeParameters: TypeParameterList
leftBracket: <
typeParameters
TypeParameter
name: T
declaredElement: T@62
rightBracket: >
parameters: FormalParameterList
leftParenthesis: (
parameter: SimpleFormalParameter
type: NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
name: b
declaredElement: self::@class::B::@constructor::::@parameter::a::@parameter::b
declaredElementType: int
rightParenthesis: )
declaredElement: self::@class::B::@constructor::::@parameter::a
declaredElementType: T Function<T>(int)
''');
}
test_invalid_notConstructor() async {
@ -98,14 +116,15 @@ void f(super.a) {}
error(CompileTimeErrorCode.INVALID_SUPER_FORMAL_PARAMETER_LOCATION, 7, 5),
]);
var f = findElement.topFunction('f');
var element = f.superFormalParameter('a');
assertTypeDynamic(element.type);
assertElement(
findNode.superFormalParameter('super.a'),
element,
);
final node = findNode.superFormalParameter('super.');
assertResolvedNodeText(node, r'''
SuperFormalParameter
superKeyword: super
period: .
name: a
declaredElement: self::@function::f::@parameter::a
declaredElementType: dynamic
''');
}
test_optionalNamed() async {
@ -119,10 +138,15 @@ class B extends A {
}
''');
assertElement(
findNode.superFormalParameter('super.a'),
findElement.unnamedConstructor('B').superFormalParameter('a'),
);
final node = findNode.superFormalParameter('super.');
assertResolvedNodeText(node, r'''
SuperFormalParameter
superKeyword: super
period: .
name: a
declaredElement: self::@class::B::@constructor::::@parameter::a
declaredElementType: int?
''');
}
test_optionalPositional() async {
@ -136,10 +160,15 @@ class B extends A {
}
''');
assertElement(
findNode.superFormalParameter('super.a'),
findElement.unnamedConstructor('B').superFormalParameter('a'),
);
final node = findNode.superFormalParameter('super.');
assertResolvedNodeText(node, r'''
SuperFormalParameter
superKeyword: super
period: .
name: a
declaredElement: self::@class::B::@constructor::::@parameter::a
declaredElementType: int?
''');
}
test_requiredNamed() async {
@ -153,10 +182,16 @@ class B extends A {
}
''');
assertElement(
findNode.superFormalParameter('super.a'),
findElement.unnamedConstructor('B').superFormalParameter('a'),
);
final node = findNode.superFormalParameter('super.');
assertResolvedNodeText(node, r'''
SuperFormalParameter
requiredKeyword: required
superKeyword: super
period: .
name: a
declaredElement: self::@class::B::@constructor::::@parameter::a
declaredElementType: int
''');
}
test_requiredPositional() async {
@ -170,10 +205,15 @@ class B extends A {
}
''');
assertElement(
findNode.superFormalParameter('super.a'),
findElement.unnamedConstructor('B').superFormalParameter('a'),
);
final node = findNode.superFormalParameter('super.');
assertResolvedNodeText(node, r'''
SuperFormalParameter
superKeyword: super
period: .
name: a
declaredElement: self::@class::B::@constructor::::@parameter::a
declaredElementType: int
''');
}
test_scoping_inBody() async {
@ -190,10 +230,13 @@ class B extends A {
}
''');
assertElement(
findNode.simple('a; // ref'),
findElement.getter('a', of: 'A'),
);
final node = findNode.simple('a; // ref');
assertResolvedNodeText(node, r'''
SimpleIdentifier
token: a
staticElement: self::@class::A::@getter::a
staticType: int
''');
}
test_scoping_inInitializer() async {
@ -208,9 +251,12 @@ class B extends A {
}
''');
assertElement(
findNode.simple('a; }'),
findElement.unnamedConstructor('B').superFormalParameter('a'),
);
final node = findNode.simple('a; }');
assertResolvedNodeText(node, r'''
SimpleIdentifier
token: a
staticElement: self::@class::B::@constructor::::@parameter::a
staticType: int
''');
}
}

View file

@ -9,6 +9,7 @@ import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/generated/source.dart';
@ -1061,7 +1062,7 @@ class ResolvedAstPrinter extends ThrowingAstVisitor<void> {
_withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeElement('declaredElement', node.declaredElement);
_writeDeclaredElement(node, node.declaredElement);
_writeType('declaredElementType', node.declaredElement!.type);
}
});
@ -1136,7 +1137,7 @@ class ResolvedAstPrinter extends ThrowingAstVisitor<void> {
_withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeElement('declaredElement', node.declaredElement);
_writeDeclaredElement(node, node.declaredElement);
_writeType('declaredElementType', node.declaredElement!.type);
}
});
@ -1430,6 +1431,17 @@ class ResolvedAstPrinter extends ThrowingAstVisitor<void> {
});
}
void _writeDeclaredElement(AstNode node, Element? declaredElement) {
if (_withResolution) {
if (node is FormalParameter) {
final expected = _expectedFormalParameterElements(node);
_assertHasIdenticalElement(expected, declaredElement);
}
}
_writeElement('declaredElement', declaredElement);
}
void _writeDirectiveUri(DirectiveUri? uri) {
if (uri == null) {
_writeln('<null>');
@ -1696,6 +1708,15 @@ class ResolvedAstPrinter extends ThrowingAstVisitor<void> {
}
}
static void _assertHasIdenticalElement<T>(List<T> elements, T expected) {
for (final element in elements) {
if (identical(element, expected)) {
return;
}
}
fail('No $expected in $elements');
}
static Token _entityBeginToken(SyntacticEntity entity) {
if (entity is Token) {
return entity;
@ -1716,6 +1737,35 @@ class ResolvedAstPrinter extends ThrowingAstVisitor<void> {
}
}
/// Every [FormalParameter] declares an element, and this element must be
/// in the list of formal parameter elements of some declaration, e.g. of
/// [ConstructorDeclaration], [MethodDeclaration], or a local
/// [FunctionDeclaration].
static List<ParameterElement> _expectedFormalParameterElements(
FormalParameter node,
) {
final parametersParent = node.parentFormalParameterList.parent;
if (parametersParent is ConstructorDeclaration) {
final declaredElement = parametersParent.declaredElement2!;
return declaredElement.parameters;
} else if (parametersParent is FormalParameter) {
final declaredElement = parametersParent.declaredElement!;
return declaredElement.parameters;
} else if (parametersParent is FunctionExpression) {
final declaredElement = parametersParent.declaredElement!;
return declaredElement.parameters;
} else if (parametersParent is GenericFunctionTypeImpl) {
final declaredElement = parametersParent.declaredElement!;
return declaredElement.parameters;
} else if (parametersParent is MethodDeclaration) {
final declaredElement = parametersParent.declaredElement2!;
return declaredElement.parameters;
}
throw UnimplementedError(
'(${parametersParent.runtimeType}) $parametersParent',
);
}
static String _nameOfMemberClass(Member member) {
return '${member.runtimeType}';
}