Skip to content

Commit

Permalink
add start of type system
Browse files Browse the repository at this point in the history
  • Loading branch information
tjfontaine committed Dec 28, 2011
1 parent 3d1ffaf commit 139606a
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 5 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,3 +1,4 @@
.lock-wscript
build/
libclang.node
*.swp
61 changes: 61 additions & 0 deletions src/constants.cc
Expand Up @@ -185,4 +185,65 @@ ConstantsInitialize(v8::Handle<v8::Object> target)

target->Set(v8::String::NewSymbol("KINDS"), KINDS);

TYPES = v8::Persistent<v8::Object>(v8::Object::New());

NODE_DEFINE_CONSTANT(TYPES, CXType_Invalid);
NODE_DEFINE_CONSTANT(TYPES, CXType_Unexposed);
NODE_DEFINE_CONSTANT(TYPES, CXType_Void);
NODE_DEFINE_CONSTANT(TYPES, CXType_Bool);
NODE_DEFINE_CONSTANT(TYPES, CXType_Char_U);
NODE_DEFINE_CONSTANT(TYPES, CXType_UChar);
NODE_DEFINE_CONSTANT(TYPES, CXType_Char16);
NODE_DEFINE_CONSTANT(TYPES, CXType_Char32);
NODE_DEFINE_CONSTANT(TYPES, CXType_UShort);
NODE_DEFINE_CONSTANT(TYPES, CXType_UInt);
NODE_DEFINE_CONSTANT(TYPES, CXType_ULong);
NODE_DEFINE_CONSTANT(TYPES, CXType_ULongLong);
NODE_DEFINE_CONSTANT(TYPES, CXType_UInt128);
NODE_DEFINE_CONSTANT(TYPES, CXType_Char_S);
NODE_DEFINE_CONSTANT(TYPES, CXType_SChar);
NODE_DEFINE_CONSTANT(TYPES, CXType_WChar);
NODE_DEFINE_CONSTANT(TYPES, CXType_Short);
NODE_DEFINE_CONSTANT(TYPES, CXType_Int);
NODE_DEFINE_CONSTANT(TYPES, CXType_Long);
NODE_DEFINE_CONSTANT(TYPES, CXType_LongLong);
NODE_DEFINE_CONSTANT(TYPES, CXType_Int128);
NODE_DEFINE_CONSTANT(TYPES, CXType_Float);
NODE_DEFINE_CONSTANT(TYPES, CXType_Double);
NODE_DEFINE_CONSTANT(TYPES, CXType_LongDouble);
NODE_DEFINE_CONSTANT(TYPES, CXType_NullPtr);
NODE_DEFINE_CONSTANT(TYPES, CXType_Overload);
NODE_DEFINE_CONSTANT(TYPES, CXType_Dependent);
NODE_DEFINE_CONSTANT(TYPES, CXType_ObjCId);
NODE_DEFINE_CONSTANT(TYPES, CXType_ObjCClass);
NODE_DEFINE_CONSTANT(TYPES, CXType_ObjCSel);
NODE_DEFINE_CONSTANT(TYPES, CXType_Complex);
NODE_DEFINE_CONSTANT(TYPES, CXType_Pointer);
NODE_DEFINE_CONSTANT(TYPES, CXType_BlockPointer);
NODE_DEFINE_CONSTANT(TYPES, CXType_LValueReference);
NODE_DEFINE_CONSTANT(TYPES, CXType_RValueReference);
NODE_DEFINE_CONSTANT(TYPES, CXType_Record);
NODE_DEFINE_CONSTANT(TYPES, CXType_Enum);
NODE_DEFINE_CONSTANT(TYPES, CXType_Typedef);
NODE_DEFINE_CONSTANT(TYPES, CXType_ObjCInterface);
NODE_DEFINE_CONSTANT(TYPES, CXType_ObjCObjectPointer);
NODE_DEFINE_CONSTANT(TYPES, CXType_FunctionNoProto);
NODE_DEFINE_CONSTANT(TYPES, CXType_FunctionProto);
NODE_DEFINE_CONSTANT(TYPES, CXType_ConstantArray);
NODE_DEFINE_CONSTANT(TYPES, CXType_Vector);

/* Duplicates
CXType_FirstBuiltin = CXType_Void,
CXType_LastBuiltin = CXType_ObjCSel,
*/

props = TYPES->GetPropertyNames();
for (i = 0; i < props->Length(); i++)
{
v8::Local<v8::Value> key = props->Get(v8::Integer::New(i));
v8::Local<v8::Value> value = KINDS->Get(key);
TYPES->Set(value, key);
}

target->Set(v8::String::NewSymbol("TYPES"), TYPES);
}
1 change: 1 addition & 0 deletions src/constants.h
Expand Up @@ -5,6 +5,7 @@
#include <clang-c/Index.h>

static v8::Persistent<v8::Object> KINDS;
static v8::Persistent<v8::Object> TYPES;
void ConstantsInitialize(v8::Handle<v8::Object> target);

#endif
2 changes: 2 additions & 0 deletions src/libclang.cc
Expand Up @@ -2,6 +2,7 @@
#include "translation.h"
#include "ncursor.h"
#include "constants.h"
#include "type.h"

using namespace v8;
using namespace node;
Expand All @@ -15,6 +16,7 @@ init (Handle<Object> target)
Index::Initialize(target);
TranslationUnit::Initialize(target);
NCursor::Initialize(target);
Type::Initialize(target);
}

NODE_MODULE(libclang, init)
24 changes: 20 additions & 4 deletions src/ncursor.cc
Expand Up @@ -2,13 +2,17 @@
#include "ncursor.h"
#include "nstring.h"
#include "constants.h"
#include "type.h"

using namespace v8;
using namespace node;
using namespace nclang;

