Browse Source

Merge branch 'master' into make_install_juci

merge-requests/37/head
Jørgen Lien Sellæg 11 years ago
parent
commit
de26e4f0cb
  1. 2
      src/CMakeLists.txt
  2. 12
      src/CodeCompleteResults.cc
  3. 13
      src/CodeCompleteResults.h
  4. 9
      src/CompileCommand.cc
  5. 23
      src/CompletionString.cc
  6. 6
      src/CompletionString.h
  7. 19
      src/Cursor.cc
  8. 3
      src/Cursor.h
  9. 16
      src/Diagnostic.cc
  10. 7
      src/Diagnostic.h
  11. 47
      src/SourceLocation.cc
  12. 21
      src/SourceLocation.h
  13. 25
      src/SourceRange.cc
  14. 11
      src/SourceRange.h
  15. 71
      src/Token.cc
  16. 14
      src/Token.h
  17. 58
      src/Tokens.cc
  18. 7
      src/Tokens.h
  19. 11
      src/TranslationUnit.cc
  20. 2
      src/TranslationUnit.h
  21. 10
      src/Utility.cc
  22. 10
      src/Utility.h
  23. 1
      src/clangmm.h
  24. 2
      tests/CodeCompleteResults_H_Test.cc
  25. 1
      tests/Diagnostics_Test.cc
  26. 28
      tests/SourceLocation_H_Test.cc
  27. 4
      tests/Token_H_Test.cc

2
src/CMakeLists.txt

