blob: 33483b4e37f67b0d585dd2d72465b284fae0c47f [file] [log] [blame]
Haojian Wu783d4312016-07-08 13:11:38 +00001//===-- IncludeFixerContext.cpp - Include fixer context ---------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "IncludeFixerContext.h"
11#include <algorithm>
12
13namespace clang {
14namespace include_fixer {
15
16IncludeFixerContext::IncludeFixerContext(
17 llvm::StringRef Name, llvm::StringRef ScopeQualifiers,
18 const std::vector<find_all_symbols::SymbolInfo> Symbols,
19 tooling::Range Range)
20 : SymbolIdentifier(Name), SymbolScopedQualifiers(ScopeQualifiers),
21 MatchedSymbols(Symbols), SymbolRange(Range) {
22 // Deduplicate headers, so that we don't want to suggest the same header
23 // twice.
24 for (const auto &Symbol : MatchedSymbols)
25 Headers.push_back(Symbol.getFilePath());
26 Headers.erase(std::unique(Headers.begin(), Headers.end(),
27 [](const std::string &A, const std::string &B) {
28 return A == B;
29 }),
30 Headers.end());
31}
32
33tooling::Replacement
34IncludeFixerContext::createSymbolReplacement(llvm::StringRef FilePath,
35 size_t Idx) {
36 assert(Idx < MatchedSymbols.size());
Haojian Wu5d9482d2016-07-08 14:28:43 +000037 // No need to add missing qualifiers if SymbolIndentifer has a global scope
38 // operator "::".
39 if (getSymbolIdentifier().startswith("::"))
40 return tooling::Replacement();
Haojian Wu783d4312016-07-08 13:11:38 +000041 std::string QualifiedName = MatchedSymbols[Idx].getQualifiedName();
42 // For nested classes, the qualified name constructed from database misses
43 // some stripped qualifiers, because when we search a symbol in database,
44 // we strip qualifiers from the end until we find a result. So append the
45 // missing stripped qualifiers here.
46 //
47 // Get stripped qualifiers.
48 llvm::SmallVector<llvm::StringRef, 8> SymbolQualifiers;
49 getSymbolIdentifier().split(SymbolQualifiers, "::");
50 std::string StrippedQualifiers;
51 while (!SymbolQualifiers.empty() &&
52 !llvm::StringRef(QualifiedName).endswith(SymbolQualifiers.back())) {
53 StrippedQualifiers = "::" + SymbolQualifiers.back().str();
54 SymbolQualifiers.pop_back();
55 }
56 // Append the missing stripped qualifiers.
57 std::string FullyQualifiedName = QualifiedName + StrippedQualifiers;
58 auto pos = FullyQualifiedName.find(SymbolScopedQualifiers);
59 return {FilePath, SymbolRange.getOffset(), SymbolRange.getLength(),
60 FullyQualifiedName.substr(
61 pos == std::string::npos ? 0 : SymbolScopedQualifiers.size())};
62}
63
64} // include_fixer
65} // clang