Browse Source

Merge pull request #8 from eidheim/master

Can now find similar tokens for refactoring purposes.
merge-requests/37/head
Jørgen Lien Sellæg 11 years ago
parent
commit
27845401a5
  1. 25
      src/Cursor.cc
  2. 4
      src/Cursor.h
  3. 4
      src/Diagnostic.cc
  4. 1
      src/Token.cc
  5. 94
      src/Tokens.cc
  6. 3
      src/Tokens.h
  7. 5
      src/TranslationUnit.cc
  8. 2
      src/TranslationUnit.h
  9. 3
      tests/Cursor_H_Test.cc

25
src/Cursor.cc

@ -4,11 +4,6 @@ const clang::CursorKind clang::Cursor::get_kind() {
return (CursorKind) clang_getCursorKind(this->cx_cursor);
}
clang::Cursor::
Cursor(CXTranslationUnit &cx_tu, clang::SourceLocation &source_location) {
cx_cursor = clang_getCursor(cx_tu, source_location.cx_location);
}
clang::SourceLocation clang::Cursor::get_source_location() const {
return SourceLocation(clang_getCursorLocation(cx_cursor));
}
@ -17,8 +12,22 @@ clang::SourceRange clang::Cursor::get_source_range() const {
return SourceRange(clang_getCursorExtent(cx_cursor));
}
std::string clang::Cursor::get_usr() const {
auto cxstr=clang_getCursorUSR(cx_cursor);
std::string USR=clang_getCString(cxstr);
clang_disposeString(cxstr);
return USR;
}
std::string clang::Cursor::get_referenced_usr() const {
auto referenced=clang_getCursorReferenced(cx_cursor);
if(!clang_Cursor_isNull(referenced)) {
return Cursor(referenced).get_usr();
}
else
return "";
}
bool clang::Cursor::operator==(const Cursor& rhs) const {
auto lhs_rd=get_source_range().get_range_data();
auto rhs_rd=rhs.get_source_range().get_range_data();
return lhs_rd.path==rhs_rd.path && lhs_rd.start_offset==rhs_rd.start_offset && lhs_rd.end_offset==rhs_rd.end_offset;
return get_usr()==rhs.get_usr();
}

4
src/Cursor.h

