Make godotapigen use getter return type for property types

Fixes #20.
This commit is contained in:
Ruslan Mustakov 2018-04-24 11:12:49 +07:00
commit 6e014bbc01
2 changed files with 66 additions and 56 deletions

View file

@ -1,4 +1,4 @@
version = "0.7.8" version = "0.7.9"
author = "Xored Software, Inc." author = "Xored Software, Inc."
description = "Godot Engine bindings" description = "Godot Engine bindings"
license = "MIT" license = "MIT"

View file

@ -659,15 +659,73 @@ proc generateMethod(tree: PNode, methodBindRegistry: var HashSet[string],
meth: MethodInfo, withImplementation: bool) = meth: MethodInfo, withImplementation: bool) =
doGenerateMethod(tree, methodBindRegistry, meth, withImplementation) doGenerateMethod(tree, methodBindRegistry, meth, withImplementation)
proc getMethodInfo(methodObj: JsonNode, types: Table[string, GodotType],
typ: GodotType): MethodInfo =
var origArgs = methodObj["arguments"]
var isBase = methodObj["is_virtual"].bval
if methodObj["is_virtual"].bval:
proc getMethod(typNode: JsonNode, methName: string): JsonNode =
for meth in typNode["methods"]:
if meth["is_virtual"].bval and
meth["name"].str == methName: return meth
var curTyp = types.getOrDefault(typ.baseName)
while not curTyp.isNil:
let meth = curTyp.jsonNode.getMethod(methodObj["name"].str)
if not meth.isNil:
origArgs = meth["arguments"]
isBase = false
curTyp = types.getOrDefault(curTyp.baseName)
var args = newSeqOfCap[MethodArg](methodObj["arguments"].len + 1)
for arg in origArgs:
let typ = toNimType(types, arg["type"].str)
let defaultVal = if arg["has_default_value"].bval: arg["default_value"]
else: nil
args.add(MethodArg(
name: toNimStyle(arg["name"].str), typ: typ,
defaultVal: defaultVal))
if methodObj["has_varargs"].bval:
args.add(MethodArg(name: "variantArgs", typ: "Variant", kind: ArgKind.VarArgs))
let godotName = methodObj["name"].str
var nimName = toNimStyle(godotName)
if not godotName.startsWith('_'):
for meth in typ.jsonNode["methods"]:
if meth["name"].str == '_' & godotName:
nimName = nimName & "Impl"
let returnType = if methodObj["return_type"].str != "void":
toNimType(types, methodObj["return_type"].str)
else: nil
const discardableMethods = toSet(["emit_signal"])
result = MethodInfo(
name: ident(nimName),
typ: typ,
godotName: methodObj["name"].str,
args: args,
returnType: returnType,
isVirtual: methodObj["is_virtual"].bval,
isBase: isBase,
isDiscardable: typ.godotName == "Object" and
methodObj["name"].str in discardableMethods
)
proc findMethod(obj: JsonNode, methName: string): JsonNode =
for meth in obj["methods"]:
if meth["name"].str == methName:
return meth
proc makeProperty(types: Table[string, GodotType], tree: PNode, proc makeProperty(types: Table[string, GodotType], tree: PNode,
methodBindRegistry: var HashSet[string], methodBindRegistry: var HashSet[string],
typ: GodotType, typ: GodotType, propertyObj: JsonNode, obj: JsonNode,
propertyObj: JsonNode, withImplementation: bool) = withImplementation: bool) =
let getterNameStr = toNimStyle(propertyObj["name"].str) let getterNameStr = toNimStyle(propertyObj["name"].str)
let getterName = ident(toNimStyle(propertyObj["name"].str)) let getterName = ident(getterNameStr)
let setterName = newNode(nkAccQuoted).addChain(ident(getterNameStr & "=")) let setterName = newNode(nkAccQuoted).addChain(ident(getterNameStr & "="))
let nimType = toNimType(types, propertyObj["type"].str) let getter = findMethod(obj, propertyObj["getter"].str)
let nimType = if getter.isNil: toNimType(types, propertyObj["type"].str)
else: getMethodInfo(getter, types, typ).returnType
let getterInfo = MethodInfo( let getterInfo = MethodInfo(
name: getterName, name: getterName,
typ: typ, typ: typ,
@ -693,10 +751,6 @@ proc makeMethod(types: Table[string, GodotType], tree: PNode,
methodBindRegistry: var HashSet[string], methodBindRegistry: var HashSet[string],
typ: GodotType, methodObj: JsonNode, typ: GodotType, methodObj: JsonNode,
withImplementation: bool) = withImplementation: bool) =
let returnType = if methodObj["return_type"].str != "void":
toNimType(types, methodObj["return_type"].str)
else: nil
if not typ.isSingleton: if not typ.isSingleton:
# for singletons we don't generate Nim setters/getters, # for singletons we don't generate Nim setters/getters,
# but use plain procedures instead. That's because setter syntax is # but use plain procedures instead. That's because setter syntax is
@ -706,51 +760,7 @@ proc makeMethod(types: Table[string, GodotType], tree: PNode,
prop["setter"].str == methodObj["name"].str: prop["setter"].str == methodObj["name"].str:
return return
var args = newSeqOfCap[MethodArg](methodObj["arguments"].len + 1) let methodInfo = getMethodInfo(methodObj, types, typ)
var origArgs = methodObj["arguments"]
var isBase = methodObj["is_virtual"].bval
if methodObj["is_virtual"].bval:
proc getMethod(typNode: JsonNode, methName: string): JsonNode =
for meth in typNode["methods"]:
if meth["is_virtual"].bval and
meth["name"].str == methName: return meth
var curTyp = types.getOrDefault(typ.baseName)
while not curTyp.isNil:
let meth = curTyp.jsonNode.getMethod(methodObj["name"].str)
if not meth.isNil:
origArgs = meth["arguments"]
isBase = false
curTyp = types.getOrDefault(curTyp.baseName)
for arg in origArgs:
let typ = toNimType(types, arg["type"].str)
let defaultVal = if arg["has_default_value"].bval: arg["default_value"]
else: nil
args.add(MethodArg(
name: toNimStyle(arg["name"].str), typ: typ,
defaultVal: defaultVal))
if methodObj["has_varargs"].bval:
args.add(MethodArg(name: "variantArgs", typ: "Variant", kind: ArgKind.VarArgs))
let godotName = methodObj["name"].str
var nimName = toNimStyle(godotName)
if not godotName.startsWith('_'):
for meth in typ.jsonNode["methods"]:
if meth["name"].str == '_' & godotName:
nimName = nimName & "Impl"
const discardableMethods = toSet(["emit_signal"])
let methodInfo = MethodInfo(
name: ident(nimName),
typ: typ,
godotName: methodObj["name"].str,
args: args,
returnType: returnType,
isVirtual: methodObj["is_virtual"].bval,
isBase: isBase,
isDiscardable: typ.godotName == "Object" and
methodObj["name"].str in discardableMethods
)
generateMethod(tree, methodBindRegistry, methodInfo, withImplementation) generateMethod(tree, methodBindRegistry, methodInfo, withImplementation)
@ -931,7 +941,7 @@ proc genApi*(targetDir: string, apiJsonFile: string) =
if not typ.isSingleton: if not typ.isSingleton:
for property in obj["properties"]: for property in obj["properties"]:
makeProperty(types, tree, methodBindRegsitry, typ, property, makeProperty(types, tree, methodBindRegsitry, typ, property,
withImplementation = false) obj, withImplementation = false)
for meth in obj["methods"]: for meth in obj["methods"]:
makeMethod(types, tree, methodBindRegsitry, typ, makeMethod(types, tree, methodBindRegsitry, typ,
meth, withImplementation = false) meth, withImplementation = false)
@ -939,7 +949,7 @@ proc genApi*(targetDir: string, apiJsonFile: string) =
if not typ.isSingleton: if not typ.isSingleton:
for property in obj["properties"]: for property in obj["properties"]:
makeProperty(types, tree, methodBindRegsitry, typ, makeProperty(types, tree, methodBindRegsitry, typ,
property, withImplementation = true) property, obj, withImplementation = true)
for meth in obj["methods"]: for meth in obj["methods"]:
makeMethod(types, tree, methodBindRegsitry, typ, meth, makeMethod(types, tree, methodBindRegsitry, typ, meth,
withImplementation = true) withImplementation = true)