Browse Source

Merge pull request #3 from eidheim/master

Diagnostics implemented.
merge-requests/37/head
Jørgen Lien Sellæg 11 years ago
parent
commit
e71b0d033c
  1. 3
      cmake/Modules/FindLibClang.cmake
  2. 4
      src/CMakeLists.txt
  3. 7
      src/CodeCompleteResults.cc
  4. 1
      src/CodeCompleteResults.h
  5. 12
      src/CompletionString.cc
  6. 8
      src/CompletionString.h
  7. 2
      src/Cursor.h
  8. 46
      src/Diagnostic.cc
  9. 28
      src/Diagnostic.h
  10. 2
      src/SourceLocation.cc
  11. 2
      src/SourceLocation.h
  12. 2
      src/SourceRange.cc
  13. 3
      src/SourceRange.h
  14. 4
      src/Token.h
  15. 131
      src/Tokens.cc
  16. 10
      src/Tokens.h
  17. 66
      src/TranslationUnit.cc
  18. 10
      src/TranslationUnit.h
  19. 1
      src/clangmm.h
  20. 3
      tests/CMakeLists.txt
  21. 2
      tests/CodeCompleteResults_H_Test.cc
  22. 4
      tests/CompletionString_H_Test.cc
  23. 32
      tests/Diagnostics_Test.cc
  24. 2
      tests/SourceLocation_H_Test.cc
  25. 6
      tests/Token_H_Test.cc
  26. 7
      tests/case/main_error.cpp

3
cmake/Modules/FindLibClang.cmake

@ -14,7 +14,8 @@
# Known LLVM release numbers. # Known LLVM release numbers.
# most recent versions come first # most recent versions come first
set(LIBCLANG_KNOWN_LLVM_VERSIONS 3.6 set(LIBCLANG_KNOWN_LLVM_VERSIONS 3.6.1
3.6
3.5.1 3.5.1
3.5.0 #Arch Linux 3.5.0 #Arch Linux
3.5 #LLVM Debian/Ubuntu packages from http://llvm.org/apt/ 3.5 #LLVM Debian/Ubuntu packages from http://llvm.org/apt/

4
src/CMakeLists.txt

@ -1,4 +1,4 @@
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3 -Wall -Wno-reorder")
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_HOME_DIRECTORY}/cmake/Modules/") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_HOME_DIRECTORY}/cmake/Modules/")
@ -25,6 +25,7 @@ set(header_files
Token.h Token.h
Tokens.h Tokens.h
TranslationUnit.h TranslationUnit.h
Diagnostic.h
) )
set(cc_files set(cc_files
CodeCompleteResults.cc CodeCompleteResults.cc
@ -39,6 +40,7 @@ set(cc_files
Token.cc Token.cc
Tokens.cc Tokens.cc
TranslationUnit.cc TranslationUnit.cc
Diagnostic.cc
) )
add_library(${project_name} SHARED ${header_files} ${cc_files}) add_library(${project_name} SHARED ${header_files} ${cc_files})

7
src/CodeCompleteResults.cc

@ -22,10 +22,15 @@ CodeCompleteResults(clang::TranslationUnit *tu,
column, column,
files.data(), files.data(),
files.size(), files.size(),
clang_defaultCodeCompleteOptions()); clang_defaultCodeCompleteOptions()|CXCodeComplete_IncludeBriefComments);
clang_sortCodeCompletionResults(results_->Results, results_->NumResults); clang_sortCodeCompletionResults(results_->Results, results_->NumResults);
} }
clang::CodeCompleteResults::~CodeCompleteResults() {
delete[] results_->Results;
delete results_;
}
int clang::CodeCompleteResults:: int clang::CodeCompleteResults::
size() { size() {
return results_->NumResults; return results_->NumResults;

1
src/CodeCompleteResults.h

@ -13,6 +13,7 @@ namespace clang {
const std::map<std::string, std::string> &buffers, const std::map<std::string, std::string> &buffers,
int line_num, int line_num,
int column); int column);
~CodeCompleteResults();
CompletionString get(int index); CompletionString get(int index);
int size(); int size();

12
src/CompletionString.cc

@ -26,6 +26,16 @@ get_chunks() {
return res; return res;
} }
std::string clang::CompletionString::get_brief_comments() {
std::string brief_comments;
auto cxstr=clang_getCompletionBriefComment(str_);
if(cxstr.data!=NULL) {
brief_comments=clang_getCString(cxstr);
clang_disposeString(cxstr);
}
return brief_comments;
}
clang::CompletionChunk:: clang::CompletionChunk::
CompletionChunk(std::string chunk, clang::CompletionChunkKind kind) : CompletionChunk(std::string chunk, clang::CompletionChunkKind kind) :
chunk_(chunk), kind_(kind) { } chunk(chunk), kind(kind) { }

