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