[beast: 10/70] V8BSE: generate classes with properties into V8stub



commit e99dff619fb9bf24507f165bf4bcda50bce53c3c
Author: Tim Janik <timj gnu org>
Date:   Sat Feb 18 00:27:25 2017 +0100

    V8BSE: generate classes with properties into V8stub
    
    Signed-off-by: Tim Janik <timj gnu org>

 ebeast/v8bse/V8Stub.py |  100 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 100 insertions(+), 0 deletions(-)
---
diff --git a/ebeast/v8bse/V8Stub.py b/ebeast/v8bse/V8Stub.py
index 505a2a1..567c664 100644
--- a/ebeast/v8bse/V8Stub.py
+++ b/ebeast/v8bse/V8Stub.py
@@ -5,6 +5,32 @@ More details at http://www.rapicorn.org/
 """
 import Decls, re, sys, os
 
+# == Utilities ==
+def type_namespace_names (tp):
+  namespaces = tp.list_namespaces() # [ Namespace... ]
+  return [d.name for d in namespaces if d.name]
+def underscore_namespace (tp):
+  return '__'.join (type_namespace_names (tp))
+def colon_namespace (tp):
+  return '::'.join (type_namespace_names (tp))
+def identifier_name (joiner, type_name, member = None):
+  parts = type_namespace_names (type_name) + [ type_name.name ]
+  if member: parts += [ member ]
+  return joiner.join (parts)
+def underscore_typename (tp):
+  if tp.storage == Decls.ANY:
+    return 'Rapicorn__Any'
+  return identifier_name ('__', tp)
+def colon_typename (tp):
+  name = identifier_name ('::', tp)
+  if tp.storage == Decls.INTERFACE:
+    name += 'H' # e.g. WidgetHandle
+  return name
+def v8ppclass_type (tp):
+  return 'V8ppType_' + identifier_name ('', tp)
+def v8ppclass (tp):
+  return identifier_name ('', tp) + '_class_'
+
 class Generator:
   def __init__ (self, idl_file, module_name):
     assert isinstance (module_name, str)
@@ -16,6 +42,80 @@ class Generator:
     self.marshallers = {}
   def generate_types_v8 (self, implementation_types):
     s  = '// === Generated by V8Stub.py ===            -*-mode:javascript;-*-\n'
+    # includes
+    s += '#include "v8pp/context.hpp"\n'
+    s += '#include "v8pp/module.hpp"\n'
+    s += '#include "v8pp/class.hpp"\n'
+    # collect impl types
+    namespaces = []
+    types = []
+    for tp in implementation_types:
+      if tp.isimpl:
+        types += [ tp ]
+        namespaces.append (tp.list_namespaces())
+    if not types:
+      return s
+    # check unique namespace
+    while len (namespaces) >= 2 and namespaces[0] == namespaces[1]:
+      namespaces = namespaces[1:]
+    namespaces = [[n for n in names if n.name] for names in namespaces] # strip (initial) empty names
+    max_namespaces = max (len (namespaces), len (namespaces[0]))
+    if max_namespaces != 1:
+      raise NotImplementedError ('V8 code generation requires exactly 1 namespace (%d given)' % 
max_namespaces)
+    self.namespace = namespaces[0][0].name
+    del namespaces, max_namespaces
+    # Collect v8pp::class_ types
+    v8pp_class_types = []
+    for tp in types:
+      if tp.is_forward:
+        continue
+      if tp.storage in (Decls.SEQUENCE, Decls.RECORD, Decls.INTERFACE):
+        v8pp_class_types += [ tp ]
+    # C++ Classes
+    s += '\n// C++ Classes\n'
+    for tp in v8pp_class_types:
+      s += 'typedef %-40s %s;\n' % ('v8pp::class_<%s>' % colon_typename (tp), v8ppclass_type (tp))
+    # V8stub - main binding stub
+    s += '\n// Main binding stub\n'
+    s += 'struct V8stub final {\n'
+    s += '  v8::Isolate                             *const isolate_;\n'
+    for tp in v8pp_class_types:
+      s += '  %-40s %s;\n' % (v8ppclass_type (tp), v8ppclass (tp))
+    s += '  v8pp::module                             module_;\n'
+    s += 'public:\n'
+    s += '  V8stub (v8::Isolate *const isolate);\n'
+    s += '};\n'
+    # V8stub ctor - begin
+    s += '\nV8stub::V8stub (v8::Isolate *const isolate) :\n'
+    s += '  isolate_ (isolate),\n'
+    for tp in v8pp_class_types:
+      s += '  %s (isolate),\n' % v8ppclass (tp)
+    s += '  module_ (isolate)\n'
+    s += '{\n'
+    # Class bindings
+    for tp in v8pp_class_types:
+      b = ''
+      cn = colon_typename (tp)
+      # Class ctor
+      if tp.storage == Decls.SEQUENCE or tp.storage == Decls.RECORD:
+        b += '    .ctor()\n'
+      # Class properties
+      if tp.storage != Decls.SEQUENCE:
+        for fname, ftp in tp.fields:
+          if tp.storage == Decls.INTERFACE:
+            b += '    .set ("%s", ' % fname
+            b += 'v8pp::property (&%s::%s, &%s::%s))\n' % (cn, fname, cn, fname)
+          elif tp.storage == Decls.RECORD:
+            b += '    .set ("%s", &%s::%s)\n' % (fname, cn, fname)
+      if b:
+        s += '  %s\n' % v8ppclass (tp)
+        s += b
+        s += '  ;\n'
+    # Class registration
+    for tp in v8pp_class_types:
+      s += '  module_.set ("%s", %s);\n' % (tp.name, v8ppclass (tp))
+    # V8stub ctor - end
+    s += '}\n'
     return s
 
 def generate (namespace_list, **args):


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]