Use whitespace indentation to detect selector-style call continuations.

Implement several rules that determine when an identifier on a new
line is a continuation of a selector-style call on a previous line:

  - In certain contexts, such as parentheses or square brackets, it's
    always a continuation because one does not split statements in
    those contexts;

  - Otherwise, compare the leading whitespace on the line containing
    the nearest enclosing statement or declaration to the leading
    whitespace for the line containing the identifier.

The leading whitespace for a line is currently defined as all space
and tab characters from the start of the line up to the first
non-space, non-tab character. Leading whitespace is compared via a
string comparison, which eliminates any dependency on the width of a
tab. One can run into a few amusing cases where adjacent lines that
look indented (under some specific tab width) aren't actually indented
according to this rule because there are different mixes of tabs and
spaces in the two lines. See the bottom of call-suffix-indent.swift
for an example.

I had to adjust two test cases that had lines with slightly different
indentation. The diagnostics here are awful; I've made no attempt at
improving them.



Swift SVN r13843
This commit is contained in:
Doug Gregor
2014-02-12 22:50:50 +00:00
parent 3f7d3877a4
commit 45ca5fe987
8 changed files with 317 additions and 7 deletions

View File

@@ -142,6 +142,7 @@ static Pattern *rebuildImplicitPatternAround(const Pattern *P, Pattern *NewRoot,
static ParserResult<Pattern> parseArgument(Parser &P, Identifier leadingIdent,
Parser::DefaultArgumentInfo *defaultArgs) {
// Consume the (.
Parser::StructureMarkerRAII ParsingArgument(P, P.Tok);
SourceLoc LPLoc = P.consumeToken(tok::l_paren);
// Decide if this is a singular unnamed argument (e.g. "foo(Int)" or if
@@ -782,6 +783,7 @@ Parser::parsePatternTupleElement(bool isLet, bool isArgumentList,
ParserResult<Pattern> Parser::parsePatternTuple(bool isLet, bool isArgumentList,
DefaultArgumentInfo *defaults) {
StructureMarkerRAII ParsingPatternTuple(*this, Tok);
SourceLoc LPLoc = consumeToken(tok::l_paren);
return parsePatternTupleAfterLP(isLet, isArgumentList, LPLoc, defaults);
}