Skip to content

Refactoring tool: Avoid re-tokenizing when collecting the available refactorings in a given source range. NFC #11857

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions include/swift/Parse/Lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,16 @@ class Lexer {
bool tryLexConflictMarker();
};

/// Given an ordered token \param Array , get the iterator pointing to the first
/// token that is not before \param Loc .
template<typename ArrayTy, typename Iterator = typename ArrayTy::iterator>
Iterator token_lower_bound(ArrayTy &Array, SourceLoc Loc) {
return std::lower_bound(Array.begin(), Array.end(), Loc,
[](const Token &T, SourceLoc L) {
return T.getLoc().getOpaquePointerValue() < L.getOpaquePointerValue();
});
}

} // end namespace swift

#endif
21 changes: 8 additions & 13 deletions lib/IDE/Refactoring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1257,15 +1257,10 @@ struct SimilarExprCollector: public SourceEntityWalker {

/// Find all tokens included by an expression.
llvm::ArrayRef<Token> getExprSlice(Expr *E) {
auto TokenComp = [&](const Token &LHS, SourceLoc Loc) {
return SM.isBeforeInBuffer(LHS.getLoc(), Loc);
};
SourceLoc StartLoc = E->getStartLoc();
SourceLoc EndLoc = E->getEndLoc();
auto StartIt = std::lower_bound(AllTokens.begin(), AllTokens.end(),
StartLoc, TokenComp);
auto EndIt = std::lower_bound(AllTokens.begin(), AllTokens.end(),
EndLoc, TokenComp);
auto StartIt = token_lower_bound(AllTokens, StartLoc);
auto EndIt = token_lower_bound(AllTokens, EndLoc);
assert(StartIt->getLoc() == StartLoc);
assert(EndIt->getLoc() == EndLoc);
return AllTokens.slice(StartIt - AllTokens.begin(), EndIt - StartIt + 1);
Expand Down Expand Up @@ -1333,16 +1328,16 @@ bool RefactoringActionExtractExprBase::performChange() {
Collector.walk(BS);

if (ExtractRepeated) {
unsigned BufferId = *TheFile->getBufferID();

// Tokenize the brace statement; all expressions should have their tokens
// in this array.
std::vector<Token> AllToks(tokenize(Ctx.LangOpts, SM, BufferId,
/*start offset*/SM.getLocOffsetInBuffer(BS->getStartLoc(), BufferId),
/*end offset*/SM.getLocOffsetInBuffer(BS->getEndLoc(), BufferId)));
auto AllTokens = TheFile->getAllTokens();
auto StartIt = token_lower_bound(AllTokens, BS->getStartLoc());
auto EndIt = token_lower_bound(AllTokens, BS->getEndLoc());

// Collect all expressions we are going to extract.
SimilarExprCollector(SM, SelectedExpr, AllToks, AllExpressions).walk(BS);
SimilarExprCollector(SM, SelectedExpr,
AllTokens.slice(StartIt - AllTokens.begin(), EndIt - StartIt + 1),
AllExpressions).walk(BS);
} else {
AllExpressions.insert(SelectedExpr);
}
Expand Down
43 changes: 26 additions & 17 deletions lib/IDE/SwiftSourceDocInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ struct RangeResolver::Implementation {
};


std::vector<Token> TokensInRange;
ArrayRef<Token> TokensInRange;
SourceLoc Start;
SourceLoc End;

Expand Down Expand Up @@ -1066,32 +1066,41 @@ struct RangeResolver::Implementation {
createInstance(SourceFile &File, unsigned StartOff, unsigned Length) {
SourceManager &SM = File.getASTContext().SourceMgr;
unsigned BufferId = File.getBufferID().getValue();

LangOptions Opts = File.getASTContext().LangOpts;
Opts.AttachCommentsToDecls = true;
std::vector<Token> AllTokens = tokenize(Opts, SM, BufferId, 0, 0, false);
auto TokenComp = [&](Token &LHS, SourceLoc Loc) {
return SM.isBeforeInBuffer(LHS.getLoc(), Loc);
};

auto AllTokens = File.getAllTokens();
SourceLoc StartRaw = SM.getLocForOffset(BufferId, StartOff);
SourceLoc EndRaw = SM.getLocForOffset(BufferId, StartOff + Length);

// This points to the first token after or on the start loc.
auto StartIt = std::lower_bound(AllTokens.begin(), AllTokens.end(), StartRaw,
TokenComp);
auto StartIt = token_lower_bound(AllTokens, StartRaw);

// Skip all the comments.
while(StartIt != AllTokens.end()) {
if (StartIt->getKind() != tok::comment)
break;
StartIt ++;
}

// Erroneous case.
if (StartIt == AllTokens.end())
return nullptr;

// This points to the first token after or on the end loc;
auto EndIt = std::lower_bound(AllTokens.begin(), AllTokens.end(), EndRaw,
TokenComp);
auto EndIt = token_lower_bound(AllTokens, EndRaw);

// Adjust end token to skip comments.
while (EndIt != AllTokens.begin()) {
EndIt --;
if (EndIt->getKind() != tok::comment)
break;
}

// Erroneous case.
if (StartIt == AllTokens.end() || EndIt == AllTokens.begin())
if (EndIt < StartIt)
return nullptr;

// The start token is inclusive.
unsigned StartIdx = StartIt - AllTokens.begin();

return std::unique_ptr<Implementation>(new Implementation(File,
llvm::makeArrayRef(AllTokens.data() + StartIdx, EndIt - StartIt)));
AllTokens.slice(StartIdx, EndIt - StartIt + 1)));
}

static std::unique_ptr<Implementation>
Expand Down
6 changes: 1 addition & 5 deletions lib/Parse/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,10 +308,7 @@ class TokenRecorder: public ConsumeTokenReceiver {
llvm::DenseMap<const void*, tok> TokenKindChangeMap;

std::vector<Token>::iterator lower_bound(SourceLoc Loc) {
return std::lower_bound(Bag.begin(), Bag.end(), Loc,
[](const Token &T, SourceLoc L) {
return T.getLoc().getOpaquePointerValue() < L.getOpaquePointerValue();
});
return token_lower_bound(Bag, Loc);
}

std::vector<Token>::iterator lower_bound(Token Tok) {
Expand Down Expand Up @@ -400,7 +397,6 @@ class TokenRecorder: public ConsumeTokenReceiver {
llvm::SmallVector<Token, 4> TokensToConsume;
if (Tok.hasComment()) {
relexComment(Tok.getCommentRange(), TokensToConsume);
Tok.clearCommentLength();
}

TokensToConsume.push_back(Tok);
Expand Down
1 change: 1 addition & 0 deletions tools/swift-ide-test/swift-ide-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2669,6 +2669,7 @@ static int doPrintRangeInfo(const CompilerInvocation &InitInvok,
CompilerInvocation Invocation(InitInvok);
Invocation.addInputFilename(SourceFileName);
Invocation.getLangOptions().DisableAvailabilityChecking = false;
Invocation.getLangOptions().KeepTokensInSourceFile = true;

CompilerInstance CI;

Expand Down