~pali/llvm/clang-tools-extra-3.9

« back to all changes in this revision

Viewing changes to include-fixer/IncludeFixerContext.cpp

  • Committer: hokein
  • Date: 2016-07-13 16:43:54 UTC
  • Revision ID: svn-v4:91177308-0d34-0410-b5e6-96231b3b80d8:clang-tools-extra/trunk:275279
[include-fixer] Implement adding missing namespace qualifiers in vim integration.

Summary:
The patch extends include-fixer's "-output-headers", and "-insert-headers"
command line options to make it dump more information (e.g. QualifiedSymbol),
so that vim-integration can add missing qualifiers.

Reviewers: bkramer

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D22299

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
namespace clang {
14
14
namespace include_fixer {
15
15
 
16
 
IncludeFixerContext::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
 
}
 
16
namespace {
32
17
 
33
 
tooling::Replacement
34
 
IncludeFixerContext::createSymbolReplacement(llvm::StringRef FilePath,
35
 
                                             size_t Idx) {
36
 
  assert(Idx < MatchedSymbols.size());
 
18
std::string createQualifiedNameForReplacement(
 
19
    llvm::StringRef RawSymbolName,
 
20
    llvm::StringRef SymbolScopedQualifiers,
 
21
    const find_all_symbols::SymbolInfo &MatchedSymbol) {
37
22
  // No need to add missing qualifiers if SymbolIndentifer has a global scope
38
23
  // operator "::".
39
 
  if (getSymbolIdentifier().startswith("::"))
40
 
    return tooling::Replacement();
41
 
  std::string QualifiedName = MatchedSymbols[Idx].getQualifiedName();
 
24
  if (RawSymbolName.startswith("::"))
 
25
    return RawSymbolName;
 
26
 
 
27
  std::string QualifiedName = MatchedSymbol.getQualifiedName();
 
28
 
42
29
  // For nested classes, the qualified name constructed from database misses
43
30
  // some stripped qualifiers, because when we search a symbol in database,
44
31
  // we strip qualifiers from the end until we find a result. So append the
46
33
  //
47
34
  // Get stripped qualifiers.
48
35
  llvm::SmallVector<llvm::StringRef, 8> SymbolQualifiers;
49
 
  getSymbolIdentifier().split(SymbolQualifiers, "::");
 
36
  RawSymbolName.split(SymbolQualifiers, "::");
50
37
  std::string StrippedQualifiers;
51
38
  while (!SymbolQualifiers.empty() &&
52
39
         !llvm::StringRef(QualifiedName).endswith(SymbolQualifiers.back())) {
56
43
  // Append the missing stripped qualifiers.
57
44
  std::string FullyQualifiedName = QualifiedName + StrippedQualifiers;
58
45
  auto pos = FullyQualifiedName.find(SymbolScopedQualifiers);
59
 
  return {FilePath, SymbolRange.getOffset(), SymbolRange.getLength(),
60
 
          FullyQualifiedName.substr(
61
 
              pos == std::string::npos ? 0 : SymbolScopedQualifiers.size())};
 
46
  return FullyQualifiedName.substr(
 
47
      pos == std::string::npos ? 0 : SymbolScopedQualifiers.size());
 
48
}
 
49
 
 
50
} // anonymous namespace
 
51
 
 
52
IncludeFixerContext::IncludeFixerContext(
 
53
    llvm::StringRef Name, llvm::StringRef ScopeQualifiers,
 
54
    std::vector<find_all_symbols::SymbolInfo> Symbols,
 
55
    tooling::Range Range)
 
56
    : SymbolIdentifier(Name), SymbolScopedQualifiers(ScopeQualifiers),
 
57
      MatchedSymbols(std::move(Symbols)), SymbolRange(Range) {
 
58
  for (const auto &Symbol : MatchedSymbols) {
 
59
    HeaderInfos.push_back({Symbol.getFilePath().str(),
 
60
                           createQualifiedNameForReplacement(
 
61
                               SymbolIdentifier, ScopeQualifiers, Symbol)});
 
62
  }
 
63
  // Deduplicate header infos.
 
64
  HeaderInfos.erase(std::unique(HeaderInfos.begin(), HeaderInfos.end(),
 
65
                                [](const HeaderInfo &A, const HeaderInfo &B) {
 
66
                                  return A.Header == B.Header &&
 
67
                                         A.QualifiedName == B.QualifiedName;
 
68
                                }),
 
69
                    HeaderInfos.end());
62
70
}
63
71
 
64
72
} // include_fixer