Skip to content

Commit

Permalink
Resolve VariablePattern.
Browse files Browse the repository at this point in the history
Change-Id: Ibfd32610e86aa3396495b3ba7210612a17756fc4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/261782
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
  • Loading branch information
scheglov authored and Commit Queue committed Sep 28, 2022
1 parent b48846c commit e1b5cbd
Show file tree
Hide file tree
Showing 9 changed files with 249 additions and 48 deletions.
2 changes: 1 addition & 1 deletion pkg/analyzer/lib/dart/ast/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5420,7 +5420,7 @@ abstract class VariablePattern implements DartPattern {
/// Return the element associated with this declaration, or `null` if either
/// the variable name is `_` (in which case no variable is defined) or the AST
/// structure has not been resolved.
VariableElement? get declaredElement;
VariablePatternElement? get declaredElement;

/// The 'var' or 'final' keyword used when there is no [type], or `null` if a
/// type is given.
Expand Down
9 changes: 9 additions & 0 deletions pkg/analyzer/lib/dart/element/element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2388,6 +2388,15 @@ abstract class VariableElement implements Element, ConstantEvaluationTarget {
DartObject? computeConstantValue();
}

/// A pattern variable.
///
/// Clients may not extend, implement or mix-in this class.
@experimental
abstract class VariablePatternElement implements LocalVariableElement {
/// Aliases of this variable in logical-or patterns.
List<VariablePatternElement> get aliases;
}

/// This class exists to provide non-nullable overrides for existing elements,
/// as opposite to artificial "multiply defined" element.
abstract class _ExistingElement implements Element {
Expand Down
6 changes: 4 additions & 2 deletions pkg/analyzer/lib/src/dart/ast/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13422,7 +13422,7 @@ class VariableDeclarationStatementImpl extends StatementImpl
@experimental
class VariablePatternImpl extends DartPatternImpl implements VariablePattern {
@override
VariableElement? declaredElement;
VariablePatternElementImpl? declaredElement;

@override
final Token? keyword;
Expand Down Expand Up @@ -13463,7 +13463,9 @@ class VariablePatternImpl extends DartPatternImpl implements VariablePattern {
DartType matchedType,
Map<PromotableElement, VariableTypeInfo<AstNode, DartType>> typeInfos,
MatchContext<AstNode, Expression> context) {
// TODO(scheglov) https://github.com/dart-lang/sdk/issues/50066
resolverVisitor.analyzeVariablePattern(matchedType, typeInfos, context,
this, declaredElement, type?.typeOrThrow,
isFinal: keyword?.keyword == Keyword.FINAL);
}

@override
Expand Down
8 changes: 8 additions & 0 deletions pkg/analyzer/lib/src/dart/element/element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6479,6 +6479,14 @@ abstract class VariableElementImpl extends ElementImpl
DartObject? computeConstantValue() => null;
}

class VariablePatternElementImpl extends LocalVariableElementImpl
implements VariablePatternElement {
@override
final List<VariablePatternElementImpl> aliases = [];

VariablePatternElementImpl(super.name, super.offset);
}

abstract class _ExistingElementImpl extends ElementImpl with _HasLibraryMixin {
_ExistingElementImpl(super.name, super.offset, {super.reference});
}
Expand Down
17 changes: 17 additions & 0 deletions pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'package:analyzer/dart/analysis/features.dart';
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';
import 'package:analyzer/dart/element/nullability_suffix.dart';
Expand Down Expand Up @@ -1177,6 +1178,22 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
}
}

@override
void visitVariablePattern(covariant VariablePatternImpl node) {
node.type?.accept(this);

if (node.name.lexeme != '_') {
final element = VariablePatternElementImpl(
node.name.lexeme,
node.name.offset,
);
node.declaredElement = element;
_elementHolder.enclose(element);
element.isFinal = node.keyword?.keyword == Keyword.FINAL;
element.hasImplicitType = node.type == null;
}
}

/// Builds the label elements associated with [labels] and stores them in the
/// element holder.
void _buildLabelElements(
Expand Down
9 changes: 7 additions & 2 deletions pkg/analyzer/lib/src/generated/resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,11 @@ class ResolverVisitor extends ThrowingAstVisitor<void>

@override
void setVariableType(PromotableElement variable, DartType type) {
throw UnimplementedError('TODO(paulberry)');
if (variable is LocalVariableElementImpl) {
variable.type = type;
} else {
throw UnimplementedError('TODO(paulberry)');
}
}

void setWriteElement(Expression node, Element? element) {
Expand Down Expand Up @@ -1241,7 +1245,8 @@ class ResolverVisitor extends ThrowingAstVisitor<void>

@override
DartType variableTypeFromInitializerType(DartType type) {
throw UnimplementedError('TODO(paulberry)');
// TODO(scheglov) https://github.com/dart-lang/sdk/issues/50078
return type;
}

@override
Expand Down
18 changes: 12 additions & 6 deletions pkg/analyzer/test/src/dart/resolution/postfix_pattern_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,18 @@ ExtractorPattern

test_inside_ifStatement_case() async {
await assertNoErrorsInCode(r'''
void f(x) {
void f(int? x) {
if (x case var y!) {}
}
''');
final node = findNode.caseClause('case').pattern;
assertParsedNodeText(node, r'''
assertResolvedNodeText(node, r'''
PostfixPattern
operand: VariablePattern
keyword: var
name: y
declaredElement: hasImplicitType y@34
type: int
operator: !
''');
}
Expand Down Expand Up @@ -252,13 +254,14 @@ void f(x) {
}
''');
final node = findNode.switchPatternCase('case').pattern;
assertParsedNodeText(node, r'''
assertResolvedNodeText(node, r'''
ParenthesizedPattern
leftParenthesis: (
pattern: PostfixPattern
operand: ConstantPattern
expression: IntegerLiteral
literal: 0
staticType: int
operator: !
rightParenthesis: )
''');
Expand Down Expand Up @@ -444,16 +447,18 @@ ExtractorPattern

test_inside_ifStatement_case() async {
await assertNoErrorsInCode(r'''
void f(x) {
void f(int? x) {
if (x case var y?) {}
}
''');
final node = findNode.caseClause('case').pattern;
assertParsedNodeText(node, r'''
assertResolvedNodeText(node, r'''
PostfixPattern
operand: VariablePattern
keyword: var
name: y
declaredElement: hasImplicitType y@34
type: int
operator: ?
''');
}
Expand Down Expand Up @@ -614,13 +619,14 @@ void f(x) {
}
''');
final node = findNode.switchPatternCase('case').pattern;
assertParsedNodeText(node, r'''
assertResolvedNodeText(node, r'''
ParenthesizedPattern
leftParenthesis: (
pattern: PostfixPattern
operand: ConstantPattern
expression: IntegerLiteral
literal: 0
staticType: int
operator: ?
rightParenthesis: )
''');
Expand Down
Loading

0 comments on commit e1b5cbd

Please sign in to comment.