r317343 - [refactor][extract] insert semicolons into extracted/inserted code
Galina Kistanova via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 3 13:32:58 PDT 2017
Hello Alex,
This commit broke tests on few builders:
http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast
http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast
. . .
********************
Failing Tests (1):
Clang :: Refactor/Extract/ExtractionSemicolonPolicy.cpp
Please have a look?
Thanks
Galina
On Fri, Nov 3, 2017 at 11:11 AM, Alex Lorenz via cfe-commits <
cfe-commits at lists.llvm.org> wrote:
> Author: arphaman
> Date: Fri Nov 3 11:11:22 2017
> New Revision: 317343
>
> URL: http://llvm.org/viewvc/llvm-project?rev=317343&view=rev
> Log:
> [refactor][extract] insert semicolons into extracted/inserted code
> when needed
>
> This commit implements the semicolon insertion logic into the extract
> refactoring. The following rules are used:
>
> - extracting expression: add terminating ';' to the extracted function.
> - extracting statements that don't require terminating ';' (e.g. switch):
> add
> terminating ';' to the callee.
> - extracting statements with ';': move (if possible) the original ';'
> from the
> callee and add terminating ';'.
> - otherwise, add ';' to both places.
>
> Differential Revision: https://reviews.llvm.org/D39441
>
> Added:
> cfe/trunk/lib/Tooling/Refactoring/Extract/
> cfe/trunk/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp
> cfe/trunk/lib/Tooling/Refactoring/Extract/SourceExtraction.h
> cfe/trunk/test/Refactor/Extract/ExtractionSemicolonPolicy.cpp
> cfe/trunk/test/Refactor/Extract/ExtractionSemicolonPolicy.m
> Modified:
> cfe/trunk/include/clang/Lex/Lexer.h
> cfe/trunk/lib/Lex/Lexer.cpp
> cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt
> cfe/trunk/lib/Tooling/Refactoring/Extract.cpp
> cfe/trunk/test/Refactor/Extract/ExtractExprIntoFunction.cpp
>
> Modified: cfe/trunk/include/clang/Lex/Lexer.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Lex/Lexer.h?rev=317343&r1=317342&r2=317343&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Lex/Lexer.h (original)
> +++ cfe/trunk/include/clang/Lex/Lexer.h Fri Nov 3 11:11:22 2017
> @@ -466,6 +466,13 @@ public:
> const LangOptions &LangOpts,
> unsigned MaxLines = 0);
>
> + /// Finds the token that comes right after the given location.
> + ///
> + /// Returns the next token, or none if the location is inside a macro.
> + static Optional<Token> findNextToken(SourceLocation Loc,
> + const SourceManager &SM,
> + const LangOptions &LangOpts);
> +
> /// \brief Checks that the given token is the first token that occurs
> after
> /// the given location (this excludes comments and whitespace). Returns
> the
> /// location immediately after the specified token. If the token is not
> found
>
> Modified: cfe/trunk/lib/Lex/Lexer.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/
> Lexer.cpp?rev=317343&r1=317342&r2=317343&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Lex/Lexer.cpp (original)
> +++ cfe/trunk/lib/Lex/Lexer.cpp Fri Nov 3 11:11:22 2017
> @@ -1212,18 +1212,12 @@ const char *Lexer::SkipEscapedNewLines(c
> }
> }
>
> -/// \brief Checks that the given token is the first token that occurs
> after the
> -/// given location (this excludes comments and whitespace). Returns the
> location
> -/// immediately after the specified token. If the token is not found or
> the
> -/// location is inside a macro, the returned source location will be
> invalid.
> -SourceLocation Lexer::findLocationAfterToken(SourceLocation Loc,
> - tok::TokenKind TKind,
> - const SourceManager &SM,
> - const LangOptions &LangOpts,
> - bool
> SkipTrailingWhitespaceAndNewLine) {
> +Optional<Token> Lexer::findNextToken(SourceLocation Loc,
> + const SourceManager &SM,
> + const LangOptions &LangOpts) {
> if (Loc.isMacroID()) {
> if (!Lexer::isAtEndOfMacroExpansion(Loc, SM, LangOpts, &Loc))
> - return SourceLocation();
> + return None;
> }
> Loc = Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts);
>
> @@ -1234,7 +1228,7 @@ SourceLocation Lexer::findLocationAfterT
> bool InvalidTemp = false;
> StringRef File = SM.getBufferData(LocInfo.first, &InvalidTemp);
> if (InvalidTemp)
> - return SourceLocation();
> + return None;
>
> const char *TokenBegin = File.data() + LocInfo.second;
>
> @@ -1244,15 +1238,25 @@ SourceLocation Lexer::findLocationAfterT
> // Find the token.
> Token Tok;
> lexer.LexFromRawLexer(Tok);
> - if (Tok.isNot(TKind))
> + return Tok;
> +}
> +
> +/// \brief Checks that the given token is the first token that occurs
> after the
> +/// given location (this excludes comments and whitespace). Returns the
> location
> +/// immediately after the specified token. If the token is not found or
> the
> +/// location is inside a macro, the returned source location will be
> invalid.
> +SourceLocation Lexer::findLocationAfterToken(
> + SourceLocation Loc, tok::TokenKind TKind, const SourceManager &SM,
> + const LangOptions &LangOpts, bool SkipTrailingWhitespaceAndNewLine) {
> + Optional<Token> Tok = findNextToken(Loc, SM, LangOpts);
> + if (!Tok || Tok->isNot(TKind))
> return SourceLocation();
> - SourceLocation TokenLoc = Tok.getLocation();
> + SourceLocation TokenLoc = Tok->getLocation();
>
> // Calculate how much whitespace needs to be skipped if any.
> unsigned NumWhitespaceChars = 0;
> if (SkipTrailingWhitespaceAndNewLine) {
> - const char *TokenEnd = SM.getCharacterData(TokenLoc) +
> - Tok.getLength();
> + const char *TokenEnd = SM.getCharacterData(TokenLoc) +
> Tok->getLength();
> unsigned char C = *TokenEnd;
> while (isHorizontalWhitespace(C)) {
> C = *(++TokenEnd);
> @@ -1269,7 +1273,7 @@ SourceLocation Lexer::findLocationAfterT
> }
> }
>
> - return TokenLoc.getLocWithOffset(Tok.getLength() + NumWhitespaceChars);
> + return TokenLoc.getLocWithOffset(Tok->getLength() +
> NumWhitespaceChars);
> }
>
> /// getCharAndSizeSlow - Peek a single 'character' from the specified
> buffer,
>
> Modified: cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/
> Refactoring/CMakeLists.txt?rev=317343&r1=317342&r2=317343&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt (original)
> +++ cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt Fri Nov 3 11:11:22
> 2017
> @@ -4,7 +4,8 @@ add_clang_library(clangToolingRefactor
> ASTSelection.cpp
> ASTSelectionRequirements.cpp
> AtomicChange.cpp
> - Extract.cpp
> + Extract/Extract.cpp
> + Extract/SourceExtraction.cpp
> RefactoringActions.cpp
> Rename/RenamingAction.cpp
> Rename/SymbolOccurrences.cpp
>
> Modified: cfe/trunk/lib/Tooling/Refactoring/Extract.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/
> Refactoring/Extract.cpp?rev=317343&r1=317342&r2=317343&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Tooling/Refactoring/Extract.cpp (original)
> +++ cfe/trunk/lib/Tooling/Refactoring/Extract.cpp Fri Nov 3 11:11:22 2017
> @@ -14,6 +14,7 @@
> //===-------------------------------------------------------
> ---------------===//
>
> #include "clang/Tooling/Refactoring/Extract/Extract.h"
> +#include "SourceExtraction.h"
> #include "clang/AST/ASTContext.h"
> #include "clang/AST/DeclCXX.h"
> #include "clang/AST/Expr.h"
> @@ -145,6 +146,8 @@ ExtractFunction::createSourceReplacement
> PP.SuppressLifetimeQualifiers = true;
> PP.SuppressUnwrittenScope = true;
>
> + ExtractionSemicolonPolicy Semicolons = ExtractionSemicolonPolicy::
> compute(
> + Code[Code.size() - 1], ExtractedRange, SM, LangOpts);
> AtomicChange Change(SM, ExtractedDeclLocation);
> // Create the replacement for the extracted declaration.
> {
> @@ -162,8 +165,8 @@ ExtractFunction::createSourceReplacement
> if (IsExpr && !ReturnType->isVoidType())
> OS << "return ";
> OS << ExtractedCodeRewriter.getRewrittenText(ExtractedRange);
> - // FIXME: Compute the correct semicolon policy.
> - OS << ';';
> + if (Semicolons.isNeededInExtractedFunction())
> + OS << ';';
> OS << "\n}\n\n";
> auto Err = Change.insert(SM, ExtractedDeclLocation, OS.str());
> if (Err)
> @@ -178,7 +181,8 @@ ExtractFunction::createSourceReplacement
> OS << DeclName << '(';
> // FIXME: Forward arguments.
> OS << ')';
> - // FIXME: Add semicolon if needed.
> + if (Semicolons.isNeededInOriginalFunction())
> + OS << ';';
>
> auto Err = Change.replace(
> SM, CharSourceRange::getTokenRange(ExtractedRange), OS.str());
>
> Added: cfe/trunk/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/
> Refactoring/Extract/SourceExtraction.cpp?rev=317343&view=auto
> ============================================================
> ==================
> --- cfe/trunk/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp (added)
> +++ cfe/trunk/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp Fri
> Nov 3 11:11:22 2017
> @@ -0,0 +1,112 @@
> +//===--- SourceExtraction.cpp - Clang refactoring library
> -----------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +#include "SourceExtraction.h"
> +#include "clang/AST/Stmt.h"
> +#include "clang/AST/StmtCXX.h"
> +#include "clang/AST/StmtObjC.h"
> +#include "clang/Basic/SourceManager.h"
> +#include "clang/Lex/Lexer.h"
> +
> +using namespace clang;
> +
> +namespace {
> +
> +/// Returns true if the token at the given location is a semicolon.
> +bool isSemicolonAtLocation(SourceLocation TokenLoc, const SourceManager
> &SM,
> + const LangOptions &LangOpts) {
> + return Lexer::getSourceText(
> + CharSourceRange::getTokenRange(TokenLoc, TokenLoc), SM,
> + LangOpts) == ";";
> +}
> +
> +/// Returns true if there should be a semicolon after the given statement.
> +bool isSemicolonRequiredAfter(const Stmt *S) {
> + if (isa<CompoundStmt>(S))
> + return false;
> + if (const auto *If = dyn_cast<IfStmt>(S))
> + return isSemicolonRequiredAfter(If->getElse() ? If->getElse()
> + : If->getThen());
> + if (const auto *While = dyn_cast<WhileStmt>(S))
> + return isSemicolonRequiredAfter(While->getBody());
> + if (const auto *For = dyn_cast<ForStmt>(S))
> + return isSemicolonRequiredAfter(For->getBody());
> + if (const auto *CXXFor = dyn_cast<CXXForRangeStmt>(S))
> + return isSemicolonRequiredAfter(CXXFor->getBody());
> + if (const auto *ObjCFor = dyn_cast<ObjCForCollectionStmt>(S))
> + return isSemicolonRequiredAfter(ObjCFor->getBody());
> + switch (S->getStmtClass()) {
> + case Stmt::SwitchStmtClass:
> + case Stmt::CXXTryStmtClass:
> + case Stmt::ObjCAtSynchronizedStmtClass:
> + case Stmt::ObjCAutoreleasePoolStmtClass:
> + case Stmt::ObjCAtTryStmtClass:
> + return false;
> + default:
> + return true;
> + }
> +}
> +
> +/// Returns true if the two source locations are on the same line.
> +bool areOnSameLine(SourceLocation Loc1, SourceLocation Loc2,
> + const SourceManager &SM) {
> + return !Loc1.isMacroID() && !Loc2.isMacroID() &&
> + SM.getSpellingLineNumber(Loc1) == SM.getSpellingLineNumber(Loc2)
> ;
> +}
> +
> +} // end anonymous namespace
> +
> +namespace clang {
> +namespace tooling {
> +
> +ExtractionSemicolonPolicy
> +ExtractionSemicolonPolicy::compute(const Stmt *S, SourceRange
> &ExtractedRange,
> + const SourceManager &SM,
> + const LangOptions &LangOpts) {
> + auto neededInExtractedFunction = []() {
> + return ExtractionSemicolonPolicy(true, false);
> + };
> + auto neededInOriginalFunction = []() {
> + return ExtractionSemicolonPolicy(false, true);
> + };
> +
> + /// The extracted expression should be terminated with a ';'. The call
> to
> + /// the extracted function will replace this expression, so it won't
> need
> + /// a terminating ';'.
> + if (isa<Expr>(S))
> + return neededInExtractedFunction();
> +
> + /// Some statements don't need to be terminated with ';'. The call to
> the
> + /// extracted function will be a standalone statement, so it should be
> + /// terminated with a ';'.
> + bool NeedsSemi = isSemicolonRequiredAfter(S);
> + if (!NeedsSemi)
> + return neededInOriginalFunction();
> +
> + /// Some statements might end at ';'. The extraction will move that
> ';', so
> + /// the call to the extracted function should be terminated with a ';'.
> + SourceLocation End = ExtractedRange.getEnd();
> + if (isSemicolonAtLocation(End, SM, LangOpts))
> + return neededInOriginalFunction();
> +
> + /// Other statements should generally have a trailing ';'. We can try
> to find
> + /// it and move it together it with the extracted code.
> + Optional<Token> NextToken = Lexer::findNextToken(End, SM, LangOpts);
> + if (NextToken && NextToken->is(tok::semi) &&
> + areOnSameLine(NextToken->getLocation(), End, SM)) {
> + ExtractedRange.setEnd(NextToken->getLocation());
> + return neededInOriginalFunction();
> + }
> +
> + /// Otherwise insert semicolons in both places.
> + return ExtractionSemicolonPolicy(true, true);
> +}
> +
> +} // end namespace tooling
> +} // end namespace clang
>
> Added: cfe/trunk/lib/Tooling/Refactoring/Extract/SourceExtraction.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/
> Refactoring/Extract/SourceExtraction.h?rev=317343&view=auto
> ============================================================
> ==================
> --- cfe/trunk/lib/Tooling/Refactoring/Extract/SourceExtraction.h (added)
> +++ cfe/trunk/lib/Tooling/Refactoring/Extract/SourceExtraction.h Fri Nov
> 3 11:11:22 2017
> @@ -0,0 +1,52 @@
> +//===--- SourceExtraction.cpp - Clang refactoring library
> -----------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +#ifndef LLVM_CLANG_LIB_TOOLING_REFACTORING_EXTRACT_SOURCE_EXTRACTION_H
> +#define LLVM_CLANG_LIB_TOOLING_REFACTORING_EXTRACT_SOURCE_EXTRACTION_H
> +
> +#include "clang/Basic/LLVM.h"
> +
> +namespace clang {
> +
> +class LangOptions;
> +class SourceManager;
> +class SourceRange;
> +class Stmt;
> +
> +namespace tooling {
> +
> +/// Determines which semicolons should be inserted during extraction.
> +class ExtractionSemicolonPolicy {
> +public:
> + bool isNeededInExtractedFunction() const {
> + return IsNeededInExtractedFunction;
> + }
> +
> + bool isNeededInOriginalFunction() const { return
> IsNeededInOriginalFunction; }
> +
> + /// Returns the semicolon insertion policy that is needed for
> extraction of
> + /// the given statement from the given source range.
> + static ExtractionSemicolonPolicy compute(const Stmt *S,
> + SourceRange &ExtractedRange,
> + const SourceManager &SM,
> + const LangOptions &LangOpts);
> +
> +private:
> + ExtractionSemicolonPolicy(bool IsNeededInExtractedFunction,
> + bool IsNeededInOriginalFunction)
> + : IsNeededInExtractedFunction(IsNeededInExtractedFunction),
> + IsNeededInOriginalFunction(IsNeededInOriginalFunction) {}
> + bool IsNeededInExtractedFunction;
> + bool IsNeededInOriginalFunction;
> +};
> +
> +} // end namespace tooling
> +} // end namespace clang
> +
> +#endif // LLVM_CLANG_LIB_TOOLING_REFACTORING_EXTRACT_SOURCE_EXTRACTION_H
>
> Modified: cfe/trunk/test/Refactor/Extract/ExtractExprIntoFunction.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Refactor/Extract/
> ExtractExprIntoFunction.cpp?rev=317343&r1=317342&r2=317343&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Refactor/Extract/ExtractExprIntoFunction.cpp (original)
> +++ cfe/trunk/test/Refactor/Extract/ExtractExprIntoFunction.cpp Fri Nov
> 3 11:11:22 2017
> @@ -20,10 +20,10 @@ void simpleExtractStmtNoCaptures() {
> // CHECK: 1 'astatement' results:
> // CHECK: static void extracted() {
> // CHECK-NEXT: int a = 1;
> -// CHECK-NEXT: int b = 2;;{{$}}
> +// CHECK-NEXT: int b = 2;{{$}}
> // CHECK-NEXT: }{{[[:space:]].*}}
> // CHECK-NEXT: void simpleExtractStmtNoCaptures() {
> -// CHECK-NEXT: /*range astatement=->+1:13*/extracted(){{$}}
> +// CHECK-NEXT: /*range astatement=->+1:13*/extracted();{{$}}
> // CHECK-NEXT: }
>
>
>
> Added: cfe/trunk/test/Refactor/Extract/ExtractionSemicolonPolicy.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Refactor/Extract/
> ExtractionSemicolonPolicy.cpp?rev=317343&view=auto
> ============================================================
> ==================
> --- cfe/trunk/test/Refactor/Extract/ExtractionSemicolonPolicy.cpp (added)
> +++ cfe/trunk/test/Refactor/Extract/ExtractionSemicolonPolicy.cpp Fri
> Nov 3 11:11:22 2017
> @@ -0,0 +1,192 @@
> +// RUN: clang-refactor extract -selection=test:%s %s -- -std=c++11 2>&1 |
> grep -v CHECK | FileCheck %s
> +
> +struct Rectangle { int width, height; };
> +
> +void extractStatement(const Rectangle &r) {
> + /*range adeclstmt=->+0:59*/int area = r.width * r.height;
> +}
> +// CHECK: 1 'adeclstmt' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: int area = r.width * r.height;{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +// CHECK-NEXT: void extractStatement(const Rectangle &r) {
> +// CHECK-NEXT: /*range adeclstmt=->+0:59*/extracted();{{$}}
> +// CHECK-NEXT: }
> +
> +void extractStatementNoSemiIf(const Rectangle &r) {
> + /*range bextractif=->+2:4*/if (r.width) {
> + int x = r.height;
> + }
> +}
> +// CHECK: 1 'bextractif' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: if (r.width) {
> +// CHECK-NEXT: int x = r.height;
> +// CHECK-NEXT: }{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +// CHECK-NEXT: void extractStatementNoSemiIf(const Rectangle &r) {
> +// CHECK-NEXT: /*range bextractif=->+2:4*/extracted();{{$}}
> +// CHECK-NEXT: }
> +
> +void extractStatementDontExtraneousSemi(const Rectangle &r) {
> + /*range cextractif=->+2:4*/if (r.width) {
> + int x = r.height;
> + } ;
> +} //^ This semicolon shouldn't be extracted.
> +// CHECK: 1 'cextractif' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: if (r.width) {
> +// CHECK-NEXT: int x = r.height;
> +// CHECK-NEXT: }{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +// CHECK-NEXT: void extractStatementDontExtraneousSemi(const Rectangle
> &r) {
> +// CHECK-NEXT: extracted(); ;{{$}}
> +// CHECK-NEXT: }
> +
> +void extractStatementNotSemiSwitch() {
> + /*range dextract=->+5:4*/switch (2) {
> + case 1:
> + break;
> + case 2:
> + break;
> + }
> +}
> +// CHECK: 1 'dextract' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: switch (2) {
> +// CHECK-NEXT: case 1:
> +// CHECK-NEXT: break;
> +// CHECK-NEXT: case 2:
> +// CHECK-NEXT: break;
> +// CHECK-NEXT: }{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +// CHECK-NEXT: void extractStatementNotSemiSwitch() {
> +// CHECK-NEXT: extracted();{{$}}
> +// CHECK-NEXT: }
> +
> +void extractStatementNotSemiWhile() {
> + /*range eextract=->+2:4*/while (true) {
> + int x = 0;
> + }
> +}
> +// CHECK: 1 'eextract' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: while (true) {
> +// CHECK-NEXT: int x = 0;
> +// CHECK-NEXT: }{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +// CHECK-NEXT: void extractStatementNotSemiWhile() {
> +// CHECK-NEXT: extracted();{{$}}
> +// CHECK-NEXT: }
> +
> +void extractStatementNotSemiFor() {
> + /*range fextract=->+1:4*/for (int i = 0; i < 10; ++i) {
> + }
> +}
> +// CHECK: 1 'fextract' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: for (int i = 0; i < 10; ++i) {
> +// CHECK-NEXT: }{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +// CHECK-NEXT: void extractStatementNotSemiFor() {
> +// CHECK-NEXT: extracted();{{$}}
> +// CHECK-NEXT: }
> +
> +struct XS {
> + int *begin() { return 0; }
> + int *end() { return 0; }
> +};
> +
> +void extractStatementNotSemiRangedFor(XS xs) {
> + /*range gextract=->+1:4*/for (int i : xs) {
> + }
> +}
> +// CHECK: 1 'gextract' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: for (int i : xs) {
> +// CHECK-NEXT: }{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +// CHECK-NEXT: void extractStatementNotSemiRangedFor(XS xs) {
> +// CHECK-NEXT: extracted();{{$}}
> +// CHECK-NEXT: }
> +
> +void extractStatementNotSemiRangedTryCatch() {
> + /*range hextract=->+3:4*/try { int x = 0; }
> + catch (const int &i) {
> + int y = i;
> + }
> +}
> +// CHECK: 1 'hextract' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: try { int x = 0; }
> +// CHECK-NEXT: catch (const int &i) {
> +// CHECK-NEXT: int y = i;
> +// CHECK-NEXT: }{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +// CHECK-NEXT: void extractStatementNotSemiRangedTryCatch() {
> +// CHECK-NEXT: extracted();{{$}}
> +// CHECK-NEXT: }
> +
> +void extractCantFindSemicolon() {
> + /*range iextract=->+1:17*/do {
> + } while (true)
> + // Add a semicolon in both the extracted and original function as we
> don't
> + // want to extract the semicolon below.
> + ;
> +}
> +// CHECK: 1 'iextract' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: do {
> +// CHECK-NEXT: } while (true);{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +// CHECK-NEXT: void extractCantFindSemicolon() {
> +// CHECK-NEXT: extracted();{{$}}
> +// CHECK-NEXT: //
> +// CHECK-NEXT: //
> +// CHECK-NEXT: ;
> +// CHECK-NEXT: }
> +
> +void extractFindSemicolon() {
> + /*range jextract=->+1:17*/do {
> + } while (true) /*grab*/ ;
> +}
> +// CHECK: 1 'jextract' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: do {
> +// CHECK-NEXT: } while (true) /*grab*/ ;{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +// CHECK-NEXT: void extractFindSemicolon() {
> +// CHECK-NEXT: extracted();{{$}}
> +// CHECK-NEXT: }
> +
> +void call();
> +
> +void careForNonCompoundSemicolons1() {
> + /*range kextract=->+1:11*/if (true)
> + call();
> +}
> +// CHECK: 1 'kextract' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: if (true)
> +// CHECK-NEXT: call();{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +// CHECK-NEXT: void careForNonCompoundSemicolons1() {
> +// CHECK-NEXT: extracted();{{$}}
> +// CHECK-NEXT: }
> +
> +void careForNonCompoundSemicolons2() {
> + /*range lextract=->+3:1*/for (int i = 0; i < 10; ++i)
> + while (i != 0)
> + ;
> + // end right here111!
> +}
> +// CHECK: 1 'lextract' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: for (int i = 0; i < 10; ++i)
> +// CHECK-NEXT: while (i != 0)
> +// CHECK-NEXT: ;{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +// CHECK-NEXT: void careForNonCompoundSemicolons2() {
> +// CHECK-NEXT: extracted();{{$}}
> +// CHECK-NEXT: //
> +// CHECK-NEXT: }
>
> Added: cfe/trunk/test/Refactor/Extract/ExtractionSemicolonPolicy.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Refactor/Extract/
> ExtractionSemicolonPolicy.m?rev=317343&view=auto
> ============================================================
> ==================
> --- cfe/trunk/test/Refactor/Extract/ExtractionSemicolonPolicy.m (added)
> +++ cfe/trunk/test/Refactor/Extract/ExtractionSemicolonPolicy.m Fri Nov
> 3 11:11:22 2017
> @@ -0,0 +1,56 @@
> +// RUN: clang-refactor extract -selection=test:%s %s -- 2>&1 | grep -v
> CHECK | FileCheck %s
> +
> + at interface NSArray
> ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
> + at end
> +
> +void extractStatementNoSemiObjCFor(NSArray *array) {
> + /*range astmt=->+2:4*/for (id i in array) {
> + int x = 0;
> + }
> +}
> +// CHECK: 1 'astmt' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: for (id i in array) {
> +// CHECK-NEXT: int x = 0;
> +// CHECK-NEXT: }{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +
> +void extractStatementNoSemiSync() {
> + id lock;
> + /*range bstmt=->+2:4*/@synchronized(lock) {
> + int x = 0;
> + }
> +}
> +// CHECK: 1 'bstmt' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: @synchronized(lock) {
> +// CHECK-NEXT: int x = 0;
> +// CHECK-NEXT: }{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +
> +void extractStatementNoSemiAutorel() {
> + /*range cstmt=->+2:4*/@autoreleasepool {
> + int x = 0;
> + }
> +}
> +// CHECK: 1 'cstmt' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: @autoreleasepool {
> +// CHECK-NEXT: int x = 0;
> +// CHECK-NEXT: }{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
> +
> +void extractStatementNoSemiTryFinalllllly() {
> + /*range dstmt=->+3:4*/@try {
> + int x = 0;
> + } @finally {
> + }
> +}
> +// CHECK: 1 'dstmt' results:
> +// CHECK: static void extracted() {
> +// CHECK-NEXT: @try {
> +// CHECK-NEXT: int x = 0;
> +// CHECK-NEXT: } @finally {
> +// CHECK-NEXT: }{{$}}
> +// CHECK-NEXT: }{{[[:space:]].*}}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171103/360fb8b9/attachment-0001.html>
More information about the cfe-commits
mailing list