summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2019-06-20 19:37:06 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2019-08-16 17:04:59 -0300
commit51f374dc491decc897323d5117f801d1eefd8151 (patch)
tree645a3b86c3cde1b57c1de82549d3b64fc9e63fe7
parent3a569e2d11a6463386b8b4709d8382cf7c4a3147 (diff)
testgen: Changes to make csharp generated code compile
-rw-r--r--src/scripts/testgen/ekeys.py33
-rw-r--r--src/scripts/testgen/name_helpers.py60
-rw-r--r--src/scripts/testgen/suitegen.py32
-rwxr-xr-xsrc/scripts/testgen/testgen.py13
-rw-r--r--src/scripts/testgen/testgenerator.cs.template8
5 files changed, 127 insertions, 19 deletions
diff --git a/src/scripts/testgen/ekeys.py b/src/scripts/testgen/ekeys.py
index 035f272000..5006f4ce73 100644
--- a/src/scripts/testgen/ekeys.py
+++ b/src/scripts/testgen/ekeys.py
@@ -2,6 +2,8 @@
2# encoding: utf-8 2# encoding: utf-8
3from enum import IntEnum 3from enum import IntEnum
4 4
5import name_helpers
6
5 7
6class Function_List_Type(IntEnum): 8class Function_List_Type(IntEnum):
7 INHERITIS = 1 9 INHERITIS = 1
@@ -57,23 +59,25 @@ class EMonoKeys(EKeys):
57 "uintptr": "System.IntPtr", 59 "uintptr": "System.IntPtr",
58 "void_ptr": "System.IntPtr", 60 "void_ptr": "System.IntPtr",
59 "void": "System.IntPtr", # only if is out/inout 61 "void": "System.IntPtr", # only if is out/inout
60 "Error": "eina.Error", 62 "Error": "Eina.Error",
61 "string": "System.String", 63 "string": "System.String",
62 "mstring": "System.String", 64 "mstring": "System.String",
63 "stringshare": "System.String", 65 "stringshare": "System.String",
64 "any_value": "eina.Value", 66 "any_value": "Eina.Value",
65 "any_value_ptr": "eina.Value" 67 "any_value_ptr": "Eina.Value"
66 # complex Types 68 # complex Types
67 , 69 ,
68 "list": "eina.List", 70 "list": "Eina.List",
69 "inlist": "eina.Inlist", 71 "inlist": "Eina.Inlist",
70 "array": "eina.Array", 72 "array": "Eina.Array",
71 "inarray": "eina.Inarray", 73 "inarray": "Eina.Inarray",
72 "hash": "eina.Hash", 74 "hash": "Eina.Hash",
73 "promise": "int", 75 "promise": "int",
74 "future": "int", 76 "future": "int",
75 "iterator": "eina.Iterator", 77 "iterator": "Eina.Iterator",
76 "accessor": "int", 78 "accessor": "int",
79 "strbuf": "Eina.Strbuf",
80 "Efl.Class": "System.Type",
77 } 81 }
78 82
79 self.keywords = [ 83 self.keywords = [
@@ -162,10 +166,11 @@ class EMonoKeys(EKeys):
162 "efl_ui_spin_button_loop_get", 166 "efl_ui_spin_button_loop_get",
163 "efl_ui_list_model_size_get", 167 "efl_ui_list_model_size_get",
164 "efl_ui_list_relayout_layout_do", 168 "efl_ui_list_relayout_layout_do",
169 "efl_constructor",
165 ] 170 ]
166 171
167 def escape_keyword(self, key): 172 def escape_keyword(self, key):
168 key = "kw_{}".format(key) if key.lower() in self.keywords else key 173 key = "kw_{}".format(key) if key in self.keywords else key
169 return "{}Add".format(key) if key == "Finalize" else key 174 return "{}Add".format(key) if key == "Finalize" else key
170 175
171 def direction_get(self, direction): 176 def direction_get(self, direction):
@@ -186,12 +191,15 @@ class EMonoKeys(EKeys):
186 if eotype.type == eotype.type.VOID: 191 if eotype.type == eotype.type.VOID:
187 return "System.IntPtr" 192 return "System.IntPtr"
188 193
189 new_type = self.dicttypes.get(eotype.name, self.klass_name(eotype)) 194 new_type = self.dicttypes.get(
195 eotype.name, name_helpers.type_managed_name(eotype)
196 )
190 if new_type != "int" and eotype.base_type: 197 if new_type != "int" and eotype.base_type:
191 new_type = "{}<{}>".format( 198 new_type = "{}<{}>".format(
192 new_type, 199 new_type,
193 self.dicttypes.get( 200 self.dicttypes.get(
194 eotype.base_type.name, self.klass_name(eotype.base_type) 201 eotype.base_type.name,
202 name_helpers.type_managed_name(eotype.base_type),
195 ), 203 ),
196 ) 204 )
197 205
@@ -228,7 +236,6 @@ class EMonoKeys(EKeys):
228 236
229 if func.type == func.type.METHOD: 237 if func.type == func.type.METHOD:
230 fname = self.escape_keyword(fname) 238 fname = self.escape_keyword(fname)
231 fname = "Do{}".format(fname) if fname == func.class_.short_name else fname
232 239
233 return fname 240 return fname
234 241
diff --git a/src/scripts/testgen/name_helpers.py b/src/scripts/testgen/name_helpers.py
new file mode 100644
index 0000000000..f6af8e7ae2
--- /dev/null
+++ b/src/scripts/testgen/name_helpers.py
@@ -0,0 +1,60 @@
1#!/usr/bin/env python3
2# encoding: utf-8
3
4"""Helper module with naming rules for the C# binding."""
5
6import os
7import sys
8
9# Hackish way of detecting pyolian...
10script_path = os.path.dirname(os.path.realpath(__file__))
11
12if "EFL_DIR" in os.environ:
13 root_path = os.environ["EFL_DIR"]
14else:
15 root_path = os.path.abspath(os.path.join(script_path, "..", "..", ".."))
16
17sys.path.insert(0, os.path.join(root_path, "src", "scripts"))
18
19from pyolian import eolian
20
21def remove_underlines(name):
22 """Removes underlines from name"""
23 return name.replace("_", "")
24
25
26def managed_namespaces(namespaces):
27 """Converts an eolian list of namespaces into the managed namespace"""
28 return ".".join(remove_underlines(nsp) for nsp in namespaces)
29
30
31def class_managed_name(cls):
32 """Gets the full managed name of the given eolian class"""
33 ret = managed_namespaces(cls.namespaces)
34
35 if ret:
36 ret += "."
37
38 if cls.type in (eolian.Eolian_Class_Type.INTERFACE, eolian.Eolian_Class_Type.MIXIN):
39 ret += "I"
40
41 ret += remove_underlines(cls.short_name)
42
43 if ret == 'Efl.Class':
44 return 'System.Type'
45
46 return ret
47
48def type_managed_name(type):
49 """Gets the full managed name of a given type."""
50 if type.type == eolian.Eolian_Type_Type.CLASS:
51 return class_managed_name(type.class_)
52
53 ret = managed_namespaces(type.namespaces)
54
55 if ret:
56 ret += "."
57
58 ret += remove_underlines(type.short_name)
59
60 return ret
diff --git a/src/scripts/testgen/suitegen.py b/src/scripts/testgen/suitegen.py
index 426fc28074..43ded950e4 100644
--- a/src/scripts/testgen/suitegen.py
+++ b/src/scripts/testgen/suitegen.py
@@ -2,6 +2,9 @@ import itertools
2import os 2import os
3from pyolian.eolian import Eolian_Function_Type, Eolian_Class_Type 3from pyolian.eolian import Eolian_Function_Type, Eolian_Class_Type
4from .ekeys import GetKey, Function_List_Type 4from .ekeys import GetKey, Function_List_Type
5from pyolian import eolian
6
7import name_helpers
5 8
6 9
7class BaseItem: 10class BaseItem:
@@ -175,8 +178,37 @@ class SuiteGen(BaseItem):
175 return iter(self.clslist) 178 return iter(self.clslist)
176 179
177 def type_convert(self, eotype): 180 def type_convert(self, eotype):
181 if eotype.type == eolian.Eolian_Type_Type.CLASS:
182 return name_helpers.class_managed_name(eotype.class_)
183
184 if eotype.typedecl:
185 return name_helpers.type_managed_name(eotype)
186
178 return self.keys.type_convert(eotype) 187 return self.keys.type_convert(eotype)
179 188
189 def constructor_params(self, cls):
190 ret = []
191
192 constructors = itertools.chain(
193 cls.constructors, *[base.constructors for base in cls.inherits_full]
194 )
195
196 for constructor in constructors:
197 # Skip optional constructors for now
198 if constructor.is_optional:
199 continue
200 func = constructor.function
201
202 if func.type == eolian.Eolian_Function_Type.PROPERTY:
203 first_param = list(func.setter_values)[0]
204 else:
205 first_param = list(func.parameters)[0]
206 param_type = first_param.type
207
208 ret.append("default({})".format(name_helpers.type_managed_name(param_type)))
209
210 return (", " if ret else "") + ", ".join(ret)
211
180 def print_arg(self, eoarg): 212 def print_arg(self, eoarg):
181 return self.keys.print_arg(eoarg) 213 return self.keys.print_arg(eoarg)
182 214
diff --git a/src/scripts/testgen/testgen.py b/src/scripts/testgen/testgen.py
index b91d7b7e81..8ab537beb6 100755
--- a/src/scripts/testgen/testgen.py
+++ b/src/scripts/testgen/testgen.py
@@ -5,6 +5,8 @@ import os
5import sys 5import sys
6import datetime 6import datetime
7 7
8import name_helpers
9
8script_path = os.path.dirname(os.path.realpath(__file__)) 10script_path = os.path.dirname(os.path.realpath(__file__))
9 11
10if "EFL_DIR" in os.environ: 12if "EFL_DIR" in os.environ:
@@ -48,6 +50,7 @@ def cleanup_db():
48 50
49atexit.register(cleanup_db) 51atexit.register(cleanup_db)
50 52
53
51class Template(pyratemp.Template): 54class Template(pyratemp.Template):
52 def __init__( 55 def __init__(
53 self, 56 self,
@@ -84,6 +87,7 @@ class Template(pyratemp.Template):
84 # Build the context for the template 87 # Build the context for the template
85 ctx = {} 88 ctx = {}
86 ctx["suite"] = suite 89 ctx["suite"] = suite
90 ctx["name_helpers"] = name_helpers
87 # render with the augmented context 91 # render with the augmented context
88 output = self(**ctx) 92 output = self(**ctx)
89 93
@@ -97,8 +101,13 @@ if __name__ == "__main__":
97 import argparse 101 import argparse
98 102
99 parser = argparse.ArgumentParser(description="Eolian Test Generator.") 103 parser = argparse.ArgumentParser(description="Eolian Test Generator.")
100 parser.add_argument("testname", help="The Test Name used to find custom and template files. (REQUIRED)") 104 parser.add_argument(
101 parser.add_argument("suitename", help="The Suite Name used to find custom files. (REQUIRED)") 105 "testname",
106 help="The Test Name used to find custom and template files. (REQUIRED)",
107 )
108 parser.add_argument(
109 "suitename", help="The Suite Name used to find custom files. (REQUIRED)"
110 )
102 parser.add_argument("filename", help="Generated test file destination. (REQUIRED)") 111 parser.add_argument("filename", help="Generated test file destination. (REQUIRED)")
103 parser.add_argument("eofiles", nargs="*", help="The Eolian Files to use.") 112 parser.add_argument("eofiles", nargs="*", help="The Eolian Files to use.")
104 113
diff --git a/src/scripts/testgen/testgenerator.cs.template b/src/scripts/testgen/testgenerator.cs.template
index 59e38f124c..c2085e838d 100644
--- a/src/scripts/testgen/testgenerator.cs.template
+++ b/src/scripts/testgen/testgenerator.cs.template
@@ -3,7 +3,7 @@
3${mshow}$#! 3${mshow}$#!
4 <!--(end)--> 4 <!--(end)-->
5<!--(end)--> 5<!--(end)-->
6<!--(macro def_obj)-->${'.'.join(param.type.namespaces)}$.I${param.type.short_name}$ arg_${param.name}$ = null;<!--(end)--> 6<!--(macro def_obj)-->${name_helpers.class_managed_name(param.type.class_)}$ arg_${param.name}$ = null;<!--(end)-->
7<!--(macro def_param)--> 7<!--(macro def_param)-->
8 <!--(if param.type.type == param.type.type.CLASS)-->${def_obj(param=param)}$<!--(else)-->${suite.type_convert(param.type)}$ arg_${param.name}$ = default(${suite.type_convert(param.type)}$);<!--(end)--> 8 <!--(if param.type.type == param.type.type.CLASS)-->${def_obj(param=param)}$<!--(else)-->${suite.type_convert(param.type)}$ arg_${param.name}$ = default(${suite.type_convert(param.type)}$);<!--(end)-->
9<!--(end)--> 9<!--(end)-->
@@ -13,7 +13,7 @@ ${mshow}$#!
13 <!--(end)--> 13 <!--(end)-->
14<!--(end)--> 14<!--(end)-->
15<!--(macro meth_target)--> 15<!--(macro meth_target)-->
16 <!--(if func.is_class)-->${'.'.join(cls.namespaces)}$.${cls.short_name}$<!--(else)-->obj<!--(end)--> 16 <!--(if func.is_class)-->${name_helpers.class_managed_name(cls)}$<!--(else)-->obj<!--(end)-->
17<!--(end)--> 17<!--(end)-->
18using System; 18using System;
19 19
@@ -25,7 +25,7 @@ namespace TestSuite
25class Test${cls.name.replace('.','')}$ 25class Test${cls.name.replace('.','')}$
26{ 26{
27 27
28 ${'.'.join(cls.namespaces)}$.I${cls.short_name}$ obj; 28 ${name_helpers.class_managed_name(cls)}$ obj;
29${m_show(mshow=cls.custom)}$#! 29${m_show(mshow=cls.custom)}$#!
30 30
31 public void SetUp() 31 public void SetUp()
@@ -34,7 +34,7 @@ ${m_show(mshow=suite.init)}$#!
34 <!--(if cls.init)--> 34 <!--(if cls.init)-->
35${cls.init}$ 35${cls.init}$
36 <!--(else)--> 36 <!--(else)-->
37 obj = new ${'.'.join(cls.namespaces)}$.${cls.short_name}$(); 37 obj = new ${name_helpers.class_managed_name(cls)}$(null${suite.constructor_params(cls)}$);
38 <!--(end)--> 38 <!--(end)-->
39 } 39 }
40 40