Browse Source

Slightly improved missing header include fixits

pipelines/235045657
eidheim 6 years ago
parent
commit
faca9ba5fe
  1. 81
      src/source_clang.cpp

81
src/source_clang.cpp

@ -387,58 +387,59 @@ void Source::ClangViewParse::update_diagnostics() {
diagnostic.fix_its.emplace_back(clangmm::Diagnostic::FixIt{"#include <" + *cpp_header + ">\n", file_path.string(), get_new_include_offsets()}); diagnostic.fix_its.emplace_back(clangmm::Diagnostic::FixIt{"#include <" + *cpp_header + ">\n", file_path.string(), get_new_include_offsets()});
} }
}; };
if(diagnostic.fix_its.empty() && diagnostic.severity >= clangmm::Diagnostic::Severity::Error && is_token_char(*start)) { if(diagnostic.fix_its.empty() && diagnostic.severity >= clangmm::Diagnostic::Severity::Error) {
auto token_string = get_token(start);
for(size_t c = 0; c < clang_tokens->size(); c++) { for(size_t c = 0; c < clang_tokens->size(); c++) {
auto &token = (*clang_tokens)[c]; auto &token = (*clang_tokens)[c];
if(token.get_kind() == clangmm::Token::Kind::Identifier) { auto &token_offsets = clang_tokens_offsets[c];
auto &token_offsets = clang_tokens_offsets[c]; if(static_cast<unsigned int>(line) == token_offsets.first.line - 1 && static_cast<unsigned int>(index) >= token_offsets.first.index - 1 && static_cast<unsigned int>(index) <= token_offsets.second.index - 1) {
if(static_cast<unsigned int>(line) == token_offsets.first.line - 1 && static_cast<unsigned int>(index) >= token_offsets.first.index - 1 && static_cast<unsigned int>(index) <= token_offsets.second.index - 1) { if(starts_with(diagnostic.spelling, "implicit instantiation of undefined template")) {
if(starts_with(diagnostic.spelling, "implicit instantiation of undefined template")) { size_t start = 44 + 2;
auto cursor = token.get_cursor(); if(start < diagnostic.spelling.size()) {
if(cursor.get_referenced()) { auto end = diagnostic.spelling.find('<', start);
auto type_description = cursor.get_type_description(); if(end == std::string::npos)
end = diagnostic.spelling.find('\'', start);
if(end != std::string::npos) {
auto type = diagnostic.spelling.substr(start, end - start);
bool has_std = false; bool has_std = false;
if(is_cpp) { if(is_cpp) {
if(starts_with(type_description, "std::")) { if(starts_with(type, "std::")) {
has_std = true; has_std = true;
type_description.erase(0, 5); type.erase(0, 5);
} }
if(starts_with(type_description, "__1::")) if(starts_with(type, "__1::"))
type_description.erase(0, 5); type.erase(0, 5);
auto pos = type_description.find('<');
if(pos != std::string::npos)
type_description.erase(pos);
} }
add_include_fixit(has_std, is_cpp && has_using_namespace_std(c), type);
add_include_fixit(has_std, is_cpp && has_using_namespace_std(c), type_description); break;
} }
} }
if(starts_with(diagnostic.spelling, "unknown type name") || }
starts_with(diagnostic.spelling, "no type named") || if(is_token_char(*start) && token.get_kind() == clangmm::Token::Kind::Identifier &&
starts_with(diagnostic.spelling, "no member named") || (starts_with(diagnostic.spelling, "unknown type name") ||
starts_with(diagnostic.spelling, "no template named") || starts_with(diagnostic.spelling, "no type named") ||
starts_with(diagnostic.spelling, "use of undeclared identifier") || starts_with(diagnostic.spelling, "no member named") ||
starts_with(diagnostic.spelling, "implicit instantiation of undefined template") || starts_with(diagnostic.spelling, "no template named") ||
starts_with(diagnostic.spelling, "no viable constructor or deduction guide for deduction of template arguments of")) { starts_with(diagnostic.spelling, "use of undeclared identifier") ||
bool has_std = false; starts_with(diagnostic.spelling, "implicit instantiation of undefined template") ||
if(is_cpp) { starts_with(diagnostic.spelling, "no viable constructor or deduction guide for deduction of template arguments of"))) {
if(token_string == "std" && c + 2 < clang_tokens->size() && (*clang_tokens)[c + 2].get_kind() == clangmm::Token::Kind::Identifier) { auto token_string = get_token(start);
token_string = (*clang_tokens)[c + 2].get_spelling(); bool has_std = false;
has_std = true; if(is_cpp) {
} if(token_string == "std" && c + 2 < clang_tokens->size() && (*clang_tokens)[c + 2].get_kind() == clangmm::Token::Kind::Identifier) {
else if(c >= 2 && token_string = (*clang_tokens)[c + 2].get_spelling();
(*clang_tokens)[c - 1].get_kind() == clangmm::Token::Punctuation && has_std = true;
(*clang_tokens)[c - 2].get_kind() == clangmm::Token::Identifier &&
(*clang_tokens)[c - 1].get_spelling() == "::" &&
(*clang_tokens)[c - 2].get_spelling() == "std")
has_std = true;
} }
else if(c >= 2 &&
add_include_fixit(has_std, is_cpp && has_using_namespace_std(c), token_string); (*clang_tokens)[c - 1].get_kind() == clangmm::Token::Punctuation &&
(*clang_tokens)[c - 2].get_kind() == clangmm::Token::Identifier &&
(*clang_tokens)[c - 1].get_spelling() == "::" &&
(*clang_tokens)[c - 2].get_spelling() == "std")
has_std = true;
} }
break;
add_include_fixit(has_std, is_cpp && has_using_namespace_std(c), token_string);
} }
break;
} }
} }
} }

Loading…
Cancel
Save