Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implemented argument type aliasing

  • Loading branch information...
commit 7fef8bb184e5b6c0abef271cf7a9edce2521914a 1 parent 092f0ee
@codeboost authored
View
222 README
@@ -1,16 +1,17 @@
Running bea
- bea fileName.bea [-oh hfile -oc cppfile -manual]
- -oh = output header file. overrides 'header' directive in the bea file
- -oc = output cpp file. overrides 'cpp' directive in the bea file
- -manual or -m = only the blank implementation of @manual methods and types will be written to the file specified by '-oc'
+ bea fileName.bea [-o outputDir -m -f]
+ -o = the output directory
+ -m = only the blank implementation of @manual methods and types will be written to the file specified in the @project directive
+ -f = force file overwrite. If this parameter is not present and the file already exists, the program will exit
+
Bea file syntax
A bea file is a mixture of special directives (starting with @), C++ declarations and snippets of C++ code.
Bea has been written in CoffeeScript and quite frankly, it has been one the most pleasurable programming experiences in my life.
- The syntax of the bea file tries to borrow from the cleanliness of CoffeeScript (which borrows from Python/Ruby) - braces, semi-columns, etc are not used.
+ The syntax of the bea file tries to borrow from the cleanliness of CoffeeScript (which borrows from Python/Ruby) - braces, semi-columns, etc are optional
The bea parser builds a tree of nodes from the file, based on line indentation.
Each line is a node in the tree, lines below it, which are more indented, are it's children:
@@ -22,130 +23,135 @@ Bea file syntax
AnotherLine
AnotherLine child
-Lines which start with '#' are considered comments and are ignored.
-Lines which must start with '#' (usually inserted C++ preprocessor definitions) can be escaped:
+ Comments start with #. C++ style comments (//) can only be used in C++ code/class declaration. C-style (/* ... */) comments are not supported.
+ Lines which must start with '#' (usually inserted C++ preprocessor definitions) can be escaped:
- #This is a comment, but next line is not
- \#include <header.h>
+ #This is a comment, but next line is not
+ \#include <header.h>
-Bea directives start with the '@' character:
- //bea
- @include "constants.bea"
- @namespace myproject
- @class myclass
-
+ Bea directives start with the '@' character:
+ //bea
+ @include "constants.bea"
+ @namespace myproject
+ @class myclass
-Primary Directives
-
-The following directives can only appear within the root indent of the file.
-@header
+Directives
-Child lines of the @header directive will be inserted at the top of the generated header file. Usually some #include statements.
- #Bea
+ The following directives can only appear within the root indent of the file.
+
@header
- \#include <v8.h>
-
- //Generated C++
- #include <v8.h>
-
-@cpp
+ Child lines of the @header directive will be inserted at the top of the generated header file. Usually some #include statements.
+ #Bea
+ @header
+ \#include <v8.h>
+
+ //Generated C++
+ #include <v8.h>
+
-Child lines of the @cpp directive will be inserted at the top of the generated cpp file. Usually, some #include statements:
@cpp
- \#include "myfile.h"
- \#define MYCONDITION(x);
- using namespace myproject;
-
- //Generated C++ -> myproject.cpp
- #include "myfile.h"
- #define MYCONDITION(x);
- using namespace myproject;
+
+ Child lines of the @cpp directive will be inserted at the top of the generated cpp file. Usually, some #include statements:
+ @cpp
+ \#include "myfile.h"
+ \#define MYCONDITION(x);
+ using namespace myproject;
-@const
-
-All child lines are the constants which are exposed to the javascript.
- #Bea
- @const
- EACCESS
- DBL_MAX
- BUFFER_SIZE
-
- //Generated C++
- namespace jmyproject{
- void ExposeConstants(v8::Handle<v8::Object> target) {
- BEA_DEFINE_CONSTANT(target, EACCESS);
- BEA_DEFINE_CONSTANT(target, DBL_MAX);
- BEA_DEFINE_CONSTANT(target, BUFFER_SIZE);
- }
- }
+ //C++: Generated C++ -> myproject.cpp
+ #include "myfile.h"
+ #define MYCONDITION(x);
+ using namespace myproject;
+
+ @const
+ All child lines are the constants which are exposed to the javascript.
+ #Bea
+ @const
+ EACCESS
+ DBL_MAX
+ BUFFER_SIZE
-Note that only the names of the constants must be entered. It is assumed that during compilation, the C++ compiler knows the values of the constants.
-Tip: You can add a 'using namespace' statement in the @cpp section if your constants are defined in some other namespace.
-
-@targetNamespace namespaceName
+ //C++: Generated C++
+ namespace jmyproject{
+ void ExposeConstants(v8::Handle<v8::Object> target) {
+ BEA_DEFINE_CONSTANT(target, EACCESS);
+ BEA_DEFINE_CONSTANT(target, DBL_MAX);
+ BEA_DEFINE_CONSTANT(target, BUFFER_SIZE);
+ }
+ }
+
+
+ Note that only the names of the constants must be entered. It is assumed that during compilation, the C++ compiler knows the values of the constants.
+ Tip: You can add a 'using namespace' statement in the @cpp section if your constants/enums are defined in some other namespace.
+
+ @targetNamespace namespaceName
+
+ The namespace where the generated exposable code will be placed. Quotes are optional.
+
+ @include "filename.bea"
+
+ Include another bea file. This is done recursively. Note that some directives should only appear once (like @targetNamespace) so make sure that the included files don't override
+ previously defined directives. I see including the file as pasting it in the main bea file in place of the @include line (or rather, replacing the '@include' node with the children of the
+ root node of the included file).
+
+ @namespace native_namespace
+ Context: Root
+
+ This is the C++ namespace of the object(s) you want to expose. If no namespace name is entered, it is assumed that the classes/functions defined below are globally accessible.
+ The children of the @namespace are the objects and types which you want to expose to the Javascript.
+ If the custom types used in function declarations don't have an implicit namespace, these types are assumed to be part of the parent @namespace.
+ #bea
+ @namespace cv
+ #expose cv::Mat
+ @class Mat
+ Mat(Size sz, int type) #__constructor(cv::Size sz, int type)
+ @static Global
+ #bool clipLine(cv::Size imgSize, cv::Point pt1, cv::Point& pt2)
+ bool clipLine(Size imgSize, Point& pt1, Point& pt2)
+ #void namedWindow(const std::string& winname, int flags)
+ void namedWindow(const std::string& winname, int flags)
+
-The namespace where the generated exposable code will be placed. Quotes are optional.
-@include "filename.bea"
+ @class className exposedName : public Base1, public Base2
+ Context: @namespace
-Include another bea file. This is done recursively. Note that some directives should only appear once (like @targetNamespace) so make sure that the included files don't override
-previously defined directives. I see including the file as pasting it in the main bea file instead of the @include line (or rather, replacing the '@include' node with the children of the
-root node of the included file).
+ Sample:
+ //bea
+ @namespace ns
+ @class MyClass
+ MyClass(const int number, bool option = false); #semicolon ; at the end is optional
+ MyClass(const std::string& name, int id = 0, const std::vector<int>& numbers) #argument types and default values
+ int sum(const std::vector<int>* numbers) #references
+ MyClass* clone() #Custom type/pointer return values
+
+
+
+ //Javascript
+ #1
+ var obj = new MyClass(); //throws 'Couldn't determine overload from supplied arguments'
+ #2
+ var obj = new MyClass(0); //calls MyClass::MyClass(const int, bool)
+ var obj = new MyClass("my name"); //calls MyClass(const std::string&, int, std::vector<int>&)
+
+ res = obj.myMethod({x: 0, y: 0}); //assume we a conversion for ns::Point to/from JS is defined
-@namespace native_namespace
-Context: Root
+ Exposes a class to the javascript. The exposed class can be instantiated with javascript's new operator (eg. obj = new className)
+ className must be a valid C++ class declared in the C++ namespace which is defined by the parent @namespace directive.
+ exposedName is the name of the exposed object in Javascript. If exposedName is ommited, className will be used.
-This is the C++ namespace of the object(s) you want to expose. All exposed classes must be part namespaces.
-The children of the @namespace are the objects and types which you want to expose to the Javascript.
-If the custom types used in function declarations don't have an implicit namespace, these types are assumed to be part of the parent @namespace.
+ @class children are the exposed functions. The function declarations are mostly identical to the way they are declared in the C++ class
+ (without the private, protected or public modifiers).
+ You can add multiple overloads of the same function or multiple constructor overloads.
- #bea
- @namespace cv
- #expose cv::Mat
- @class Mat
- Mat(Size sz, int type) #__constructor(cv::Size sz, int type)
- @static Global
- #bool clipLine(cv::Size imgSize, cv::Point pt1, cv::Point& pt2)
- bool clipLine(Size imgSize, Point& pt1, Point& pt2)
- #void namedWindow(const std::string& winname, int flags)
- void namedWindow(const std::string& winname, int flags)
-
-
-
-@class className exposedName
-Context: @namespace
-
-Sample:
- //bea
- @namespace ns
- @class MyClass
- MyClass(const int number, bool option = false); #semicolon ; at the end is optional
- MyClass(const std::string& name, int id = 0, const std::vector<int>& numbers) #argument types and default values
- int sum(const std::vector<int>* numbers) #references
- MyClass* clone() #Custom type/pointer return values
-
-
+ Inheritance
+ As in C++, you can declare the base classes of a class. Note that these must also be defined in the .bea file, *before* the compiler sees the current class.
+ The way inheritance works is described in the chapter Inheritance.
- //Javascript
- #1
- var obj = new MyClass(); //throws 'Couldn't determine overload from supplied arguments'
- #2
- var obj = new MyClass(0); //calls MyClass::MyClass(const int, bool)
- var obj = new MyClass("my name"); //calls MyClass(const std::string&, int, std::vector<int>&)
- res = obj.myMethod({x: 0, y: 0}); //assume we a conversion for ns::Point to/from JS is defined
-
-Exposes a class to the javascript. The exposed class can be instantiated with javascript's new operator (eg. obj = new className)
-className must be a valid C++ class declared in the C++ namespace which is defined by the parent @namespace directive.
-exposedName is the name of the exposed object in Javascript. If exposedName is ommited, className will be used.
-
-@class children are the exposed functions. The function declarations are mostly identical to the way they are declared in the C++ class
-(without the private, protected or public modifiers).
-You can add multiple overloads of the same function or multiple constructor overloads.
View
9 bealoader.js
@@ -83,9 +83,8 @@
return RecursiveParser;
})();
MessageLogger = (function() {
- function MessageLogger() {
- this.warnings = 0;
- }
+ function MessageLogger() {}
+ MessageLogger.warnings = 0;
MessageLogger.prototype.warn = function(msg, node) {
var fileName, line, _ref, _ref2, _ref3;
_ref3 = [(_ref = (node != null ? node.fileName : void 0)) != null ? _ref : "", (_ref2 = (node != null ? node.line : void 0)) != null ? _ref2 : 0], fileName = _ref3[0], line = _ref3[1];
@@ -142,7 +141,8 @@
failed: 0,
constants: 0,
typesConverted: 0,
- typesIgnored: 0
+ typesIgnored: 0,
+ warnings: 0
};
}
BeaLoader.prototype.filenameFromNode = function(node) {
@@ -380,6 +380,7 @@
} else {
return this.convertFull();
}
+ return this.stats.warnings = this.warnings;
};
BeaLoader.prototype.load = function(fileName) {
var parser, root;
View
60 beautils.js
@@ -1,5 +1,5 @@
(function() {
- var Argument, Type, hasOverload, isNativeType, isSameOverload, parseArg, parseClassDirective, parseDeclaration, tabify, trim, _;
+ var Argument, Type, expandCast, findOverload, fixt, isNativeType, isSameOverload, parseArg, parseClassDirective, parseDeclaration, tabify, trim, _;
_ = require('./lib/underscore');
trim = function(str) {
return str.replace(/^\s+|\s+$/g, '');
@@ -54,9 +54,39 @@
return nt === type;
});
};
+ fixt = function(type) {
+ if (/>$/.test(type)) {
+ return type + ' ';
+ }
+ return type;
+ };
+ expandCast = function(cast, type) {
+ if (cast) {
+ if (cast === 'vector') {
+ cast = 'bea::vector<>';
+ }
+ if (cast === 'string') {
+ cast = 'bea::string';
+ }
+ if (cast === 'external') {
+ cast = 'bea::external<>';
+ }
+ } else {
+ if (type.isConst && type.rawType === 'char' && type.isPointer) {
+ cast = 'bea::string';
+ } else if (type.isPointer && isNativeType(type.rawType)) {
+ cast = 'bea::external<>';
+ }
+ }
+ if (cast && cast.indexOf('<>') !== -1) {
+ cast = cast.replace(/<|>/g, '');
+ cast = "" + cast + "<" + (fixt(type.rawType)) + ">";
+ }
+ return cast;
+ };
Type = (function() {
function Type(org, namespace) {
- var ln, type;
+ var ln, type, _ref;
this.org = org;
this.namespace = namespace;
type = this.org.replace(/^\s*const\s+|\s*volatile\s+/, '');
@@ -65,6 +95,7 @@
this.namespace = type.substring(0, ln);
type = type.substring(ln + 2);
}
+ _ref = type.split(':@'), type = _ref[0], this.cast = _ref[1];
this.type = type;
this.rawType = type.replace(/^\s+|\s+$/g, '').replace(/\s*\&$/, '').replace(/\s*\*$/, '');
this.isPointer = type.match(/\*\s*$/) != null;
@@ -73,6 +104,7 @@
if (this.org.match(/^\s*const\s+/)) {
this.isConst = true;
}
+ this.cast = expandCast(this.cast, this);
}
Type.prototype.fullType = function() {
if (isNativeType(this.rawType)) {
@@ -90,13 +122,17 @@
})();
Argument = (function() {
function Argument(org, ns) {
- var parsed;
+ var cast, parsed, _ref;
this.org = org;
this.ns = ns;
parsed = parseArg(this.org);
- this.name = parsed.name;
+ this.cast = '';
+ _ref = parsed.name.split(':@'), this.name = _ref[0], cast = _ref[1];
this.type = new Type(parsed.type, this.ns);
this.value = parsed.value;
+ if (cast) {
+ this.type.cast = expandCast(cast, this.type);
+ }
}
return Argument;
})();
@@ -148,7 +184,11 @@
ret.push(cur);
return ret;
};
- args = parseArgs(args);
+ if (args !== 'void') {
+ args = parseArgs(args);
+ } else {
+ args = [];
+ }
fnArgs = [];
for (_i = 0, _len = args.length; _i < _len; _i++) {
arg = args[_i];
@@ -173,10 +213,12 @@
});
};
isSameOverload = function(overload1, overload2) {
- return overload1.name === overload2.name && _.isEqual(overload1.args, overload2.args);
+ return overload1.name === overload2.name && overload1.args.length === overload2.args.length && _.all(overload1.args, function(a1, i) {
+ return a1.type.type === overload2.args[i].type.type;
+ });
};
- hasOverload = function(list, overload) {
- return _.any(list, function(over) {
+ findOverload = function(list, overload) {
+ return _.detect(list, function(over) {
return isSameOverload(over, overload);
});
};
@@ -206,7 +248,7 @@
trim: trim,
parseDeclaration: parseDeclaration,
isSameOverload: isSameOverload,
- hasOverload: hasOverload,
+ findOverload: findOverload,
Type: Type,
Argument: Argument,
isNativeType: isNativeType,
View
30 classconvert.js
@@ -166,7 +166,7 @@
return ret;
};
ClassConverter.prototype.processFunNode = function(node) {
- var accType, callNode, fn, fspace, isManual, nodeText, str, _accName;
+ var accType, callNode, existing, fn, fspace, isManual, nodeText, str, _accName;
if (/^\/\//.test(node.text)) {
return false;
}
@@ -254,8 +254,11 @@
fn.sublines = _.without(fn.sublines, callNode);
}
if (this.classFns[fn.name]) {
- if (!beautils.hasOverload(this.classFns[fn.name], fn)) {
+ existing = beautils.findOverload(this.classFns[fn.name], fn);
+ if (!existing) {
this.classFns[fn.name].push(fn);
+ } else {
+ existing.pure = fn.pure;
}
} else {
this.classFns[fn.name] = [fn];
@@ -382,10 +385,11 @@
vfuncdecla = "" + vfunc.type.org + " " + vfunc.name + "(" + (dargs.join(', ')) + ")";
publicd.add(vfuncdecla + ';');
fn = implBlock.add(new CodeBlock.FunctionBlock("" + vfunc.type.org + " " + this.nativeClassName + "::" + vfunc.name + "(" + (dargs.join(', ')) + ")"));
+ fn.add("v8::Locker v8locker;");
fn.add("v8::HandleScope v8scope; v8::Handle<v8::Value> v8retVal;");
cif = fn.add(new CodeBlock.CodeBlock("if (bea_derived_hasOverride(\"" + vfunc.name + "\"))"));
arglist = _.map(vfunc.args, __bind(function(arg) {
- return snippets.ToJS(arg.type.org, arg.name, '');
+ return snippets.ToJS(this.nativeType(arg.type), arg.name, '');
}, this));
if (vfunc.args.length > 0) {
cif.add("v8::Handle<v8::Value> v8args[" + vfunc.args.length + "] = {" + (arglist.join(', ')) + "};");
@@ -472,27 +476,21 @@
};
ClassConverter.prototype.nativeType = function(type) {
var nativeType;
- nativeType = type.fullType();
+ if (type.cast) {
+ nativeType = type.cast;
+ } else {
+ nativeType = type.fullType();
+ }
if (this.typeManager.isWrapped(type)) {
return nativeType + '*';
}
return nativeType;
};
ClassConverter.prototype.convertArg = function(arg, narg) {
- var argType, argv, nativeType, ret;
+ var argType, argv, nativeType;
nativeType = this.nativeType(arg.type);
- if (arg.type.rawType === 'void') {
- this.warn("Type " + (arg.type.fullType()) + " used as argument type.");
- return "";
- }
if (!arg.value) {
- if (0 && arg.type.isPointer && !this.typeManager.isWrapped(arg.type && arg.type.isConst)) {
- ret = snippets.FromJSPointer(nativeType, arg.name, "args[" + narg + "]", narg);
- arg.name = "&v_" + arg.name + "[0]";
- return ret;
- } else {
- return ("" + nativeType + " " + arg.name + " = ") + snippets.FromJS(nativeType, "args[" + narg + "]", narg);
- }
+ return ("" + nativeType + " " + arg.name + " = ") + snippets.FromJS(nativeType, "args[" + narg + "]", narg);
} else {
argv = arg.value;
argType = this.typeManager.typeFromValue(argv);
View
20 snippets.js
@@ -114,9 +114,23 @@
struct.ToJS = struct.add(new CodeBlock.FunctionBlock("static v8::Handle<v8::Value> ToJS(" + (fixt(type)) + " const& v)"));
return struct;
};
- exports.FromJSPointer = function(type, name, v, i) {
+ exports.FromJSCast = function(castName, type, name, v, i) {
var vtype;
- vtype = "std::vector<" + (fixt(type)) + ">";
- return ("" + vtype + " v_" + name + " = ") + exports.FromJS(vtype, v, i);
+ if (castName.indexOf("<>") === -1) {
+ vtype = castName;
+ } else {
+ castName = castName.replace(/<|>/g, '');
+ vtype = "" + castName + "<" + (fixt(type)) + ">";
+ }
+ return ("" + vtype + " " + name + " = ") + exports.FromJS(vtype, v, i);
+ };
+ exports.FromJSCastOptional = function(castName, type, name, v, i, argv) {
+ var vtype;
+ if (castName.indexOf("<") === -1) {
+ vtype = castName;
+ } else {
+ vtype = "" + castName + "<" + (fixt(type)) + ">";
+ }
+ return ("" + vtype + " " + name + " = ") + exports.Optional(vtype, v, i, argv);
};
}).call(this);
View
8 src/bealoader.coffee
@@ -65,9 +65,8 @@ class RecursiveParser
return root
class MessageLogger
- constructor: ->
- @warnings = 0
-
+ @warnings: 0
+
warn: (msg, node) ->
[fileName, line] = [(node?.fileName) ? "", (node?.line) ? 0]
console.log "#{fileName}(#{line}): warning: #{msg}"
@@ -119,6 +118,7 @@ class BeaLoader extends MessageLogger
constants: 0 #number of constants declared
typesConverted: 0 #number of types converted
typesIgnored: 0 #number of types not converted
+ warnings: 0
filenameFromNode: (node) ->
filename = node.text.replace /^@\w+\s*=?\s*/, '' #remove node type
@@ -342,6 +342,8 @@ class BeaLoader extends MessageLogger
return @convertManual()
else
return @convertFull()
+
+ @stats.warnings = @warnings
#catch e
# @error "Exception: " + e
View
69 src/beautils.coffee
@@ -18,6 +18,7 @@ tabify = (str, ntabs) ->
#value - default value or undefined
parseArg = (arg) ->
## char*, const char*, const char *, const char* value, const char * value = NULL
+##the argument name can also contain 'type aliasing', eg. const int* numbers:@vector
ret = {}
arg = trim arg
@@ -65,7 +66,39 @@ isNativeType = (type) ->
nativeTypes = ['void', 'int', 'long', 'bool', 'char', 'double', 'short', 'float', 'size_t']
type = type.replace /^\s*unsigned\s+|\s*signed\s+/, ''
_.any nativeTypes, (nt) -> nt == type
+
+#fix template type, add a space if type ends in >
+fixt = (type) ->
+ if />$/.test type then return type + ' '
+ return type
+
+#adjust the cast string
+#make cast for const char* -> bea::string
+#make cast for const nativeType* -> bea::vector<nativeType>
+
+#cast syntax:
+#int:@vector | int:@string | int:@external | int:@external[indexSizeCode]
+#type:@mytype | type:@mytype<> -> @mytype<type>
+#type:@mytype<>[max] -> @mype<type> made indexable with maxCode length
+expandCast = (cast, type) ->
+
+ if cast
+ cast = 'bea::vector<>' if cast == 'vector'
+ cast = 'bea::string' if cast == 'string'
+ cast = 'bea::external<>' if cast == 'external'
+ else
+ if type.isConst && type.rawType == 'char' && type.isPointer
+ cast = 'bea::string'
+ else if type.isPointer && isNativeType(type.rawType)
+ cast = 'bea::external<>'
+
+ if cast && cast.indexOf('<>') != -1
+ cast = cast.replace /<|>/g, ''
+ cast = "#{cast}<#{fixt type.rawType}>"
+
+ return cast
+#myType:castType
class Type
constructor: (@org, @namespace) ->
type = @org.replace /^\s*const\s+|\s*volatile\s+/, ''
@@ -75,6 +108,7 @@ class Type
@namespace = type.substring 0, ln
type = type.substring ln + 2
+ [type, @cast] = type.split ':@'
#nsType = type without namespace, but with pointer/ref
@type = type
@rawType = type.replace(/^\s+|\s+$/g, '').replace(/\s*\&$/, '').replace(/\s*\*$/, '') #the type without namespaces and decoration
@@ -82,6 +116,9 @@ class Type
@isRef = type.match(/\&\s*$/)?
@isConst = false
if @org.match(/^\s*const\s+/) then @isConst = true
+
+ @cast = expandCast(@cast, this)
+
fullType: ->
if isNativeType(@rawType) then return @org
if @namespace then return @namespace + '::' + @rawType
@@ -91,10 +128,15 @@ class Type
class Argument
constructor: (@org, @ns) ->
parsed = parseArg @org
- @name = parsed.name
+
+ @cast = ''
+ #argument cast:
+ #int* numbers:@vector -> cast argument as vector<int>
+ #unsigned char* buffer:@external -> argument is an external buffer
+ [@name, cast] = parsed.name.split(':@')
@type = new Type parsed.type, @ns
@value = parsed.value
-
+ if cast then @type.cast = expandCast cast, @type
parseDeclaration = (str, namespace) ->
@@ -141,7 +183,11 @@ parseDeclaration = (str, namespace) ->
return ret
- args = parseArgs args
+ #can be declared as void fn(void)
+ if args != 'void'
+ args = parseArgs args
+ else
+ args = []
fnArgs = [];
@@ -161,11 +207,18 @@ parseDeclaration = (str, namespace) ->
_.extend fnDec, {args: fnArgs, virtual: isVirtual, pure: isPure, static: isStatic}
isSameOverload = (overload1, overload2) ->
+ #name should be equal
+ #same number of arguments
+ #same type of arguments
+ #_.isEqual overload1.args, overload2.args
overload1.name == overload2.name &&
- _.isEqual overload1.args, overload2.args
-
-hasOverload = (list, overload) ->
- _.any list, (over) ->
+ overload1.args.length == overload2.args.length &&
+ _.all overload1.args, (a1, i) ->
+ a1.type.type == overload2.args[i].type.type
+
+
+findOverload = (list, overload) ->
+ _.detect list, (over) ->
isSameOverload over, overload
parseClassDirective = (node) ->
@@ -193,7 +246,7 @@ exports.u =
trim: trim
parseDeclaration: parseDeclaration
isSameOverload: isSameOverload
- hasOverload: hasOverload
+ findOverload: findOverload
Type: Type
Argument: Argument
isNativeType: isNativeType
View
32 src/classconvert.coffee
@@ -267,9 +267,11 @@ class ClassConverter
if @classFns[fn.name]
- if not beautils.hasOverload @classFns[fn.name], fn
+ existing = beautils.findOverload @classFns[fn.name], fn
+ if not existing
@classFns[fn.name].push fn
-
+ else
+ existing.pure = fn.pure
else
@classFns[fn.name] = [fn]
@classFns[fn.name].name = fn.name
@@ -400,11 +402,13 @@ class ClassConverter
fn = implBlock.add new CodeBlock.FunctionBlock "#{vfunc.type.org} #{@nativeClassName}::#{vfunc.name}(#{dargs.join ', '})"
+ fn.add "v8::Locker v8locker;"
+ #fn.add "v8::Context::Scope v8ctxScope(bea::Global::context);"
fn.add "v8::HandleScope v8scope; v8::Handle<v8::Value> v8retVal;"
cif = fn.add new CodeBlock.CodeBlock "if (bea_derived_hasOverride(\"#{vfunc.name}\"))"
arglist = _.map vfunc.args, (arg) =>
- snippets.ToJS(arg.type.org, arg.name, '')
+ snippets.ToJS(@nativeType(arg.type), arg.name, '')
if vfunc.args.length > 0
cif.add "v8::Handle<v8::Value> v8args[#{vfunc.args.length}] = {#{arglist.join(', ')}};"
@@ -497,25 +501,22 @@ class ClassConverter
nativeType: (type) ->
#Checks if the type is a 'wrapped' type and returns it as a pointer
#otherwise returns the type properly namespaced, but without pointer/ref
- nativeType = type.fullType()
+
+ if type.cast
+ nativeType = type.cast
+ else
+ nativeType = type.fullType()
+
if @typeManager.isWrapped(type) then return nativeType + '*'
+
nativeType
-
+
#Create conversion code for a function argument
convertArg: (arg, narg) ->
nativeType = @nativeType arg.type
-
- if arg.type.rawType == 'void'
- @warn "Type #{arg.type.fullType()} used as argument type."
- return ""
if not arg.value
- if 0 && arg.type.isPointer && !@typeManager.isWrapped arg.type && arg.type.isConst
- ret = snippets.FromJSPointer nativeType, arg.name, "args[#{narg}]", narg
- arg.name = "&v_" + arg.name + "[0]"
- return ret
- else
- return "#{nativeType} #{arg.name} = " + snippets.FromJS nativeType, "args[#{narg}]", narg
+ return "#{nativeType} #{arg.name} = " + snippets.FromJS nativeType, "args[#{narg}]", narg
else
#value can be:
#someArg = integer
@@ -529,6 +530,7 @@ class ClassConverter
argv = argType.namespace + '::' + argv
if argType.wrapped and not arg.type.isPointer
argv = '&' + argv
+
return "#{nativeType} #{arg.name} = " + snippets.Optional nativeType, narg, argv
#Generates the if clause for a type check used to determine which overload to call
View
22 src/snippets.coffee
@@ -103,6 +103,22 @@ exports.ConvertStruct = (type) ->
struct.ToJS = struct.add new CodeBlock.FunctionBlock "static v8::Handle<v8::Value> ToJS(#{fixt type} const& v)"
return struct
-exports.FromJSPointer = (type, name, v, i) ->
- vtype = "std::vector<#{fixt type}>"
- "#{vtype} v_#{name} = " + exports.FromJS vtype, v, i
+exports.FromJSCast = (castName, type, name, v, i) ->
+ if castName.indexOf("<>") == -1
+ vtype = castName
+ else
+ castName = castName.replace /<|>/g, ''
+ vtype = "#{castName}<#{fixt type}>"
+
+ "#{vtype} #{name} = " + exports.FromJS vtype, v, i
+
+exports.FromJSCastOptional = (castName, type, name, v, i, argv) ->
+ if castName.indexOf("<") == -1
+ vtype = castName
+ else
+ vtype = "#{castName}<#{fixt type}>"
+ "#{vtype} #{name} = " + exports.Optional vtype, v, i, argv
+
+
+
+
Please sign in to comment.
Something went wrong with that request. Please try again.