#define USR String::NewSymbol("usr")
#define KIND String::NewSymbol("kind")
#define SPELL String::NewSymbol("spelling")
#define DISPLAY String::NewSymbol("displayname")
#define TYPE String::NewSymbol("type")

NCursor*
NCursor::New(CXCursor cx)
Expand Down Expand Up @@ -65,21 +69,30 @@ NCursor::Visit(const Arguments &args)
}

static Handle<Value>
StringGetter(Local<String> property, const AccessorInfo& info)
Getter(Local<String> property, const AccessorInfo& info)
{
HandleScope scope;
NCursor *c = ObjectWrap::Unwrap<NCursor>(info.This());

if (USR == property)
return scope.Close(from_string(clang_getCursorUSR(c->opaque_)));
else if (SPELL == property)
return scope.Close(from_string(clang_getCursorSpelling(c->opaque_)));
else if (DISPLAY == property)
return scope.Close(from_string(clang_getCursorDisplayName(c->opaque_)));
else if (KIND == property)
{
CXCursorKind k = clang_getCursorKind(c->opaque_);
Local<Value> ki = Integer::New(k);
return scope.Close(ki);
}
else if (TYPE == property)
{
Type *t = Type::New(clang_getCursorType(c->opaque_));
return scope.Close(t->handle_);
}

return info.This();
return Undefined();
}

Persistent<FunctionTemplate> NCursor::Klass;
Expand All @@ -95,8 +108,11 @@ NCursor::Initialize(Handle<Object> target)

NODE_SET_PROTOTYPE_METHOD(Klass, "visitChildren", Visit);

Klass->PrototypeTemplate()->SetAccessor(USR, StringGetter);
Klass->PrototypeTemplate()->SetAccessor(KIND, StringGetter);
Klass->PrototypeTemplate()->SetAccessor(USR, Getter);
Klass->PrototypeTemplate()->SetAccessor(SPELL, Getter);
Klass->PrototypeTemplate()->SetAccessor(DISPLAY, Getter);
Klass->PrototypeTemplate()->SetAccessor(KIND, Getter);
Klass->PrototypeTemplate()->SetAccessor(TYPE, Getter);

target->Set(String::NewSymbol("cursor"), Klass->GetFunction());
}
64 changes: 64 additions & 0 deletions src/type.cc
@@ -0,0 +1,64 @@
#include "type.h"
#include "nstring.h"

using namespace v8;
using namespace node;
using namespace nclang;

#define KIND String::NewSymbol("kind")
#define SPELL String::NewSymbol("spelling")
#define RESULT String::NewSymbol("result")

Type*
Type::New(CXType ct)
{
Local<Object> self = Klass->GetFunction()->NewInstance();
Type *t = ObjectWrap::Unwrap<Type>(self);
t->opaque_ = ct;
return t;
}

Handle<Value>
Type::New(const Arguments &args)
{
HandleScope scope;
Type *t = new Type();
t->Wrap(args.This());
return args.This();
}

static Handle<Value>
Getter(Local<String> property, const AccessorInfo& info)
{
HandleScope scope;
Type *t = ObjectWrap::Unwrap<Type>(info.This());

if (KIND == property)
return scope.Close(Integer::New(t->opaque_.kind));
else if (SPELL == property)
return scope.Close(from_string(clang_getTypeKindSpelling(t->opaque_.kind)));
else if (RESULT == property)
{
Type *nt = Type::New(clang_getResultType(t->opaque_));
return scope.Close(nt->handle_);
}

return Undefined();
}
Persistent<FunctionTemplate> Type::Klass;

void
Type::Initialize(Handle<Object> target)
{
HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New(New);
Klass = Persistent<FunctionTemplate>::New(t);

Klass->InstanceTemplate()->SetInternalFieldCount(1);

Klass->PrototypeTemplate()->SetAccessor(KIND, Getter);
Klass->PrototypeTemplate()->SetAccessor(SPELL, Getter);
Klass->PrototypeTemplate()->SetAccessor(RESULT, Getter);

target->Set(String::NewSymbol("type"), Klass->GetFunction());
}
20 changes: 20 additions & 0 deletions src/type.h
@@ -0,0 +1,20 @@
#ifndef NCLANG_TYPE_H
#define NCLANG_TYPE_H

#include <node.h>
#include <clang-c/Index.h>

namespace nclang
{
class Type : public node::ObjectWrap
{
public:
CXType opaque_;
static void Initialize(v8::Handle<v8::Object> target);
static v8::Handle<v8::Value> New(const v8::Arguments &args);
static Type* New(CXType ct);
static v8::Persistent<v8::FunctionTemplate> Klass;
};
}

#endif
13 changes: 12 additions & 1 deletion test.js
Expand Up @@ -6,8 +6,19 @@ var tu = new libclang.translationunit()
tu.fromSource(idx, "/home/tjfontaine/.llvm/include/clang-c/Index.h");
var curs = tu.cursor();

var funcs = {};
curs.visitChildren(function(parent) {
console.log(libclang.KINDS[this.kind.toString()], '|', parent.usr, '->', this.usr);

switch (this.kind)
{
case libclang.KINDS.CXCursor_FunctionDecl:
console.log(this.usr, this.spelling, this.displayname, this.type.spelling);
var result = this.type.result;
console.log('result kind', result.kind, result.spelling);
//return libclang.CXChildVisit_Break;
break;
}

return libclang.CXChildVisit_Recurse;
});

Expand Down
1 change: 1 addition & 0 deletions wscript
Expand Up @@ -30,6 +30,7 @@ def build(bld):
"src/translation.cc",
"src/ncursor.cc",
"src/constants.cc",
"src/type.cc",
]
obj.uselib = ['LLVM']

Expand Down

0 comments on commit 139606a

Please sign in to comment.