@ -26,6 +26,7 @@ set(header_files
Tokens.h Tokens.h
TranslationUnit.h TranslationUnit.h
Diagnostic.h Diagnostic.h
Utility.h
) )
set(cc_files set(cc_files
CodeCompleteResults.cc CodeCompleteResults.cc
@ -41,6 +42,7 @@ set(cc_files
Tokens.cc Tokens.cc
TranslationUnit.cc TranslationUnit.cc
Diagnostic.cc Diagnostic.cc
Utility.cc
) )
add_library(${project_name} SHARED ${header_files} ${cc_files}) add_library(${project_name} SHARED ${header_files} ${cc_files})

12
src/CodeCompleteResults.cc

@ -3,11 +3,9 @@
#include <exception> #include <exception>
clang::CodeCompleteResults:: clang::CodeCompleteResults::
CodeCompleteResults(CXTranslationUnit &cx_tu, CodeCompleteResults(CXTranslationUnit &cx_tu, const std::string &file_name,
const std::string &file_name,
const std::map<std::string, std::string> &buffers, const std::map<std::string, std::string> &buffers,
int line_num, unsigned line_num, unsigned column) {
int column) {
std::vector<CXUnsavedFile> files; std::vector<CXUnsavedFile> files;
for (auto &buffer : buffers) { for (auto &buffer : buffers) {
CXUnsavedFile file; CXUnsavedFile file;
@ -31,15 +29,15 @@ clang::CodeCompleteResults::~CodeCompleteResults() {
delete cx_results; delete cx_results;
} }
int clang::CodeCompleteResults:: unsigned clang::CodeCompleteResults::
size() { size() {
return cx_results->NumResults; return cx_results->NumResults;
} }
clang::CompletionString clang::CodeCompleteResults:: clang::CompletionString clang::CodeCompleteResults::
get(int i) { get(unsigned i) {
if (i >= size()) { if (i >= size()) {
throw std::invalid_argument("clang::CodeCompleteResults::get(int i): i>=size()"); throw std::invalid_argument("clang::CodeCompleteResults::get(unsigned i): i>=size()");
} }
return CompletionString(cx_results->Results[i].CompletionString); return CompletionString(cx_results->Results[i].CompletionString);
} }

13
src/CodeCompleteResults.h

@ -6,15 +6,14 @@
namespace clang { namespace clang {
class CodeCompleteResults { class CodeCompleteResults {
public: friend class TranslationUnit;
CodeCompleteResults(CXTranslationUnit &cx_tu, CodeCompleteResults(CXTranslationUnit &cx_tu, const std::string &file_name,
const std::string &file_name,
const std::map<std::string, std::string> &buffers, const std::map<std::string, std::string> &buffers,
int line_num, unsigned line_num, unsigned column);
int column); public:
~CodeCompleteResults(); ~CodeCompleteResults();
CompletionString get(int index); CompletionString get(unsigned index);
int size(); unsigned size();
CXCodeCompleteResults *cx_results; CXCodeCompleteResults *cx_results;
}; };

9
src/CompileCommand.cc

@ -1,12 +1,13 @@
#include "CompileCommand.h" #include "CompileCommand.h"
#include "CompileCommands.h" #include "CompileCommands.h"
#include "Utility.h"
std::string clang::CompileCommand:: std::string clang::CompileCommand::
get_command() { get_command() {
std::string res; std::string res;
unsigned N = clang_CompileCommand_getNumArgs(cx_command); unsigned N = clang_CompileCommand_getNumArgs(cx_command);
for (int i = 0; i < N; i++) { for (unsigned i = 0; i < N; i++) {
res += clang_getCString(clang_CompileCommand_getArg(cx_command, i)); res += clang::to_string(clang_CompileCommand_getArg(cx_command, i));
} }
return res; return res;
} }
@ -15,8 +16,8 @@ std::vector<std::string> clang::CompileCommand::
get_command_as_args() { get_command_as_args() {
unsigned N = clang_CompileCommand_getNumArgs(cx_command); unsigned N = clang_CompileCommand_getNumArgs(cx_command);
std::vector<std::string> res(N); std::vector<std::string> res(N);
for (int i = 0; i < N; i++) { for (unsigned i = 0; i < N; i++) {
res[i] = clang_getCString(clang_CompileCommand_getArg(cx_command, i)); res[i] = clang::to_string(clang_CompileCommand_getArg(cx_command, i));
} }
return res; return res;
} }

23
src/CompletionString.cc

@ -1,34 +1,27 @@
#include "CompletionString.h" #include "CompletionString.h"
#include "Utility.h"
clang::CompletionString:: clang::CompletionString::
CompletionString(const CXCompletionString &cx_str) : cx_str(cx_str) {} CompletionString(const CXCompletionString &cx_completion_sting) : cx_completion_sting(cx_completion_sting) {}
bool clang::CompletionString::available() { bool clang::CompletionString::available() {
return clang_getCompletionAvailability(cx_str) == CXAvailability_Available; return clang_getCompletionAvailability(cx_completion_sting) == CXAvailability_Available;
} }
int clang::CompletionString::get_num_chunks() { unsigned clang::CompletionString::get_num_chunks() {
return clang_getNumCompletionChunks(cx_str); return clang_getNumCompletionChunks(cx_completion_sting);
} }
std::vector<clang::CompletionChunk> clang::CompletionString::get_chunks() { std::vector<clang::CompletionChunk> clang::CompletionString::get_chunks() {
std::vector<clang::CompletionChunk> res; std::vector<clang::CompletionChunk> res;
for (size_t i = 0; i < get_num_chunks(); i++) { for (unsigned i = 0; i < get_num_chunks(); i++) {
auto cxstr=clang_getCompletionChunkText(cx_str, i); res.emplace_back(clang::to_string(clang_getCompletionChunkText(cx_completion_sting, i)), static_cast<CompletionChunkKind> (clang_getCompletionChunkKind(cx_completion_sting, i)));
res.emplace_back(clang_getCString(cxstr), static_cast<CompletionChunkKind> (clang_getCompletionChunkKind(cx_str, i)));
clang_disposeString(cxstr);
} }
return res; return res;
} }
std::string clang::CompletionString::get_brief_comments() { std::string clang::CompletionString::get_brief_comments() {
std::string brief_comments; return clang::to_string(clang_getCompletionBriefComment(cx_completion_sting));
auto cxstr=clang_getCompletionBriefComment(cx_str);
if(cxstr.data!=NULL) {
brief_comments=clang_getCString(cxstr);
clang_disposeString(cxstr);
}
return brief_comments;
} }
clang::CompletionChunk:: clang::CompletionChunk::

6
src/CompletionString.h

@ -28,13 +28,13 @@ namespace clang {
class CompletionString { class CompletionString {
public: public:
explicit CompletionString(const CXCompletionString &cx_str); explicit CompletionString(const CXCompletionString &cx_completion_sting);
bool available(); bool available();
std::vector<CompletionChunk> get_chunks(); std::vector<CompletionChunk> get_chunks();
std::string get_brief_comments(); std::string get_brief_comments();
int get_num_chunks(); unsigned get_num_chunks();
CXCompletionString cx_str; CXCompletionString cx_completion_sting;
}; };
} // namespace clang } // namespace clang
#endif // COMPLETIONSTRING_H_ #endif // COMPLETIONSTRING_H_

19
src/Cursor.cc

@ -1,4 +1,5 @@
#include "Cursor.h" #include "Cursor.h"
#include "Utility.h"
const clang::CursorKind clang::Cursor::get_kind() { const clang::CursorKind clang::Cursor::get_kind() {
return (CursorKind) clang_getCursorKind(this->cx_cursor); return (CursorKind) clang_getCursorKind(this->cx_cursor);
@ -13,19 +14,15 @@ clang::SourceRange clang::Cursor::get_source_range() const {
} }
std::string clang::Cursor::get_usr() const { std::string clang::Cursor::get_usr() const {
auto cxstr=clang_getCursorUSR(cx_cursor); return clang::to_string(clang_getCursorUSR(cx_cursor));
std::string USR=clang_getCString(cxstr);
clang_disposeString(cxstr);
return USR;
} }
std::string clang::Cursor::get_referenced_usr() const { clang::Cursor clang::Cursor::get_referenced() const {
auto referenced=clang_getCursorReferenced(cx_cursor); return Cursor(clang_getCursorReferenced(cx_cursor));
if(!clang_Cursor_isNull(referenced)) { }
return Cursor(referenced).get_usr();
} clang::Cursor::operator bool() const {
else return !clang_Cursor_isNull(cx_cursor);
return "";
} }
bool clang::Cursor::operator==(const Cursor& rhs) const { bool clang::Cursor::operator==(const Cursor& rhs) const {

3
src/Cursor.h

@ -181,7 +181,8 @@ namespace clang {
SourceLocation get_source_location() const; SourceLocation get_source_location() const;
SourceRange get_source_range() const; SourceRange get_source_range() const;
std::string get_usr() const; std::string get_usr() const;
std::string get_referenced_usr() const; Cursor get_referenced() const;
operator bool() const;
bool operator==(const Cursor& rhs) const; bool operator==(const Cursor& rhs) const;
CXCursor cx_cursor; CXCursor cx_cursor;
}; };

16
src/Diagnostic.cc

@ -1,21 +1,19 @@
#include "Diagnostic.h" #include "Diagnostic.h"
#include "SourceLocation.h" #include "SourceLocation.h"
#include "Tokens.h" #include "Tokens.h"
#include "Utility.h"
clang::Diagnostic::Diagnostic(CXTranslationUnit& cx_tu, CXDiagnostic& cx_diagnostic) { clang::Diagnostic::Diagnostic(CXTranslationUnit& cx_tu, CXDiagnostic& cx_diagnostic) {
severity=clang_getDiagnosticSeverity(cx_diagnostic); severity=clang_getDiagnosticSeverity(cx_diagnostic);
severity_spelling=get_severity_spelling(severity); severity_spelling=get_severity_spelling(severity);
auto cxstr=clang_getDiagnosticSpelling(cx_diagnostic); spelling=clang::to_string(clang_getDiagnosticSpelling(cx_diagnostic));
spelling=clang_getCString(cxstr); clang::SourceLocation start_location(clang_getDiagnosticLocation(cx_diagnostic));
clang_disposeString(cxstr);
clang::SourceLocation location(clang_getDiagnosticLocation(cx_diagnostic));
clang::SourceRange range(location, location); path=start_location.get_path();
clang::Tokens tokens(cx_tu, range); unsigned start_offset=start_location.get_offset();
clang::Tokens tokens(cx_tu, SourceRange(start_location, start_location));
if(tokens.size()==1) { if(tokens.size()==1) {
auto& token=tokens[0]; offsets=std::pair<unsigned, unsigned>(start_offset, tokens.begin()->offsets.second);
auto locations=token.source_range.get_source_locations();
this->range=SourceRange::get_range_data(location, locations.second);
} }
} }

7
src/Diagnostic.h

@ -7,15 +7,16 @@
namespace clang { namespace clang {
class Diagnostic { class Diagnostic {
public: friend class TranslationUnit;
Diagnostic(CXTranslationUnit& cx_tu, CXDiagnostic& cx_diagnostic); Diagnostic(CXTranslationUnit& cx_tu, CXDiagnostic& cx_diagnostic);
public:
static const std::string get_severity_spelling(unsigned severity); static const std::string get_severity_spelling(unsigned severity);
unsigned severity; unsigned severity;
std::string severity_spelling; std::string severity_spelling;
std::string spelling; std::string spelling;
RangeData range; std::string path;
std::pair<unsigned, unsigned> offsets;
}; };
} }

47
src/SourceLocation.cc

@ -1,41 +1,34 @@
#include "SourceLocation.h" #include "SourceLocation.h"
#include "Utility.h"
// // // // // // // // // // // // // // // //
// SourceLocation // // SourceLocation //
// // // // // // // // // // // // // // // //
clang::SourceLocation:: clang::SourceLocation::SourceLocation(CXTranslationUnit &tu, const std::string &filepath, unsigned offset) {
SourceLocation(CXTranslationUnit &tu, CXFile file = clang_getFile(tu, filepath.c_str());
const std::string &filename, cx_location = clang_getLocationForOffset(tu, file, offset);
int line_number,
int line_offset) {
CXFile file = clang_getFile(tu,
filename.c_str());
cx_location = clang_getLocation(tu,
file,
line_number,
line_offset);
} }
clang::SourceLocation:: std::string clang::SourceLocation::get_path() {
SourceLocation(CXTranslationUnit &tu, std::string path;
const std::string &filepath, get_data(&path, NULL, NULL, NULL);
int offset) { return path;
CXFile file = clang_getFile(tu, }
filepath.c_str()); unsigned clang::SourceLocation::get_offset() {
cx_location = clang_getLocationForOffset(tu, unsigned offset;
file, get_data(NULL, NULL, NULL, &offset);
offset); return offset;
} }
void clang::SourceLocation:: void clang::SourceLocation::get_data(std::string* path, unsigned *line, unsigned *column, unsigned *offset) {
get_location_info(std::string* path, if(path==nullptr)
unsigned *line, clang_getExpansionLocation(cx_location, NULL, line, column, offset);
unsigned *column, else {
unsigned *offset) {
CXFile file; CXFile file;
clang_getExpansionLocation(cx_location, &file, line, column, offset); clang_getExpansionLocation(cx_location, &file, line, column, offset);
if (path != NULL && file!=NULL) { if (file!=NULL) {
path->operator=(((clang_getCString((clang_getFileName(file)))))); *path=clang::to_string(clang_getFileName(file));
}
} }
} }

21
src/SourceLocation.h

@ -6,24 +6,19 @@
namespace clang { namespace clang {
class SourceLocation { class SourceLocation {
friend class TranslationUnit;
SourceLocation(CXTranslationUnit &tu, const std::string &filepath, unsigned offset);
public: public:
SourceLocation(const CXSourceLocation& cx_location) : cx_location(cx_location) {} SourceLocation(const CXSourceLocation& cx_location) : cx_location(cx_location) {}
SourceLocation(CXTranslationUnit &cx_tu, public:
const std::string &filename, std::string get_path();
int line_number, unsigned get_offset();
int column);
SourceLocation(CXTranslationUnit &tu,
const std::string &filepath,
int offset);
void get_location_info(std::string *path,
unsigned *line,
unsigned *column,
unsigned *offset);
CXSourceLocation cx_location; CXSourceLocation cx_location;
private:
void get_data(std::string *path, unsigned *line, unsigned *column, unsigned *offset);
}; };
} // namespace clang } // namespace clang

25
src/SourceRange.cc

@ -5,23 +5,10 @@ SourceRange(clang::SourceLocation &start, clang::SourceLocation &end) {
cx_range = clang_getRange(start.cx_location, end.cx_location); cx_range = clang_getRange(start.cx_location, end.cx_location);
} }
std::pair<clang::SourceLocation, clang::SourceLocation> clang::SourceRange::get_source_locations() { std::pair<unsigned, unsigned> clang::SourceRange::get_offsets() {
return std::pair<SourceLocation, SourceLocation>(clang_getRangeStart(cx_range), clang_getRangeEnd(cx_range)); SourceLocation start(clang_getRangeStart(cx_range)), end(clang_getRangeEnd(cx_range));
} std::pair<unsigned, unsigned> offsets;
offsets.first=start.get_offset();
clang::RangeData clang::SourceRange::get_range_data(clang::SourceLocation &start, clang::SourceLocation &end) { offsets.second=end.get_offset();
std::string path; return offsets;
unsigned start_offset, end_offset;
start.get_location_info(&path, NULL, NULL, &start_offset);
end.get_location_info(NULL, NULL, NULL, &end_offset);
RangeData range_data;
range_data.path=path;
range_data.start_offset=start_offset;
range_data.end_offset=end_offset;
return range_data;
}
clang::RangeData clang::SourceRange::get_range_data() {
auto locations=get_source_locations();
return get_range_data(locations.first, locations.second);
} }

11
src/SourceRange.h

@ -3,21 +3,14 @@
#include <clang-c/Index.h> #include <clang-c/Index.h>
#include "SourceLocation.h" #include "SourceLocation.h"
#include <string> #include <string>
#include <utility>
namespace clang { namespace clang {
class RangeData {
public:
std::string path;
unsigned start_offset, end_offset;
};
class SourceRange { class SourceRange {
public: public:
SourceRange(const CXSourceRange& cx_range) : cx_range(cx_range) {} SourceRange(const CXSourceRange& cx_range) : cx_range(cx_range) {}
SourceRange(SourceLocation &start, SourceLocation &end); SourceRange(SourceLocation &start, SourceLocation &end);
std::pair<SourceLocation, SourceLocation> get_source_locations(); std::pair<unsigned, unsigned> get_offsets();
static RangeData get_range_data(SourceLocation &start, SourceLocation &end);
RangeData get_range_data();
CXSourceRange cx_range; CXSourceRange cx_range;
}; };
} // namespace clang } // namespace clang

71
src/Token.cc

@ -1,4 +1,5 @@
#include "Token.h" #include "Token.h"
#include "Utility.h"
// // // // // // // // // //
// Token // // Token //
@ -15,12 +16,11 @@ clang::SourceRange clang::Token::get_source_range() {
return SourceRange(clang_getTokenExtent(cx_tu, cx_token)); return SourceRange(clang_getTokenExtent(cx_tu, cx_token));
} }
// returns a string description of this tokens kind // returns a string description of this tokens kind
std::string clang::Token::get_token_spelling() { std::string clang::Token::get_spelling() {
CXString s = clang_getTokenSpelling(cx_tu, cx_token); return clang::to_string(clang_getTokenSpelling(cx_tu, cx_token));
return std::string(clang_getCString(s));
} }
const clang::TokenKind clang::Token::kind() { const clang::TokenKind clang::Token::get_kind() {
return (TokenKind) clang_getTokenKind(cx_token); return (TokenKind) clang_getTokenKind(cx_token);
} }
@ -30,9 +30,7 @@ bool clang::Token::has_type() {
if(clang_Cursor_isNull(referenced)) if(clang_Cursor_isNull(referenced))
return false; return false;
auto type=clang_getCursorType(referenced); auto type=clang_getCursorType(referenced);
auto cxstr=clang_getTypeSpelling(type); auto spelling=clang::to_string(clang_getTypeSpelling(type));
std::string spelling=clang_getCString(cxstr);
clang_disposeString(cxstr);
return spelling!=""; return spelling!="";
} }
@ -41,17 +39,13 @@ std::string clang::Token::get_type() {
auto referenced=clang_getCursorReferenced(cx_cursor); auto referenced=clang_getCursorReferenced(cx_cursor);
if(!clang_Cursor_isNull(referenced)) { if(!clang_Cursor_isNull(referenced)) {
auto type=clang_getCursorType(referenced); auto type=clang_getCursorType(referenced);
auto cxstr=clang_getTypeSpelling(type); spelling=clang::to_string(clang_getTypeSpelling(type));
spelling=clang_getCString(cxstr);
clang_disposeString(cxstr);
std::string auto_end=""; std::string auto_end="";
//TODO fix const auto //TODO fix const auto
if((spelling.size()>=4 && spelling.substr(0, 4)=="auto")) { if((spelling.size()>=4 && spelling.substr(0, 4)=="auto")) {
auto_end=spelling.substr(4); auto_end=spelling.substr(4);
auto type=clang_getCanonicalType(clang_getCursorType(cx_cursor)); auto type=clang_getCanonicalType(clang_getCursorType(cx_cursor));
auto cxstr=clang_getTypeSpelling(type); spelling=clang::to_string(clang_getTypeSpelling(type));
spelling=clang_getCString(cxstr);
clang_disposeString(cxstr);
if(spelling.find(" ")==std::string::npos) if(spelling.find(" ")==std::string::npos)
spelling+=auto_end; spelling+=auto_end;
} }
@ -61,54 +55,9 @@ std::string clang::Token::get_type() {
std::string clang::Token::get_brief_comments() { std::string clang::Token::get_brief_comments() {
std::string comment_string; std::string comment_string;
auto referenced=clang_getCursorReferenced(cx_cursor); auto referenced=get_cursor().get_referenced();
auto comment=clang_Cursor_getParsedComment(referenced); if(referenced) {
if(clang_Comment_getKind(comment)==CXComment_FullComment) { comment_string=clang::to_string(clang_Cursor_getBriefCommentText(referenced.cx_cursor));
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; return comment_string;
} }

14
src/Token.h

@ -16,12 +16,14 @@ namespace clang {
}; };
class Token { class Token {
public: friend class Tokens;
Token(CXTranslationUnit &cx_tu, CXToken &cx_token, CXCursor &cx_cursor): Token(CXTranslationUnit &cx_tu, CXToken &cx_token, CXCursor &cx_cursor):
cx_tu(cx_tu), cx_token(cx_token), cx_cursor(cx_cursor), source_range(get_source_range()) {}; cx_tu(cx_tu), cx_token(cx_token), cx_cursor(cx_cursor), offsets(get_source_range().get_offsets()) {};
const TokenKind kind(); public:
std::string get_token_spelling(); const TokenKind get_kind();
std::string get_spelling();
SourceLocation get_source_location(); SourceLocation get_source_location();
SourceRange get_source_range();
clang::Cursor get_cursor() {return clang::Cursor(cx_cursor);} clang::Cursor get_cursor() {return clang::Cursor(cx_cursor);}
bool has_type(); bool has_type();
std::string get_type(); std::string get_type();
@ -29,9 +31,7 @@ namespace clang {
CXTranslationUnit &cx_tu; CXTranslationUnit &cx_tu;
CXToken& cx_token; CXToken& cx_token;
CXCursor& cx_cursor; CXCursor& cx_cursor;
SourceRange source_range; std::pair<unsigned, unsigned> offsets;
private:
SourceRange get_source_range();
}; };
} // namespace clang } // namespace clang
#endif // TOKEN_H_ #endif // TOKEN_H_

58
src/Tokens.cc

@ -1,15 +1,15 @@
#include "Tokens.h" #include "Tokens.h"
#include "Utility.h"
#include <iostream> #include <iostream>
using namespace std; using namespace std;
clang::Tokens::Tokens(CXTranslationUnit &cx_tu, SourceRange &range): cx_tu(cx_tu) { clang::Tokens::Tokens(CXTranslationUnit &cx_tu, const SourceRange &range): cx_tu(cx_tu) {
clang_tokenize(cx_tu, range.cx_range, &cx_tokens, &num_tokens); clang_tokenize(cx_tu, range.cx_range, &cx_tokens, &num_tokens);
cx_cursors.clear(); cx_cursors.clear();
cx_cursors.reserve(num_tokens); cx_cursors.resize(num_tokens);
clang_annotateTokens(cx_tu, cx_tokens, num_tokens, cx_cursors.data()); clang_annotateTokens(cx_tu, cx_tokens, num_tokens, cx_cursors.data());
for (int i = 0; i < num_tokens; i++) { for (unsigned i = 0; i < num_tokens; i++) {
emplace_back(cx_tu, cx_tokens[i], cx_cursors[i]); emplace_back(Token(cx_tu, cx_tokens[i], cx_cursors[i]));
} }
} }
@ -20,16 +20,50 @@ clang::Tokens::~Tokens() {
//This works across TranslationUnits! However, to get rename refactoring to work, //This works across TranslationUnits! However, to get rename refactoring to work,
//one have to open all the files that might include a similar token //one have to open all the files that might include a similar token
//Similar tokens defined as tokens with equal referenced cursors. //Similar tokens defined as tokens with equal referenced cursors.
std::vector<std::pair<unsigned, unsigned> > clang::Tokens::get_similar_token_offsets(clang::Token& token) { std::vector<std::pair<unsigned, unsigned> > clang::Tokens::get_similar_token_offsets(const std::string &usr) {
std::vector<std::pair<unsigned, unsigned> > offsets; std::vector<std::pair<unsigned, unsigned> > offsets;
auto referenced_usr=token.get_cursor().get_referenced_usr(); for(auto &token: *this) {
if(referenced_usr!="") { if(token.get_kind()==clang::Token_Identifier) {
for(auto &a_token: *this) { auto referenced=token.get_cursor().get_referenced();
if(referenced_usr==a_token.get_cursor().get_referenced_usr() && token.get_token_spelling()==a_token.get_token_spelling()) { if(referenced && usr==referenced.get_usr()) {
auto range_data=a_token.source_range.get_range_data(); offsets.emplace_back(token.offsets);
offsets.emplace_back(range_data.start_offset, range_data.end_offset);
} }
} }
} }
return offsets; return offsets;
} }
std::vector<std::pair<std::string, unsigned> > clang::Tokens::get_cxx_methods() {
std::vector<std::pair<std::string, unsigned> > methods;
long last_offset=-1;
for(auto &token: *this) {
if(token.get_kind()==clang::Token_Identifier) {
auto cursor=token.get_cursor();
auto kind=cursor.get_kind();
if(kind==clang::CursorKind::CXXMethod || kind==clang::CursorKind::Constructor || kind==clang::CursorKind::Destructor) {
auto offset=cursor.get_source_location().get_offset();
if(offset!=last_offset) {
std::string method;
if(kind==clang::CursorKind::CXXMethod) {
auto type=clang_getResultType(clang_getCursorType(cursor.cx_cursor));
method+=clang::to_string(clang_getTypeSpelling(type));
auto pos=method.find(" ");
if(pos!=std::string::npos)
method.erase(pos, 1);
method+=" ";
}
clang::Cursor parent(clang_getCursorSemanticParent(cursor.cx_cursor));
method+=clang::to_string(clang_getCursorDisplayName(parent.cx_cursor));
method+="::";
method+=clang::to_string(clang_getCursorDisplayName(cursor.cx_cursor));
methods.emplace_back(method, offset);
}
last_offset=offset;
}
}
}
return methods;
}

7
src/Tokens.h

@ -8,10 +8,13 @@
namespace clang { namespace clang {
class Tokens : public std::vector<clang::Token> { class Tokens : public std::vector<clang::Token> {
friend class TranslationUnit;
friend class Diagnostic;
Tokens(CXTranslationUnit &cx_tu, const SourceRange &range);
public: public:
Tokens(CXTranslationUnit &cx_tu, SourceRange &range);
~Tokens(); ~Tokens();
std::vector<std::pair<unsigned, unsigned> > get_similar_token_offsets(clang::Token& token); std::vector<std::pair<unsigned, unsigned> > get_similar_token_offsets(const std::string &usr);
std::vector<std::pair<std::string, unsigned> > get_cxx_methods();
private: private:
CXToken *cx_tokens; CXToken *cx_tokens;
unsigned num_tokens; unsigned num_tokens;

11
src/TranslationUnit.cc

@ -1,6 +1,7 @@
#include "TranslationUnit.h" #include "TranslationUnit.h"
#include "SourceLocation.h" #include "SourceLocation.h"
#include "Tokens.h" #include "Tokens.h"
#include "Utility.h"
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
@ -90,10 +91,8 @@ unsigned clang::TranslationUnit::DefaultFlags() {
return CXTranslationUnit_CacheCompletionResults | CXTranslationUnit_PrecompiledPreamble | CXTranslationUnit_Incomplete | CXTranslationUnit_IncludeBriefCommentsInCodeCompletion; return CXTranslationUnit_CacheCompletionResults | CXTranslationUnit_PrecompiledPreamble | CXTranslationUnit_Incomplete | CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
} }
clang::CodeCompleteResults clang::TranslationUnit::get_code_completions(const std::map<std::string, std::string> &buffers, int line_number, int column) { clang::CodeCompleteResults clang::TranslationUnit::get_code_completions(const std::map<std::string, std::string> &buffers, unsigned line_number, unsigned column) {
auto cxstr=clang_getTranslationUnitSpelling(cx_tu); auto path=clang::to_string(clang_getTranslationUnitSpelling(cx_tu));
std::string path=clang_getCString(cxstr);
clang_disposeString(cxstr);
clang::CodeCompleteResults results(cx_tu, path, buffers, line_number, column); clang::CodeCompleteResults results(cx_tu, path, buffers, line_number, column);
return results; return results;
@ -110,9 +109,7 @@ std::vector<clang::Diagnostic> clang::TranslationUnit::get_diagnostics() {
} }
std::unique_ptr<clang::Tokens> clang::TranslationUnit::get_tokens(unsigned start_offset, unsigned end_offset) { std::unique_ptr<clang::Tokens> clang::TranslationUnit::get_tokens(unsigned start_offset, unsigned end_offset) {
auto cxstr=clang_getTranslationUnitSpelling(cx_tu); auto path=clang::to_string(clang_getTranslationUnitSpelling(cx_tu));
std::string path=clang_getCString(cxstr);
clang_disposeString(cxstr);
clang::SourceLocation start_location(cx_tu, path, start_offset); clang::SourceLocation start_location(cx_tu, path, start_offset);
clang::SourceLocation end_location(cx_tu, path, end_offset); clang::SourceLocation end_location(cx_tu, path, end_offset);
clang::SourceRange range(start_location, end_location); clang::SourceRange range(start_location, end_location);

2
src/TranslationUnit.h

@ -35,7 +35,7 @@ namespace clang {
const std::map<std::string, std::string> &buffers, const std::map<std::string, std::string> &buffers,
unsigned flags=DefaultFlags()); unsigned flags=DefaultFlags());
clang::CodeCompleteResults get_code_completions(const std::map<std::string, std::string> &buffers, int line_number, int column); clang::CodeCompleteResults get_code_completions(const std::map<std::string, std::string> &buffers, unsigned line_number, unsigned column);
std::vector<clang::Diagnostic> get_diagnostics(); std::vector<clang::Diagnostic> get_diagnostics();
std::unique_ptr<Tokens> get_tokens(unsigned start_offset, unsigned end_offset); std::unique_ptr<Tokens> get_tokens(unsigned start_offset, unsigned end_offset);
clang::Cursor get_cursor(std::string path, unsigned offset); clang::Cursor get_cursor(std::string path, unsigned offset);

10
src/Utility.cc

@ -0,0 +1,10 @@
#include "Utility.h"
std::string clang::to_string(CXString cx_string) {
std::string string;
if(cx_string.data!=NULL) {
string=clang_getCString(cx_string);
clang_disposeString(cx_string);
}
return string;
}

10
src/Utility.h

@ -0,0 +1,10 @@
#ifndef UTILITY_H_
#define UTILITY_H_
#include <clang-c/Index.h>
#include <string>
namespace clang {
std::string to_string(CXString cx_string);
}
#endif // UTILITY_H_

1
src/clangmm.h

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

2
tests/CodeCompleteResults_H_Test.cc

@ -31,7 +31,7 @@ BOOST_AUTO_TEST_CASE(code_complete_results) {
auto results=tu.get_code_completions(buffers, 4, 5); auto results=tu.get_code_completions(buffers, 4, 5);
bool substr_found=false; bool substr_found=false;
for(int c=0;c<results.size();c++) { for(unsigned 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;

1
tests/Diagnostics_Test.cc

@ -23,6 +23,5 @@ BOOST_AUTO_TEST_CASE(diagnostics_test) {
auto diagnostics=tu.get_diagnostics(); auto diagnostics=tu.get_diagnostics();
BOOST_CHECK(diagnostics.size()==1); BOOST_CHECK(diagnostics.size()==1);
BOOST_CHECK(diagnostics[0].spelling=="use of undeclared identifier 'undeclared_variable'"); BOOST_CHECK(diagnostics[0].spelling=="use of undeclared identifier 'undeclared_variable'");
BOOST_CHECK(diagnostics[0].range.path=="./case/main_error.cpp");
BOOST_CHECK(diagnostics[0].severity==3); BOOST_CHECK(diagnostics[0].severity==3);
} }

28
tests/SourceLocation_H_Test.cc

@ -10,30 +10,8 @@ BOOST_AUTO_TEST_CASE(source_location) {
clang::TranslationUnit tu(index, path); clang::TranslationUnit tu(index, path);
auto tokens=tu.get_tokens(0, 113); auto tokens=tu.get_tokens(0, 113);
clang::SourceRange token_range = (*tokens)[28].source_range; auto offsets=(*tokens)[28].offsets;
unsigned token_start_line, token_start_column, token_start_offset, BOOST_CHECK(offsets.first == 103);
token_end_line, token_end_column, token_end_offset; BOOST_CHECK(offsets.second == 109);
std::string token_start_path, token_end_path;
auto locations=token_range.get_source_locations();
locations.first.get_location_info(&token_start_path,
&token_start_line,
&token_start_column,
&token_start_offset);
locations.second.get_location_info(&token_end_path,
&token_end_line,
&token_end_column,
&token_end_offset);
BOOST_CHECK(token_start_path == path);
BOOST_CHECK(token_start_line == 6);
BOOST_CHECK(token_start_column == 3);
BOOST_CHECK(token_start_offset == 103);
BOOST_CHECK(token_end_path == path);
BOOST_CHECK(token_end_line == 6);
BOOST_CHECK(token_end_column == 9);
BOOST_CHECK(token_end_offset == 109);
} }

4
tests/Token_H_Test.cc

@ -12,8 +12,8 @@ BOOST_AUTO_TEST_CASE(token) {
auto tokens=tu.get_tokens(0, 113); auto tokens=tu.get_tokens(0, 113);
BOOST_CHECK(tokens->size() == 32); BOOST_CHECK(tokens->size() == 32);
BOOST_CHECK((*tokens)[1].kind() == clang::TokenKind::Token_Identifier); BOOST_CHECK((*tokens)[1].get_kind() == clang::TokenKind::Token_Identifier);
std::string str = (*tokens)[28].get_token_spelling(); std::string str = (*tokens)[28].get_spelling();
BOOST_CHECK(str == "return"); BOOST_CHECK(str == "return");
} }

Loading…
Cancel
Save