mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Enhance VarPattern to capture a bit indicating whether the pattern was a var or let.
Previously we only used this information in the parser, but Sema needs to know as well. NFC except in -dump-ast. Swift SVN r25914
This commit is contained in:
@@ -757,14 +757,18 @@ public:
|
||||
/// parsed as expressions referencing existing entities.
|
||||
class VarPattern : public Pattern {
|
||||
SourceLoc VarLoc;
|
||||
bool IsLet; // True if this is a let pattern, false if a var pattern.
|
||||
Pattern *SubPattern;
|
||||
public:
|
||||
VarPattern(SourceLoc loc, Pattern *sub, Optional<bool> implicit = None)
|
||||
: Pattern(PatternKind::Var), VarLoc(loc), SubPattern(sub) {
|
||||
VarPattern(SourceLoc loc, bool isLet, Pattern *sub,
|
||||
Optional<bool> implicit = None)
|
||||
: Pattern(PatternKind::Var), VarLoc(loc), IsLet(isLet), SubPattern(sub) {
|
||||
if (implicit.hasValue() ? *implicit : !loc.isValid())
|
||||
setImplicit();
|
||||
}
|
||||
|
||||
bool isLet() const { return IsLet; }
|
||||
|
||||
SourceLoc getLoc() const { return VarLoc; }
|
||||
SourceRange getSourceRange() const {
|
||||
SourceLoc EndLoc = SubPattern->getSourceRange().End;
|
||||
|
||||
@@ -51,7 +51,7 @@ const uint16_t VERSION_MAJOR = 0;
|
||||
/// To ensure that two separate changes don't silently get merged into one
|
||||
/// in source control, you should also update the comment to briefly
|
||||
/// describe what change you made.
|
||||
const uint16_t VERSION_MINOR = 177; // Last change: Flag for sib
|
||||
const uint16_t VERSION_MINOR = 178; // Last change: VarPattern
|
||||
|
||||
using DeclID = Fixnum<31>;
|
||||
using DeclIDField = BCFixed<31>;
|
||||
@@ -1009,6 +1009,7 @@ namespace decls_block {
|
||||
|
||||
using VarPatternLayout = BCRecordLayout<
|
||||
VAR_PATTERN,
|
||||
BCFixed<1>, // isLet?
|
||||
BCFixed<1> // implicit?
|
||||
// The sub-pattern trails the record.
|
||||
>;
|
||||
|
||||
@@ -259,7 +259,7 @@ namespace {
|
||||
OS << ')';
|
||||
}
|
||||
void visitVarPattern(VarPattern *P) {
|
||||
printCommon(P, "pattern_var");
|
||||
printCommon(P, P->isLet() ? "pattern_let" : "pattern_var");
|
||||
OS << '\n';
|
||||
printRec(P->getSubPattern());
|
||||
OS << ')';
|
||||
|
||||
@@ -498,7 +498,7 @@ void PrintAST::printPattern(const Pattern *pattern) {
|
||||
|
||||
case PatternKind::Var:
|
||||
if (!Options.SkipIntroducerKeywords)
|
||||
Printer << "var ";
|
||||
Printer << (cast<VarPattern>(pattern)->isLet() ? "let " : "var ");
|
||||
printPattern(cast<VarPattern>(pattern)->getSubPattern());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -390,7 +390,7 @@ Pattern *Pattern::clone(ASTContext &context,
|
||||
|
||||
case PatternKind::Var: {
|
||||
auto var = cast<VarPattern>(this);
|
||||
result = new(context) VarPattern(var->getLoc(),
|
||||
result = new(context) VarPattern(var->getLoc(), var->isLet(),
|
||||
var->getSubPattern()->clone(
|
||||
context,
|
||||
options|IsVar));
|
||||
@@ -431,7 +431,7 @@ Pattern *Pattern::cloneForwardable(ASTContext &context, DeclContext *DC,
|
||||
|
||||
case PatternKind::Var: {
|
||||
auto var = cast<VarPattern>(this);
|
||||
result = new(context) VarPattern(var->getLoc(),
|
||||
result = new(context) VarPattern(var->getLoc(), var->isLet(),
|
||||
var->getSubPattern()->cloneForwardable(
|
||||
context, DC, options|IsVar));
|
||||
break;
|
||||
|
||||
@@ -391,7 +391,8 @@ mapParsedParameters(Parser &parser,
|
||||
// If 'var' or 'let' was specified explicitly, create a pattern for it.
|
||||
if (specifierKind != Parser::ParsedParameter::InOut &&
|
||||
letVarInOutLoc.isValid()) {
|
||||
param = new (ctx) VarPattern(letVarInOutLoc, param);
|
||||
bool isLet = specifierKind == Parser::ParsedParameter::Let;
|
||||
param = new (ctx) VarPattern(letVarInOutLoc, isLet, param);
|
||||
}
|
||||
|
||||
if (var)
|
||||
@@ -802,7 +803,8 @@ ParserResult<Pattern> Parser::parsePatternVarOrLet() {
|
||||
return makeParserCodeCompletionResult<Pattern>();
|
||||
if (subPattern.isNull())
|
||||
return nullptr;
|
||||
return makeParserResult(new (Context) VarPattern(varLoc, subPattern.get()));
|
||||
return makeParserResult(new (Context) VarPattern(varLoc, isLet,
|
||||
subPattern.get()));
|
||||
}
|
||||
|
||||
/// \brief Determine whether this token can start a binding name, whether an
|
||||
@@ -978,21 +980,22 @@ ParserResult<Pattern> Parser::parseMatchingPattern() {
|
||||
|
||||
ParserResult<Pattern> Parser::parseMatchingPatternVarOrVal() {
|
||||
assert((Tok.is(tok::kw_let) || Tok.is(tok::kw_var)) && "expects val or var");
|
||||
bool isVal = Tok.is(tok::kw_let);
|
||||
bool isLet = Tok.is(tok::kw_let);
|
||||
SourceLoc varLoc = consumeToken();
|
||||
|
||||
// 'var' and 'let' patterns shouldn't nest.
|
||||
if (InVarOrLetPattern)
|
||||
diagnose(varLoc, diag::var_pattern_in_var, unsigned(isVal));
|
||||
diagnose(varLoc, diag::var_pattern_in_var, unsigned(isLet));
|
||||
|
||||
// In our recursive parse, remember that we're in a var/let pattern.
|
||||
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
|
||||
T(InVarOrLetPattern, isVal ? IVOLP_InLet : IVOLP_InVar);
|
||||
T(InVarOrLetPattern, isLet ? IVOLP_InLet : IVOLP_InVar);
|
||||
|
||||
ParserResult<Pattern> subPattern = parseMatchingPattern();
|
||||
if (subPattern.isNull())
|
||||
return nullptr;
|
||||
return makeParserResult(new (Context) VarPattern(varLoc, subPattern.get()));
|
||||
return makeParserResult(new (Context) VarPattern(varLoc, isLet,
|
||||
subPattern.get()));
|
||||
}
|
||||
|
||||
// matching-pattern ::= 'is' type
|
||||
|
||||
@@ -367,12 +367,12 @@ Pattern *ModuleFile::maybeReadPattern() {
|
||||
return result;
|
||||
}
|
||||
case decls_block::VAR_PATTERN: {
|
||||
bool isImplicit;
|
||||
VarPatternLayout::readRecord(scratch, isImplicit);
|
||||
bool isImplicit, isLet;
|
||||
VarPatternLayout::readRecord(scratch, isLet, isImplicit);
|
||||
Pattern *subPattern = maybeReadPattern();
|
||||
assert(subPattern);
|
||||
|
||||
auto result = new (getContext()) VarPattern(SourceLoc(), subPattern,
|
||||
auto result = new (getContext()) VarPattern(SourceLoc(), isLet, subPattern,
|
||||
isImplicit);
|
||||
result->setType(subPattern->getType());
|
||||
return result;
|
||||
|
||||
@@ -842,7 +842,7 @@ void Serializer::writePattern(const Pattern *pattern) {
|
||||
auto var = cast<VarPattern>(pattern);
|
||||
|
||||
unsigned abbrCode = DeclTypeAbbrCodes[VarPatternLayout::Code];
|
||||
VarPatternLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||
VarPatternLayout::emitRecord(Out, ScratchRecord, abbrCode, var->isLet(),
|
||||
var->isImplicit());
|
||||
writePattern(var->getSubPattern());
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user