@ -3,6 +3,7 @@
#include <clang-c/Index.h>
#include "SourceLocation.h"
#include "SourceRange.h"
#include <string>
namespace clang {
enum class CursorKind {
@ -176,10 +177,11 @@ namespace clang {
class Cursor {
public:
Cursor(const CXCursor &cx_cursor) : cx_cursor(cx_cursor) {}
Cursor(CXTranslationUnit &cx_tu, SourceLocation &source_location);
const CursorKind get_kind();
SourceLocation get_source_location() const;
SourceRange get_source_range() const;
std::string get_usr() const;
std::string get_referenced_usr() const;
bool operator==(const Cursor& rhs) const;
CXCursor cx_cursor;
};

4
src/Diagnostic.cc

@ -5,7 +5,9 @@
clang::Diagnostic::Diagnostic(CXTranslationUnit& cx_tu, CXDiagnostic& cx_diagnostic) {
severity=clang_getDiagnosticSeverity(cx_diagnostic);
severity_spelling=get_severity_spelling(severity);
spelling=clang_getCString(clang_getDiagnosticSpelling(cx_diagnostic));
auto cxstr=clang_getDiagnosticSpelling(cx_diagnostic);
spelling=clang_getCString(cxstr);
clang_disposeString(cxstr);
clang::SourceLocation location(clang_getDiagnosticLocation(cx_diagnostic));
clang::SourceRange range(location, location);

1
src/Token.cc

@ -24,6 +24,7 @@ const clang::TokenKind clang::Token::kind() {
return (TokenKind) clang_getTokenKind(cx_token);
}
//TODO: Is there a way to optimise this?
bool clang::Token::has_type() {
auto referenced=clang_getCursorReferenced(cx_cursor);
if(clang_Cursor_isNull(referenced))

94
src/Tokens.cc

@ -17,87 +17,19 @@ clang::Tokens::~Tokens() {
clang_disposeTokens(cx_tu, cx_tokens, size());
}
/*CXCursor clang::Tokens::find_referenced() {
cursors.clear();
cursors.reserve(size());
clang_annotateTokens(tu, tokens.data(), size(), cursors.data());
auto kind=clang_getCursorKind(cursors[0]);
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[0]);
kind=clang_getCursorKind(referenced);
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;
//TODO: To find similar function declarations, these must be equal (if cursor is declaration):
//TODO: How do we know it is a function? clang_getCursorKind(cursor)==CXCursor_CXXMethod?
cout << " " << clang_getCString(clang_getTypeSpelling(clang_getCursorType(referenced))) << endl;
cout << " " << clang_getCString(clang_getTypeSpelling(clang_getCursorType(clang_getCursorSemanticParent(referenced)))) << endl;
cout << " " << clang_getCString(clang_getCursorSpelling(referenced)) << endl;
return referenced;
}*/
void clang::Tokens::rename(CXCursor &referenced) {
for(size_t c=0;c<size();c++) {
auto a_referenced=clang_getCursorReferenced(cx_cursors[c]);
if(Cursor(a_referenced)==Cursor(referenced)) {
std::string path;
unsigned line, column, offset;
clang::Cursor cursor(cx_cursors[c]);
auto range=cursor.get_source_range();
auto locations=range.get_source_locations();
locations.first.get_location_info(&path, &line, &column, &offset);
cout << " start: " << path << ", " << line << ", " << column << endl;
locations.second.get_location_info(&path, &line, &column, &offset);
cout << " end: " << path << ", " << line << ", " << column << endl;
clang::Cursor referenced_cursor(a_referenced);
range=referenced_cursor.get_source_range();
locations=range.get_source_locations();
locations.first.get_location_info(&path, &line, &column, &offset);
cout << " start: " << path << ", " << line << ", " << column << endl;
locations.second.get_location_info(&path, &line, &column, &offset);
cout << " end: " << path << ", " << line << ", " << column << endl;
auto type=clang_getCursorType(a_referenced);
cout << " " << clang_getCString(clang_getTypeSpelling(type)) << endl;
//This works across TranslationUnits! However, to get rename refactoring to work,
//one have to open all the files that might include a similar token
//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> > offsets;
auto referenced_usr=token.get_cursor().get_referenced_usr();
if(referenced_usr!="") {
for(auto &a_token: *this) {
if(referenced_usr==a_token.get_cursor().get_referenced_usr() && token.get_token_spelling()==a_token.get_token_spelling()) {
auto range_data=a_token.source_range.get_range_data();
offsets.emplace_back(range_data.start_offset, range_data.end_offset);
}
}
}
//clang_visitChildren(clang_getTranslationUnitCursor(tu.tu_), clang::Tokens::clang_visitor, &referenced);
return offsets;
}
/*CXChildVisitResult clang::Tokens::clang_visitor(CXCursor cursor, CXCursor parent, CXClientData clientData) {
CXCursor* referenced=(CXCursor*)clientData;
auto a_referenced=clang_getCursorReferenced(cursor);
if(clang_equalCursors(a_referenced, *referenced)) {
cout << "found" << endl;
clang::Cursor a_cursor;
a_cursor.cursor_=cursor;
auto range=clang::SourceRange(&a_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 << " end: " << path << ", " << line << ", " << column << endl;
}
return CXChildVisit_Recurse;
}*/

3
src/Tokens.h

@ -11,8 +11,7 @@ namespace clang {
public:
Tokens(CXTranslationUnit &cx_tu, SourceRange &range);
~Tokens();
void rename(CXCursor &referenced);
//std::unordered_map<std::string, std::unordered_multimap<unsigned, unsigned> >
std::vector<std::pair<unsigned, unsigned> > get_similar_token_offsets(clang::Token& token);
private:
CXToken *cx_tokens;
unsigned num_tokens;

5
src/TranslationUnit.cc

@ -118,3 +118,8 @@ std::unique_ptr<clang::Tokens> clang::TranslationUnit::get_tokens(unsigned start
clang::SourceRange range(start_location, end_location);
return std::unique_ptr<Tokens>(new Tokens(cx_tu, range));
}
clang::Cursor clang::TranslationUnit::get_cursor(std::string path, unsigned offset) {
clang::SourceLocation location(cx_tu, path, offset);
return Cursor(clang_getCursor(cx_tu, location.cx_location));
}

2
src/TranslationUnit.h

@ -9,6 +9,7 @@
#include "Diagnostic.h"
#include "Tokens.h"
#include "CodeCompleteResults.h"
#include "Cursor.h"
namespace clang {
class TranslationUnit {
@ -37,6 +38,7 @@ namespace clang {
clang::CodeCompleteResults get_code_completions(const std::map<std::string, std::string> &buffers, int line_number, int column);
std::vector<clang::Diagnostic> get_diagnostics();
std::unique_ptr<Tokens> get_tokens(unsigned start_offset, unsigned end_offset);
clang::Cursor get_cursor(std::string path, unsigned offset);
CXTranslationUnit cx_tu;
};

3
tests/Cursor_H_Test.cc

@ -12,8 +12,7 @@ BOOST_AUTO_TEST_CASE(cursor) {
// ]
clang::SourceLocation location(tu.cx_tu, path, 6, 4);
clang::Cursor cursor(tu.cx_tu, location);
auto cursor=tu.get_cursor(path, 103);
BOOST_CHECK(cursor.get_kind() == clang::CursorKind::ReturnStmt);
}

Loading…
Cancel
Save