8
src/CompletionString.h

@ -21,16 +21,14 @@ namespace clang {
class CompletionChunk { class CompletionChunk {
public: public:
CompletionChunk(std::string chunk, CompletionChunkKind kind); CompletionChunk(std::string chunk, CompletionChunkKind kind);
const std::string& chunk() const { return chunk_; } std::string chunk;
const CompletionChunkKind& kind() const { return kind_; } CompletionChunkKind kind;
private:
std::string chunk_;
CompletionChunkKind kind_;
}; };
class CompletionString { class CompletionString {
public: public:
std::vector<CompletionChunk> get_chunks(); std::vector<CompletionChunk> get_chunks();
std::string get_brief_comments();
int get_num_chunks(); int get_num_chunks();
private: private:
explicit CompletionString(const CXCompletionString &str); explicit CompletionString(const CXCompletionString &str);

2
src/Cursor.h

@ -174,12 +174,14 @@ namespace clang {
class Cursor { class Cursor {
public: public:
Cursor() {}
Cursor(TranslationUnit *tu, SourceLocation *source_location); Cursor(TranslationUnit *tu, SourceLocation *source_location);
const CursorKind kind(); const CursorKind kind();
private: private:
CXCursor cursor_; CXCursor cursor_;
friend SourceRange; friend SourceRange;
friend SourceLocation; friend SourceLocation;
friend Tokens;
}; };
} // namespace clang } // namespace clang
#endif // CURSOR_H_ #endif // CURSOR_H_

46
src/Diagnostic.cc

@ -0,0 +1,46 @@
#include "Diagnostic.h"
#include "SourceLocation.h"
#include "Tokens.h"
clang::Diagnostic::Diagnostic(clang::TranslationUnit& tu, CXDiagnostic& clang_diagnostic) {
severity=clang_getDiagnosticSeverity(clang_diagnostic);
severity_spelling=get_severity_spelling(severity);
spelling=clang_getCString(clang_getDiagnosticSpelling(clang_diagnostic));
clang::SourceLocation location(clang_getDiagnosticLocation(clang_diagnostic));
std::string tmp_path;
unsigned line, column, offset;
location.get_location_info(&tmp_path, &line, &column, &offset);
path=tmp_path;
start_location.line=line;
start_location.column=column;
start_location.offset=offset;
clang::SourceRange range(&location, &location);
clang::Tokens tokens(&tu, &range);
if(tokens.size()==1) {
auto& token=tokens[0];
clang::SourceRange range=token.get_source_range(&tu);
clang::SourceLocation location(&range, false);
location.get_location_info(NULL, &line, &column, &offset);
end_location.line=line;
end_location.column=column;
end_location.offset=offset;
}
}
const std::string clang::Diagnostic::get_severity_spelling(unsigned severity) {
switch(severity) {
case CXDiagnostic_Ignored:
return "Ignored";
case CXDiagnostic_Note:
return "Note";
case CXDiagnostic_Warning:
return "Warning";
case CXDiagnostic_Error:
return "Error";
case CXDiagnostic_Fatal:
return "Fatal";
default:
return "";
}
}

28
src/Diagnostic.h

@ -0,0 +1,28 @@
#ifndef DIAGNOSTIC_H_
#define DIAGNOSTIC_H_
#include <string>
#include <vector>
#include <clang-c/Index.h>
#include "TranslationUnit.h"
namespace clang {
class Diagnostic {
public:
class LocationData {
public:
unsigned line, column, offset;
};
Diagnostic(clang::TranslationUnit& tu, CXDiagnostic& clang_diagnostic);
static const std::string get_severity_spelling(unsigned severity);
unsigned severity;
std::string severity_spelling;
std::string spelling;
std::string path;
LocationData start_location, end_location;
};
}
#endif // DIAGNOSTIC_H_

2
src/SourceLocation.cc

@ -52,7 +52,7 @@ get_location_info(std::string* path,
unsigned *offset) { unsigned *offset) {
CXFile file; CXFile file;
clang_getExpansionLocation(location_, &file, line, column, offset); clang_getExpansionLocation(location_, &file, line, column, offset);
if (path != NULL) { if (path != NULL && file!=NULL) {
path->operator=(((clang_getCString((clang_getFileName(file)))))); path->operator=(((clang_getCString((clang_getFileName(file))))));
} }
} }

2
src/SourceLocation.h

@ -21,6 +21,8 @@ namespace clang {
const std::string &filepath, const std::string &filepath,
int offset); int offset);
SourceLocation(CXSourceLocation location) {location_=location;}
explicit SourceLocation(Cursor *cursor); explicit SourceLocation(Cursor *cursor);
void get_location_info(std::string* path, void get_location_info(std::string* path,

2
src/SourceRange.cc

@ -10,8 +10,6 @@ SourceRange(clang::SourceLocation *start, clang::SourceLocation *end) {
range_ = clang_getRange(start->location_, end->location_); range_ = clang_getRange(start->location_, end->location_);
} }
clang::SourceRange::~SourceRange() { }
clang::SourceRange::SourceRange(Cursor *cursor) { clang::SourceRange::SourceRange(Cursor *cursor) {
range_ = clang_getCursorExtent(cursor->cursor_); range_ = clang_getCursorExtent(cursor->cursor_);
} }

3
src/SourceRange.h

@ -7,16 +7,17 @@
namespace clang { namespace clang {
class SourceRange { class SourceRange {
public: public:
SourceRange() {}
SourceRange(TranslationUnit *tu, Token *token); SourceRange(TranslationUnit *tu, Token *token);
SourceRange(SourceLocation *start, SourceRange(SourceLocation *start,
SourceLocation *end); SourceLocation *end);
explicit SourceRange(Cursor *cursor); explicit SourceRange(Cursor *cursor);
~SourceRange();
private: private:
CXSourceRange range_; CXSourceRange range_;
friend Tokens; friend Tokens;
friend SourceLocation; friend SourceLocation;
friend Diagnostic;
}; };
} // namespace clang } // namespace clang
#endif // SOURCERANGE_H_ #endif // SOURCERANGE_H_

4
src/Token.h

@ -19,13 +19,13 @@ namespace clang {
std::string get_token_spelling(TranslationUnit *tu); std::string get_token_spelling(TranslationUnit *tu);
SourceLocation get_source_location(TranslationUnit *tu); SourceLocation get_source_location(TranslationUnit *tu);
SourceRange get_source_range(TranslationUnit *tu); SourceRange get_source_range(TranslationUnit *tu);
std::string type;
private: private:
explicit Token(const CXToken &token); explicit Token(const CXToken &token);
friend SourceRange; friend SourceRange;
friend SourceLocation; friend SourceLocation;
friend Tokens; friend Tokens;
CXToken token_; const CXToken& token_;
}; };
} // namespace clang } // namespace clang
#endif // TOKEN_H_ #endif // TOKEN_H_

131
src/Tokens.cc

@ -1,21 +1,136 @@
#include "Tokens.h" #include "Tokens.h"
clang::Tokens::Tokens(clang::TranslationUnit *tu, clang::SourceRange *range) { #include <iostream>
using namespace std;
clang::Tokens::Tokens(clang::TranslationUnit *tu, clang::SourceRange *range): tu(*tu) {
clang_tokenize(tu->tu_, clang_tokenize(tu->tu_,
range->range_, range->range_,
&tokens_, &tokens_,
&num_tokens_); &num_tokens_);
for (int i = 0; i < num_tokens_; i++) { for (int i = 0; i < num_tokens_; i++) {
tks.push_back(clang::Token(tokens_[i])); push_back(clang::Token(tokens_[i]));
} }
} }
clang::Tokens::~Tokens() { clang::Tokens::~Tokens() {
// instead of using clang_disposeTokens() the implementation clang_disposeTokens(tu.tu_, tokens_, size());
// of the latter method is just free(token_) the same as
// delete(tokens_) eliminating the need of tu*
delete tokens_;
} }
std::vector<clang::Token>& clang::Tokens::tokens() { void clang::Tokens::update_types(clang::TranslationUnit *tu) {
return tks; clang_cursors.clear();
clang_cursors.reserve(size());
clang_annotateTokens(tu->tu_, tokens_, size(), clang_cursors.data());
for(size_t c=0;c<size();c++) {
auto referenced=clang_getCursorReferenced(clang_cursors[c]);
if(!clang_Cursor_isNull(referenced)) {
auto type=clang_getCursorType(referenced);
auto cxstr=clang_getTypeSpelling(type);
std::string spelling=clang_getCString(cxstr);
clang_disposeString(cxstr);
std::string auto_end="";
//TODO fix const auto
if((spelling.size()>=4 && spelling.substr(0, 4)=="auto")) {
auto_end=spelling.substr(4);
auto type=clang_getCanonicalType(clang_getCursorType(clang_cursors[c]));
auto cxstr=clang_getTypeSpelling(type);
spelling=clang_getCString(cxstr);
clang_disposeString(cxstr);
if(spelling.find(" ")==std::string::npos)
spelling+=auto_end;
}
(*this)[c].type=spelling;
//std::cout << clang_getCString(clang_getTypeSpelling(type)) << ": " << type.kind << endl;
////auto cursor=clang_getTypeDeclaration(type);
////tks[c].type=clang_getCString(clang_getCursorSpelling(cursor));
////auto type=clang_getCursorType(referenced);
}
//Testing:
/*if(tks[c].get_token_spelling(tu)=="text_view") {
cout << tks[c].get_token_spelling(tu) << endl;
auto kind=clang_getCursorKind(cursors[c].cursor_);
cout << " " << kind << endl;
cout << " Decl: " << clang_isDeclaration(kind) << endl;
cout << " Attr: " << clang_isAttribute(kind) << endl;
cout << " Ref: " << clang_isReference(kind) << endl;
cout << " Expr: " << clang_isExpression(kind) << endl;
auto referenced=clang_getCursorReferenced(cursors[c].cursor_);
if(!clang_Cursor_isNull(referenced)) {
cout << " " << clang_getCursorKind(referenced) << endl;
clang::Cursor referenced_cursor;
referenced_cursor.cursor_=referenced;
auto range=clang::SourceRange(&referenced_cursor);
auto location=clang::SourceLocation(&range, true);
std::string path;
unsigned line, column, offset;
location.get_location_info(&path, &line, &column, &offset);
cout << " start: " << path << ", " << line << ", " << column << endl;
location=clang::SourceLocation(&range, false);
location.get_location_info(&path, &line, &column, &offset);
cout << " start: " << path << ", " << line << ", " << column << endl;
auto type=clang_getCursorType(referenced);
cout << " " << clang_getCString(clang_getTypeSpelling(type)) << endl;
}
}*/
}
}
std::string clang::Tokens::get_brief_comments(size_t cursor_id) {
std::string comment_string;
auto referenced=clang_getCursorReferenced(clang_cursors[cursor_id]);
auto comment=clang_Cursor_getParsedComment(referenced);
if(clang_Comment_getKind(comment)==CXComment_FullComment) {
size_t para_c=0;
for(unsigned c=0;c<clang_Comment_getNumChildren(comment);c++) {
auto child_comment=clang_Comment_getChild(comment, c);
if(clang_Comment_getKind(child_comment)==CXComment_Paragraph) {
para_c++;
if(para_c>=2)
break;
for(unsigned c=0;c<clang_Comment_getNumChildren(child_comment);c++) {
auto grandchild_comment=clang_Comment_getChild(child_comment, c);
if(clang_Comment_getKind(grandchild_comment)==CXComment_Text) {
auto cxstr=clang_TextComment_getText(grandchild_comment);
comment_string+=clang_getCString(cxstr);
comment_string+="\n";
clang_disposeString(cxstr);
size_t dot_position=comment_string.find(".");
if(dot_position!=std::string::npos)
return comment_string.substr(0, dot_position);
}
if(clang_Comment_getKind(grandchild_comment)==CXComment_InlineCommand) {
auto cxstr=clang_InlineCommandComment_getCommandName(grandchild_comment);
if(comment_string.size()>0)
comment_string.pop_back();
if(clang_InlineCommandComment_getNumArgs(grandchild_comment)==0)
comment_string+=clang_getCString(cxstr);
clang_disposeString(cxstr);
for(unsigned arg_c=0;arg_c<clang_InlineCommandComment_getNumArgs(grandchild_comment);arg_c++) {
auto cxstr=clang_InlineCommandComment_getArgText(grandchild_comment, arg_c);
if(cxstr.data!=NULL) {
if(arg_c>0)
comment_string+=" ";
comment_string+=clang_getCString(cxstr);
clang_disposeString(cxstr);
}
}
}
}
}
/*cout << " " << clang_Comment_getKind(child_comment) << ", children: " << clang_Comment_getNumChildren(child_comment) << endl;
auto cxstr=clang_FullComment_getAsHTML(child_comment);
cout << " " << clang_getCString(cxstr) << endl;
clang_disposeString(cxstr);*/
}
while(comment_string.size()>0 && (comment_string.back()=='\n' || comment_string.back()==' '))
comment_string.pop_back();
}
return comment_string;
} }

10
src/Tokens.h

@ -5,15 +5,17 @@
#include "Token.h" #include "Token.h"
namespace clang { namespace clang {
class Tokens { class Tokens : public std::vector<clang::Token> {
public: public:
Tokens(TranslationUnit *tu, SourceRange *range); Tokens(TranslationUnit *tu, SourceRange *range);
~Tokens(); ~Tokens();
std::vector<Token>& tokens(); void update_types(clang::TranslationUnit *tu);
protected: std::string get_brief_comments(size_t cursor_id);
std::vector<clang::Token> tks; private:
CXToken *tokens_; CXToken *tokens_;
unsigned num_tokens_; unsigned num_tokens_;
std::vector<CXCursor> clang_cursors;
TranslationUnit& tu;
}; };
} // namespace clang } // namespace clang
#endif // TOKENS_H_ #endif // TOKENS_H_

66
src/TranslationUnit.cc

@ -1,4 +1,8 @@
#include "TranslationUnit.h" #include "TranslationUnit.h"
#include "SourceLocation.h"
#include "Tokens.h"
#include <fstream>
#include <sstream>
clang::TranslationUnit:: clang::TranslationUnit::
~TranslationUnit() { ~TranslationUnit() {
@ -15,27 +19,24 @@ clang::TranslationUnit::
TranslationUnit(Index *index, TranslationUnit(Index *index,
const std::string &filepath, const std::string &filepath,
const std::vector<std::string> &command_line_args) { const std::vector<std::string> &command_line_args) {
std::vector<const char*> args; std::map<std::string, std::string> buffers;
for(auto &a: command_line_args) { std::ifstream ifs(filepath, std::ifstream::in);
args.push_back(a.c_str()); std::stringstream ss;
} ss << ifs.rdbuf();
tu_ = clang_createTranslationUnitFromSourceFile(index->index_, buffers[filepath]=ss.str();
filepath.c_str(), parse(index, filepath, command_line_args, buffers);
args.size(),
args.data(),
0,
NULL);
} }
clang::TranslationUnit:: clang::TranslationUnit::
TranslationUnit(Index *index, TranslationUnit(Index *index,
const std::string &filepath) { const std::string &filepath) {
tu_ = clang_createTranslationUnitFromSourceFile(index->index_, std::vector<std::string> command_line_args;
filepath.c_str(), std::map<std::string, std::string> buffers;
0, std::ifstream ifs(filepath, std::ifstream::in);
NULL, std::stringstream ss;
0, ss << ifs.rdbuf();
NULL); buffers[filepath]=ss.str();
parse(index, filepath, command_line_args, buffers);
} }
clang::TranslationUnit:: clang::TranslationUnit::
@ -44,6 +45,14 @@ TranslationUnit(clang::Index *index,
const std::vector<std::string> &command_line_args, const std::vector<std::string> &command_line_args,
const std::map<std::string, std::string> &buffers, const std::map<std::string, std::string> &buffers,
unsigned flags) { unsigned flags) {
parse(index, filepath, command_line_args, buffers, flags);
}
void clang::TranslationUnit::parse(Index *index,
const std::string &filepath,
const std::vector<std::string> &command_line_args,
const std::map<std::string, std::string> &buffers,
unsigned flags) {
std::vector<CXUnsavedFile> files; std::vector<CXUnsavedFile> files;
for (auto &buffer : buffers) { for (auto &buffer : buffers) {
CXUnsavedFile file; CXUnsavedFile file;
@ -57,13 +66,13 @@ TranslationUnit(clang::Index *index,
args.push_back(a.c_str()); args.push_back(a.c_str());
} }
tu_ = tu_ =
clang_parseTranslationUnit(index->index_, clang_parseTranslationUnit(index->index_,
filepath.c_str(), filepath.c_str(),
args.data(), args.data(),
args.size(), args.size(),
files.data(), files.data(),
files.size(), files.size(),
flags); flags);
} }
int clang::TranslationUnit:: int clang::TranslationUnit::
@ -85,5 +94,14 @@ ReparseTranslationUnit(const std::string &file_path,
} }
unsigned clang::TranslationUnit::DefaultFlags() { unsigned clang::TranslationUnit::DefaultFlags() {
return CXTranslationUnit_CacheCompletionResults | CXTranslationUnit_PrecompiledPreamble | CXTranslationUnit_Incomplete; return CXTranslationUnit_CacheCompletionResults | CXTranslationUnit_PrecompiledPreamble | CXTranslationUnit_Incomplete | CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
}
void clang::TranslationUnit::update_diagnostics() {
diagnostics.clear();
for(unsigned c=0;c<clang_getNumDiagnostics(tu_);c++) {
CXDiagnostic clang_diagnostic=clang_getDiagnostic(tu_, c);
diagnostics.emplace_back(clang::Diagnostic(*this, clang_diagnostic));
clang_disposeDiagnostic(clang_diagnostic);
}
} }

10
src/TranslationUnit.h

@ -6,6 +6,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include "Index.h" #include "Index.h"
#include "Diagnostic.h"
namespace clang { namespace clang {
class Token; class Token;
@ -14,6 +15,7 @@ namespace clang {
class SourceRange; class SourceRange;
class Cursor; class Cursor;
class CodeCompleteResults; class CodeCompleteResults;
class Diagnostic;
class TranslationUnit { class TranslationUnit {
public: public:
@ -34,7 +36,15 @@ namespace clang {
&buffers, &buffers,
unsigned flags=DefaultFlags()); unsigned flags=DefaultFlags());
static unsigned DefaultFlags(); static unsigned DefaultFlags();
void update_diagnostics();
std::vector<clang::Diagnostic> diagnostics;
private: private:
void parse(Index *index,
const std::string &filepath,
const std::vector<std::string> &command_line_args,
const std::map<std::string, std::string> &buffers,
unsigned flags=DefaultFlags());
friend Token; friend Token;
friend Tokens; friend Tokens;
friend SourceLocation; friend SourceLocation;

1
src/clangmm.h

@ -12,4 +12,5 @@
#include "CompletionString.h" #include "CompletionString.h"
#include "Index.h" #include "Index.h"
#include "Cursor.h" #include "Cursor.h"
#include "Diagnostic.h"
#endif // CLANGMM_H_ #endif // CLANGMM_H_

3
tests/CMakeLists.txt

@ -1,6 +1,6 @@
set(project_tests ${project_name}_tests) set(project_tests ${project_name}_tests)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_HOME_DIRECTORY}/cmake/Modules/") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_HOME_DIRECTORY}/cmake/Modules/")
@ -23,6 +23,7 @@ add_executable(${project_tests}
Cursor_H_Test.cc Cursor_H_Test.cc
Token_H_Test.cc Token_H_Test.cc
SourceLocation_H_Test.cc SourceLocation_H_Test.cc
Diagnostics_Test.cc
) )
include_directories(${LIBCLANG_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} "${CMAKE_SOURCE_DIR}/src") include_directories(${LIBCLANG_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} "${CMAKE_SOURCE_DIR}/src")

2
tests/CodeCompleteResults_H_Test.cc

@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(code_complete_results) {
bool substr_found=false; bool substr_found=false;
for(int c=0;c<results.size();c++) { for(int c=0;c<results.size();c++) {
if(results.get(c).get_chunks()[1].chunk()=="substr") { if(results.get(c).get_chunks()[1].chunk=="substr") {
substr_found=true; substr_found=true;
break; break;
} }

4
tests/CompletionString_H_Test.cc

@ -5,8 +5,8 @@
BOOST_AUTO_TEST_CASE(completion_chunk) { BOOST_AUTO_TEST_CASE(completion_chunk) {
clang::CompletionChunk str("(", clang::CompletionChunk_LeftBrace); clang::CompletionChunk str("(", clang::CompletionChunk_LeftBrace);
BOOST_CHECK(str.chunk() == "("); BOOST_CHECK(str.chunk == "(");
BOOST_CHECK(str.kind() == clang::CompletionChunk_LeftBrace); BOOST_CHECK(str.kind == clang::CompletionChunk_LeftBrace);
} }
BOOST_AUTO_TEST_CASE(completion_string) { BOOST_AUTO_TEST_CASE(completion_string) {

32
tests/Diagnostics_Test.cc

@ -0,0 +1,32 @@
#include <boost/test/unit_test.hpp>
#include "clangmm.h"
#include <iostream>
#include <fstream>
using namespace std;
BOOST_AUTO_TEST_CASE(diagnostics_test) {
std::string path("./case/main_error.cpp");
clang::Index index(0, 0);
std::map<std::string, std::string> map_buffers;
ifstream ifs(path, ifstream::in);
stringstream ss;
ss << ifs.rdbuf();
map_buffers["./case/main_error.cpp"]=ss.str();
std::vector<std::string> args;
clang::TranslationUnit tu(&index, path, args, map_buffers);
tu.update_diagnostics();
BOOST_CHECK(tu.diagnostics.size()==1);
BOOST_CHECK(tu.diagnostics[0].spelling=="use of undeclared identifier 'undeclared_variable'");
BOOST_CHECK(tu.diagnostics[0].path=="./case/main_error.cpp");
BOOST_CHECK(tu.diagnostics[0].severity==3);
BOOST_CHECK(tu.diagnostics[0].start_location.line==5);
BOOST_CHECK(tu.diagnostics[0].end_location.line==5);
BOOST_CHECK(tu.diagnostics[0].start_location.column==16);
BOOST_CHECK(tu.diagnostics[0].end_location.column==35);
}

2
tests/SourceLocation_H_Test.cc

@ -13,7 +13,7 @@ BOOST_AUTO_TEST_CASE(source_location) {
clang::SourceRange range(&start, &end); clang::SourceRange range(&start, &end);
clang::Tokens tokens(&tu, &range); clang::Tokens tokens(&tu, &range);
clang::SourceRange token_range = tokens.tokens()[28].get_source_range(&tu); clang::SourceRange token_range = tokens[28].get_source_range(&tu);
unsigned token_start_line, token_start_column, token_start_offset, unsigned token_start_line, token_start_column, token_start_offset,
token_end_line, token_end_column, token_end_offset; token_end_line, token_end_column, token_end_offset;

6
tests/Token_H_Test.cc

@ -15,9 +15,9 @@ BOOST_AUTO_TEST_CASE(token) {
clang::Tokens tokens(&tu, &range); clang::Tokens tokens(&tu, &range);
BOOST_CHECK(tokens.tokens().size() == 32); BOOST_CHECK(tokens.size() == 32);
BOOST_CHECK(tokens.tokens()[1].kind() == clang::TokenKind::Token_Identifier); BOOST_CHECK(tokens[1].kind() == clang::TokenKind::Token_Identifier);
std::string str = tokens.tokens()[28].get_token_spelling(&tu); std::string str = tokens[28].get_token_spelling(&tu);
BOOST_CHECK(str == "return"); BOOST_CHECK(str == "return");
} }

7
tests/case/main_error.cpp

@ -0,0 +1,7 @@
#include <iostream>
int main(int argc, char *argv[]) {
std::cout << "Hello, World!" << std::endl;
std::cout << undeclared_variable << std::endl;
return 0;
}
Loading…
Cancel
Save