mirror of
https://github.com/dart-lang/sdk
synced 2024-10-04 17:04:56 +00:00
Resolve PatternVariableDeclarationStatement
Change-Id: Ied7bcde49729608028eb5b62102f756b565a858f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/272080 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
parent
8b12c0c6fb
commit
7759f7fe03
|
@ -21,6 +21,7 @@ import 'package:analyzer/src/fasta/token_utils.dart' as util show findPrevious;
|
|||
import 'package:analyzer/src/generated/resolver.dart';
|
||||
import 'package:analyzer/src/generated/source.dart' show LineInfo;
|
||||
import 'package:analyzer/src/generated/utilities_dart.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
/// Two or more string literals that are implicitly concatenated because of
|
||||
|
@ -1540,8 +1541,9 @@ class CastPatternImpl extends DartPatternImpl implements CastPattern {
|
|||
E? accept<E>(AstVisitor<E> visitor) => visitor.visitCastPattern(this);
|
||||
|
||||
@override
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) {
|
||||
return resolverVisitor.analyzeCastPatternSchema();
|
||||
}
|
||||
|
||||
@override
|
||||
void resolvePattern(
|
||||
|
@ -8085,8 +8087,13 @@ class ListPatternImpl extends DartPatternImpl implements ListPattern {
|
|||
E? accept<E>(AstVisitor<E> visitor) => visitor.visitListPattern(this);
|
||||
|
||||
@override
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) {
|
||||
var elementType = typeArguments?.arguments.elementAtOrNull(0)?.typeOrThrow;
|
||||
return resolverVisitor.analyzeListPatternSchema(
|
||||
elementType: elementType,
|
||||
elements: elements,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void resolvePattern(
|
||||
|
@ -9449,8 +9456,9 @@ class ObjectPatternImpl extends DartPatternImpl implements ObjectPattern {
|
|||
E? accept<E>(AstVisitor<E> visitor) => visitor.visitObjectPattern(this);
|
||||
|
||||
@override
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) {
|
||||
return resolverVisitor.analyzeObjectPatternSchema(type.typeOrThrow);
|
||||
}
|
||||
|
||||
@override
|
||||
void resolvePattern(
|
||||
|
@ -9644,8 +9652,9 @@ class ParenthesizedPatternImpl extends DartPatternImpl
|
|||
visitor.visitParenthesizedPattern(this);
|
||||
|
||||
@override
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) {
|
||||
return resolverVisitor.dispatchPatternSchema(pattern);
|
||||
}
|
||||
|
||||
@override
|
||||
void resolvePattern(
|
||||
|
@ -10109,8 +10118,12 @@ class PostfixPatternImpl extends DartPatternImpl implements PostfixPattern {
|
|||
E? accept<E>(AstVisitor<E> visitor) => visitor.visitPostfixPattern(this);
|
||||
|
||||
@override
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) {
|
||||
return resolverVisitor.analyzeNullCheckOrAssertPatternSchema(
|
||||
operand,
|
||||
isAssert: operator.type == TokenType.BANG,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void resolvePattern(
|
||||
|
@ -10607,8 +10620,11 @@ class RecordPatternImpl extends DartPatternImpl implements RecordPattern {
|
|||
E? accept<E>(AstVisitor<E> visitor) => visitor.visitRecordPattern(this);
|
||||
|
||||
@override
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) {
|
||||
return resolverVisitor.analyzeRecordPatternSchema(
|
||||
fields: resolverVisitor.buildSharedRecordPatternFields(fields),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void resolvePattern(
|
||||
|
@ -13635,8 +13651,9 @@ class VariablePatternImpl extends DartPatternImpl implements VariablePattern {
|
|||
E? accept<E>(AstVisitor<E> visitor) => visitor.visitVariablePattern(this);
|
||||
|
||||
@override
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) {
|
||||
return resolverVisitor.analyzeVariablePatternSchema(type?.typeOrThrow);
|
||||
}
|
||||
|
||||
@override
|
||||
void resolvePattern(
|
||||
|
|
|
@ -408,7 +408,7 @@ class TypeSystemOperations
|
|||
|
||||
@override
|
||||
DartType glb(DartType type1, DartType type2) {
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
return typeSystem.getGreatestLowerBound(type1, type2);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -452,7 +452,7 @@ class TypeSystemOperations
|
|||
|
||||
@override
|
||||
DartType makeNullable(DartType type) {
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
return typeSystem.makeNullable(type);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -990,6 +990,14 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
|
|||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void visitPatternVariableDeclarationStatement(
|
||||
PatternVariableDeclarationStatement node) {
|
||||
_patternVariables.casePatternStart();
|
||||
super.visitPatternVariableDeclarationStatement(node);
|
||||
_patternVariables.casePatternFinish();
|
||||
}
|
||||
|
||||
@override
|
||||
void visitPrefixedIdentifier(covariant PrefixedIdentifierImpl node) {
|
||||
var newNode = _astRewriter.prefixedIdentifier(_nameScope, node);
|
||||
|
|
|
@ -2834,6 +2834,19 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
|
|||
elementResolver.visitPartOfDirective(node);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitPatternVariableDeclarationStatement(
|
||||
PatternVariableDeclarationStatement node) {
|
||||
checkUnreachableNode(node);
|
||||
var declaration = node.declaration;
|
||||
// TODO(scheglov) Support for `late` was removed.
|
||||
analyzePatternVariableDeclarationStatement(
|
||||
node, declaration.pattern, declaration.expression,
|
||||
isFinal: declaration.keyword.keyword == Keyword.FINAL, isLate: false);
|
||||
// node.visitChildren(this);
|
||||
popRewrite(); // expression
|
||||
}
|
||||
|
||||
@override
|
||||
void visitPostfixExpression(PostfixExpression node, {DartType? contextType}) {
|
||||
checkUnreachableNode(node);
|
||||
|
|
|
@ -45,6 +45,29 @@ class FindNode {
|
|||
return nodes.single;
|
||||
}
|
||||
|
||||
/// Returns the [PatternVariableDeclaration], there must be only one.
|
||||
PatternVariableDeclaration get singlePatternVariableDeclaration {
|
||||
var nodes = <PatternVariableDeclaration>[];
|
||||
unit.accept(
|
||||
FunctionAstVisitor(
|
||||
patternVariableDeclaration: nodes.add,
|
||||
),
|
||||
);
|
||||
return nodes.single;
|
||||
}
|
||||
|
||||
/// Returns the [PatternVariableDeclarationStatement], there must be only one.
|
||||
PatternVariableDeclarationStatement
|
||||
get singlePatternVariableDeclarationStatement {
|
||||
var nodes = <PatternVariableDeclarationStatement>[];
|
||||
unit.accept(
|
||||
FunctionAstVisitor(
|
||||
patternVariableDeclarationStatement: nodes.add,
|
||||
),
|
||||
);
|
||||
return nodes.single;
|
||||
}
|
||||
|
||||
AdjacentStrings adjacentStrings(String search) {
|
||||
return _node(search, (n) => n is AdjacentStrings);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,9 @@ class FunctionAstVisitor extends RecursiveAstVisitor<void> {
|
|||
final void Function(IfStatement)? ifStatement;
|
||||
final void Function(Label)? label;
|
||||
final void Function(MethodInvocation)? methodInvocation;
|
||||
final void Function(PatternVariableDeclaration)? patternVariableDeclaration;
|
||||
final void Function(PatternVariableDeclarationStatement)?
|
||||
patternVariableDeclarationStatement;
|
||||
final void Function(SimpleIdentifier)? simpleIdentifier;
|
||||
final void Function(SwitchExpressionCase)? switchExpressionCase;
|
||||
final void Function(SwitchPatternCase)? switchPatternCase;
|
||||
|
@ -28,6 +31,8 @@ class FunctionAstVisitor extends RecursiveAstVisitor<void> {
|
|||
this.ifStatement,
|
||||
this.label,
|
||||
this.methodInvocation,
|
||||
this.patternVariableDeclaration,
|
||||
this.patternVariableDeclarationStatement,
|
||||
this.simpleIdentifier,
|
||||
this.switchExpressionCase,
|
||||
this.switchPatternCase,
|
||||
|
@ -88,6 +93,19 @@ class FunctionAstVisitor extends RecursiveAstVisitor<void> {
|
|||
super.visitMethodInvocation(node);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitPatternVariableDeclaration(PatternVariableDeclaration node) {
|
||||
patternVariableDeclaration?.call(node);
|
||||
super.visitPatternVariableDeclaration(node);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitPatternVariableDeclarationStatement(
|
||||
PatternVariableDeclarationStatement node) {
|
||||
patternVariableDeclarationStatement?.call(node);
|
||||
super.visitPatternVariableDeclarationStatement(node);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitSimpleIdentifier(SimpleIdentifier node) {
|
||||
if (simpleIdentifier != null) {
|
||||
|
|
|
@ -62,6 +62,39 @@ CastPattern
|
|||
staticElement: dart:core::@class::int
|
||||
staticType: null
|
||||
type: int
|
||||
''');
|
||||
}
|
||||
|
||||
test_variableDeclaration() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f(x) {
|
||||
var (a as int) = x;
|
||||
}
|
||||
''');
|
||||
final node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ParenthesizedPattern
|
||||
leftParenthesis: (
|
||||
pattern: CastPattern
|
||||
pattern: VariablePattern
|
||||
name: a
|
||||
declaredElement: hasImplicitType a@19
|
||||
type: int
|
||||
asToken: as
|
||||
type: NamedType
|
||||
name: SimpleIdentifier
|
||||
token: int
|
||||
staticElement: dart:core::@class::int
|
||||
staticType: null
|
||||
type: int
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: SimpleIdentifier
|
||||
token: x
|
||||
staticElement: self::@function::f::@parameter::x
|
||||
staticType: dynamic
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -383,6 +383,123 @@ ListPattern
|
|||
type: int
|
||||
rightBracket: ]
|
||||
requiredType: List<int>
|
||||
''');
|
||||
}
|
||||
|
||||
test_variableDeclaration_inferredType() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f(List<int> x) {
|
||||
var [a] = x;
|
||||
}
|
||||
''');
|
||||
final node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ListPattern
|
||||
leftBracket: [
|
||||
elements
|
||||
VariablePattern
|
||||
name: a
|
||||
declaredElement: hasImplicitType a@29
|
||||
type: int
|
||||
rightBracket: ]
|
||||
requiredType: List<int>
|
||||
equals: =
|
||||
expression: SimpleIdentifier
|
||||
token: x
|
||||
staticElement: self::@function::f::@parameter::x
|
||||
staticType: List<int>
|
||||
''');
|
||||
}
|
||||
|
||||
test_variableDeclaration_typeSchema_withTypeArguments() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f() {
|
||||
var <int>[a] = g();
|
||||
}
|
||||
|
||||
T g<T>() => throw 0;
|
||||
''');
|
||||
final node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ListPattern
|
||||
typeArguments: TypeArgumentList
|
||||
leftBracket: <
|
||||
arguments
|
||||
NamedType
|
||||
name: SimpleIdentifier
|
||||
token: int
|
||||
staticElement: dart:core::@class::int
|
||||
staticType: null
|
||||
type: int
|
||||
rightBracket: >
|
||||
leftBracket: [
|
||||
elements
|
||||
VariablePattern
|
||||
name: a
|
||||
declaredElement: hasImplicitType a@23
|
||||
type: int
|
||||
rightBracket: ]
|
||||
requiredType: List<int>
|
||||
equals: =
|
||||
expression: MethodInvocation
|
||||
methodName: SimpleIdentifier
|
||||
token: g
|
||||
staticElement: self::@function::g
|
||||
staticType: T Function<T>()
|
||||
argumentList: ArgumentList
|
||||
leftParenthesis: (
|
||||
rightParenthesis: )
|
||||
staticInvokeType: List<int> Function()
|
||||
staticType: List<int>
|
||||
typeArgumentTypes
|
||||
List<int>
|
||||
''');
|
||||
}
|
||||
|
||||
test_variableDeclaration_typeSchema_withVariableType() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f() {
|
||||
var [int a] = g();
|
||||
}
|
||||
|
||||
T g<T>() => throw 0;
|
||||
''');
|
||||
final node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ListPattern
|
||||
leftBracket: [
|
||||
elements
|
||||
VariablePattern
|
||||
type: NamedType
|
||||
name: SimpleIdentifier
|
||||
token: int
|
||||
staticElement: dart:core::@class::int
|
||||
staticType: null
|
||||
type: int
|
||||
name: a
|
||||
declaredElement: a@22
|
||||
type: int
|
||||
rightBracket: ]
|
||||
requiredType: List<int>
|
||||
equals: =
|
||||
expression: MethodInvocation
|
||||
methodName: SimpleIdentifier
|
||||
token: g
|
||||
staticElement: self::@function::g
|
||||
staticType: T Function<T>()
|
||||
argumentList: ArgumentList
|
||||
leftParenthesis: (
|
||||
rightParenthesis: )
|
||||
staticInvokeType: List<int> Function()
|
||||
staticType: List<int>
|
||||
typeArgumentTypes
|
||||
List<int>
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -778,6 +778,177 @@ ObjectPattern
|
|||
type: int
|
||||
fieldElement: <null>
|
||||
rightParenthesis: )
|
||||
''');
|
||||
}
|
||||
|
||||
test_variableDeclaration_inferredType() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f(A<int> x) {
|
||||
var A(foo: a) = x;
|
||||
}
|
||||
|
||||
class A<T> {
|
||||
T get foo => throw 0;
|
||||
}
|
||||
''');
|
||||
final node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ObjectPattern
|
||||
type: NamedType
|
||||
name: SimpleIdentifier
|
||||
token: A
|
||||
staticElement: self::@class::A
|
||||
staticType: null
|
||||
type: A<int>
|
||||
leftParenthesis: (
|
||||
fields
|
||||
RecordPatternField
|
||||
fieldName: RecordPatternFieldName
|
||||
name: foo
|
||||
colon: :
|
||||
pattern: VariablePattern
|
||||
name: a
|
||||
declaredElement: hasImplicitType a@32
|
||||
type: int
|
||||
fieldElement: PropertyAccessorMember
|
||||
base: self::@class::A::@getter::foo
|
||||
substitution: {T: int}
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: SimpleIdentifier
|
||||
token: x
|
||||
staticElement: self::@function::f::@parameter::x
|
||||
staticType: A<int>
|
||||
''');
|
||||
}
|
||||
|
||||
/// TODO(scheglov) Remove `new` (everywhere), implement rewrite.
|
||||
test_variableDeclaration_typeSchema_withTypeArguments() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f() {
|
||||
var A<int>(foo: a) = new A();
|
||||
}
|
||||
|
||||
class A<T> {
|
||||
T get foo => throw 0;
|
||||
}
|
||||
''');
|
||||
final node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ObjectPattern
|
||||
type: NamedType
|
||||
name: SimpleIdentifier
|
||||
token: A
|
||||
staticElement: self::@class::A
|
||||
staticType: null
|
||||
typeArguments: TypeArgumentList
|
||||
leftBracket: <
|
||||
arguments
|
||||
NamedType
|
||||
name: SimpleIdentifier
|
||||
token: int
|
||||
staticElement: dart:core::@class::int
|
||||
staticType: null
|
||||
type: int
|
||||
rightBracket: >
|
||||
type: A<int>
|
||||
leftParenthesis: (
|
||||
fields
|
||||
RecordPatternField
|
||||
fieldName: RecordPatternFieldName
|
||||
name: foo
|
||||
colon: :
|
||||
pattern: VariablePattern
|
||||
name: a
|
||||
declaredElement: hasImplicitType a@29
|
||||
type: int
|
||||
fieldElement: PropertyAccessorMember
|
||||
base: self::@class::A::@getter::foo
|
||||
substitution: {T: int}
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: InstanceCreationExpression
|
||||
keyword: new
|
||||
constructorName: ConstructorName
|
||||
type: NamedType
|
||||
name: SimpleIdentifier
|
||||
token: A
|
||||
staticElement: self::@class::A
|
||||
staticType: null
|
||||
type: A<int>
|
||||
staticElement: ConstructorMember
|
||||
base: self::@class::A::@constructor::new
|
||||
substitution: {T: int}
|
||||
argumentList: ArgumentList
|
||||
leftParenthesis: (
|
||||
rightParenthesis: )
|
||||
staticType: A<int>
|
||||
''');
|
||||
}
|
||||
|
||||
test_variableDeclaration_typeSchema_withVariableType() async {
|
||||
// `int a` does not propagate up, we get `A<dynamic>`
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f() {
|
||||
var A(foo: int a) = new A();
|
||||
}
|
||||
|
||||
class A<T> {
|
||||
T get foo => throw 0;
|
||||
}
|
||||
''');
|
||||
final node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ObjectPattern
|
||||
type: NamedType
|
||||
name: SimpleIdentifier
|
||||
token: A
|
||||
staticElement: self::@class::A
|
||||
staticType: null
|
||||
type: A<dynamic>
|
||||
leftParenthesis: (
|
||||
fields
|
||||
RecordPatternField
|
||||
fieldName: RecordPatternFieldName
|
||||
name: foo
|
||||
colon: :
|
||||
pattern: VariablePattern
|
||||
type: NamedType
|
||||
name: SimpleIdentifier
|
||||
token: int
|
||||
staticElement: dart:core::@class::int
|
||||
staticType: null
|
||||
type: int
|
||||
name: a
|
||||
declaredElement: a@28
|
||||
type: int
|
||||
fieldElement: PropertyAccessorMember
|
||||
base: self::@class::A::@getter::foo
|
||||
substitution: {T: dynamic}
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: InstanceCreationExpression
|
||||
keyword: new
|
||||
constructorName: ConstructorName
|
||||
type: NamedType
|
||||
name: SimpleIdentifier
|
||||
token: A
|
||||
staticElement: self::@class::A
|
||||
staticType: null
|
||||
type: A<dynamic>
|
||||
staticElement: ConstructorMember
|
||||
base: self::@class::A::@constructor::new
|
||||
substitution: {T: dynamic}
|
||||
argumentList: ArgumentList
|
||||
leftParenthesis: (
|
||||
rightParenthesis: )
|
||||
staticType: A<dynamic>
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import 'context_collection_resolution.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(PatternVariableDeclarationStatementResolutionTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class PatternVariableDeclarationStatementResolutionTest
|
||||
extends PatternsResolutionTest {
|
||||
test_inferredType() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f((int, String) x) {
|
||||
var (a, b) = x;
|
||||
}
|
||||
''');
|
||||
final node = findNode.singlePatternVariableDeclarationStatement;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclarationStatement
|
||||
declaration: PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: RecordPattern
|
||||
leftParenthesis: (
|
||||
fields
|
||||
RecordPatternField
|
||||
pattern: VariablePattern
|
||||
name: a
|
||||
declaredElement: hasImplicitType a@33
|
||||
type: int
|
||||
fieldElement: <null>
|
||||
RecordPatternField
|
||||
pattern: VariablePattern
|
||||
name: b
|
||||
declaredElement: hasImplicitType b@36
|
||||
type: String
|
||||
fieldElement: <null>
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: SimpleIdentifier
|
||||
token: x
|
||||
staticElement: self::@function::f::@parameter::x
|
||||
staticType: (int, String)
|
||||
semicolon: ;
|
||||
''');
|
||||
}
|
||||
|
||||
test_typeSchema_fromVariableType() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f() {
|
||||
var (int a) = g();
|
||||
}
|
||||
|
||||
T g<T>() => throw 0;
|
||||
''');
|
||||
final node = findNode.singlePatternVariableDeclarationStatement;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclarationStatement
|
||||
declaration: PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ParenthesizedPattern
|
||||
leftParenthesis: (
|
||||
pattern: VariablePattern
|
||||
type: NamedType
|
||||
name: SimpleIdentifier
|
||||
token: int
|
||||
staticElement: dart:core::@class::int
|
||||
staticType: null
|
||||
type: int
|
||||
name: a
|
||||
declaredElement: a@22
|
||||
type: int
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: MethodInvocation
|
||||
methodName: SimpleIdentifier
|
||||
token: g
|
||||
staticElement: self::@function::g
|
||||
staticType: T Function<T>()
|
||||
argumentList: ArgumentList
|
||||
leftParenthesis: (
|
||||
rightParenthesis: )
|
||||
staticInvokeType: int Function()
|
||||
staticType: int
|
||||
typeArgumentTypes
|
||||
int
|
||||
semicolon: ;
|
||||
''');
|
||||
}
|
||||
}
|
|
@ -53,6 +53,33 @@ PostfixPattern
|
|||
''');
|
||||
}
|
||||
|
||||
test_nullAssert_variableDeclaration() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f(int? x) {
|
||||
var (a!) = x;
|
||||
}
|
||||
''');
|
||||
final node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ParenthesizedPattern
|
||||
leftParenthesis: (
|
||||
pattern: PostfixPattern
|
||||
operand: VariablePattern
|
||||
name: a
|
||||
declaredElement: hasImplicitType a@24
|
||||
type: int
|
||||
operator: !
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: SimpleIdentifier
|
||||
token: x
|
||||
staticElement: self::@function::f::@parameter::x
|
||||
staticType: int?
|
||||
''');
|
||||
}
|
||||
|
||||
test_nullCheck_ifCase() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f(int? x) {
|
||||
|
@ -89,6 +116,35 @@ PostfixPattern
|
|||
declaredElement: hasImplicitType y@45
|
||||
type: int
|
||||
operator: ?
|
||||
''');
|
||||
}
|
||||
|
||||
/// TODO(scheglov) finish
|
||||
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/50066')
|
||||
test_nullCheck_variableDeclaration() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f(int? x) {
|
||||
var (a?) = x;
|
||||
}
|
||||
''');
|
||||
final node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ParenthesizedPattern
|
||||
leftParenthesis: (
|
||||
pattern: PostfixPattern
|
||||
operand: VariablePattern
|
||||
name: a
|
||||
declaredElement: hasImplicitType a@24
|
||||
type: int
|
||||
operator: !
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: SimpleIdentifier
|
||||
token: x
|
||||
staticElement: self::@function::f::@parameter::x
|
||||
staticType: int?
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -646,6 +646,97 @@ RecordPattern
|
|||
type: int
|
||||
fieldElement: <null>
|
||||
rightParenthesis: )
|
||||
''');
|
||||
}
|
||||
|
||||
test_variableDeclaration_inferredType() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f((int, String) x) {
|
||||
var (a, b) = x;
|
||||
}
|
||||
''');
|
||||
final node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: RecordPattern
|
||||
leftParenthesis: (
|
||||
fields
|
||||
RecordPatternField
|
||||
pattern: VariablePattern
|
||||
name: a
|
||||
declaredElement: hasImplicitType a@33
|
||||
type: int
|
||||
fieldElement: <null>
|
||||
RecordPatternField
|
||||
pattern: VariablePattern
|
||||
name: b
|
||||
declaredElement: hasImplicitType b@36
|
||||
type: String
|
||||
fieldElement: <null>
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: SimpleIdentifier
|
||||
token: x
|
||||
staticElement: self::@function::f::@parameter::x
|
||||
staticType: (int, String)
|
||||
''');
|
||||
}
|
||||
|
||||
test_variableDeclaration_typeSchema() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f() {
|
||||
var (int a, String b) = g();
|
||||
}
|
||||
|
||||
(T, U) g<T, U>() => throw 0;
|
||||
''');
|
||||
final node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: RecordPattern
|
||||
leftParenthesis: (
|
||||
fields
|
||||
RecordPatternField
|
||||
pattern: VariablePattern
|
||||
type: NamedType
|
||||
name: SimpleIdentifier
|
||||
token: int
|
||||
staticElement: dart:core::@class::int
|
||||
staticType: null
|
||||
type: int
|
||||
name: a
|
||||
declaredElement: a@22
|
||||
type: int
|
||||
fieldElement: <null>
|
||||
RecordPatternField
|
||||
pattern: VariablePattern
|
||||
type: NamedType
|
||||
name: SimpleIdentifier
|
||||
token: String
|
||||
staticElement: dart:core::@class::String
|
||||
staticType: null
|
||||
type: String
|
||||
name: b
|
||||
declaredElement: b@32
|
||||
type: String
|
||||
fieldElement: <null>
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: MethodInvocation
|
||||
methodName: SimpleIdentifier
|
||||
token: g
|
||||
staticElement: self::@function::g
|
||||
staticType: (T, U) Function<T, U>()
|
||||
argumentList: ArgumentList
|
||||
leftParenthesis: (
|
||||
rightParenthesis: )
|
||||
staticInvokeType: (int, String) Function()
|
||||
staticType: (int, String)
|
||||
typeArgumentTypes
|
||||
int
|
||||
String
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,6 +66,8 @@ import 'object_pattern_test.dart' as object_pattern;
|
|||
import 'optional_const_test.dart' as optional_const;
|
||||
import 'parenthesized_pattern_test.dart' as parenthesized_pattern;
|
||||
import 'part_test.dart' as part_;
|
||||
import 'pattern_variable_declaration_statement_test.dart'
|
||||
as pattern_variable_declaration_statement;
|
||||
import 'postfix_expression_test.dart' as postfix_expression;
|
||||
import 'postfix_pattern_test.dart' as postfix_pattern;
|
||||
import 'prefix_element_test.dart' as prefix_element;
|
||||
|
@ -149,6 +151,7 @@ main() {
|
|||
optional_const.main();
|
||||
parenthesized_pattern.main();
|
||||
part_.main();
|
||||
pattern_variable_declaration_statement.main();
|
||||
postfix_expression.main();
|
||||
postfix_pattern.main();
|
||||
prefix_element.main();
|
||||
|
|
Loading…
Reference in a new issue