def visitAttribute(self, node): ti = jnutils.GetTypeInformation(node.attrType().unalias()) for n in node.declarators(): self.writeMethod( jnutils.CppName(n.identifier()), jnutils.JavaMangleName(jnutils.AccessorName(n, 0)), ti, []) if not node.readonly(): for n in node.declarators(): self.writeMethod( jnutils.CppName(n.identifier()), jnutils.JavaMangleName(jnutils.AccessorName(n, 1)), None, [['param', ti, jnutils.Type.IN]])
def visitAttribute(self, node): ti = jnutils.GetTypeInformation(node.attrType().unalias()) for n in node.declarators(): self.pushManglePart(jnutils.AccessorName(n, 0)) self.calculateMangled() self.writeMethod(self.mangled, jnutils.CppName(n.identifier()), ti, [], []) self.popManglePart() if not node.readonly(): itype = ti.jniType(jnutils.Type.IN) for n in node.declarators(): self.pushManglePart(jnutils.AccessorName(n, 1)) self.calculateMangled() self.writeMethod(self.mangled, jnutils.CppName(n.identifier()), None, [['param', ti, jnutils.Type.IN]], []) self.popManglePart()
def visitOperation(self, node): rti = jnutils.GetTypeInformation(node.returnType().unalias()) params = [] for p in node.parameters(): dirn = [jnutils.Type.IN, jnutils.Type.OUT, jnutils.Type.INOUT][p.direction()] pti = jnutils.GetTypeInformation(p.paramType().unalias()) params.append([p.identifier(), pti, dirn]) self.writeMethod(jnutils.CppName(node.identifier()), jnutils.JavaMangleName(node.identifier()), rti, params)
def visitOperation(self, node): rti = jnutils.GetTypeInformation(node.returnType().unalias()) params = [] for p in node.parameters(): dirn = [jnutils.Type.IN, jnutils.Type.OUT, jnutils.Type.INOUT][p.direction()] pti = jnutils.GetTypeInformation(p.paramType().unalias()) params.append([p.identifier(), pti, dirn]) self.pushManglePart(node.identifier()) self.calculateMangled() self.writeMethod(self.mangled, jnutils.CppName(node.identifier()), rti, params, node.raises()) self.popManglePart()
def writeMethod(self, name, pcmName, rtype, params, excepts): if rtype == None: rtypeName = 'void' else: rtypeName = rtype.jniType(jnutils.Type.RETURN) paramString = 'JNIEnv* env, jobject thisptr' for (pname, ti, dirn) in params: tiName = ti.jniType(dirn) paramString = paramString + ', ' + tiName + ' ' + pname self.hxx.out('extern "C" { PUBLIC_JAVAMOD_PRE ' + rtypeName + ' ' + name + '(' + paramString + ') PUBLIC_JAVAMOD_POST; };') self.cppMod.out(rtypeName + ' ' + name + '(' + paramString + ')') self.cppMod.out('{') self.cppMod.inc_indent() if (rtype != None and rtypeName != 'void'): needRet = 1 self.cppMod.out(rtype.pcmType(jnutils.Type.DERIVE) + ' _pcm_ret;') else: needRet = 0 pcmParams = '' for (pname, ti, dirn) in params: # We need to convert in parameters to the CXX type... indirect = '' if dirn != jnutils.Type.IN: indirect = ti.cref if pcmParams != '': pcmParams = pcmParams + ', ' self.cppMod.out( ti.pcmType(jnutils.Type.DERIVE) + ' _pcm_' + pname + ';') pcmParams = pcmParams + indirect + '_pcm_' + pname if dirn == jnutils.Type.OUT: continue self.cppMod.out( ti.convertToPCM(pname, '_pcm_' + pname, dirn != jnutils.Type.IN)) # Next, we need to extract the 'this' pointer... self.cppMod.out(self.cxxclass + '* pcm_this;') self.cppMod.out('{') self.cppMod.inc_indent() self.cppMod.out('jclass thisclazz = env->GetObjectClass(thisptr);') self.cppMod.out( 'jfieldID fid = env->GetFieldID(thisclazz, "nativePtr", "J");') self.cppMod.out('pcm_this = reinterpret_cast<' + self.cxxclass + '*>(env->GetLongField(thisptr, fid));') self.cppMod.dec_indent() self.cppMod.out('}') # Make the call to the PCM interface... if needRet: retsave = '_pcm_ret = ' else: retsave = '' self.cppMod.out('try') self.cppMod.out('{') self.cppMod.inc_indent() self.cppMod.out(retsave + 'pcm_this->' + pcmName + '(' + pcmParams + ');') self.cppMod.dec_indent() self.cppMod.out('}') for e in excepts: self.cppMod.out('catch (%s& _except)' % ('iface::' + jnutils.ScopedCppName(e))) self.cppMod.out('{') self.cppMod.inc_indent() # Clean up parameters... for (pname, ti, dirn) in params: self.cppMod.out(ti.pcmDestroy('_pcm_' + pname)) sigArgs = '' invokeArgs = '' for mem in e.members(): ti = jnutils.GetTypeInformation(mem.memberType()) for d in mem.declarators(): jniName = '_ejni_' + d.identifier() self.cppMod.out('%s %s;' % (ti.jniType(jnutils.Type.IN), jniName)) self.cppMod.out( ti.convertToJNI( jniName, '_except.%s' % (jnutils.CppName(d.identifier())))) sigArgs = sigArgs + ti.javaSig(jnutils.Type.IN) invokeArgs = invokeArgs + ',' + jniName self.cppMod.out('jclass eclazz = env->FindClass("%s");' % string.join(e.scopedName(), '/')) self.cppMod.out( 'jmethodID meth = env->GetMethodID(eclazz, "<init>", "(%s)V");' % sigArgs) self.cppMod.out('jobject eobj = env->NewObject(eclazz, meth%s);' % invokeArgs) self.cppMod.out('env->Throw((jthrowable)eobj);') if needRet: self.cppMod.out('return ' + rtype.failure_return + ';') else: self.cppMod.out('return;') self.cppMod.dec_indent() self.cppMod.out('}') self.cppMod.out('catch (...)') self.cppMod.out('{') self.cppMod.inc_indent() # Clean up parameters... for (pname, ti, dirn) in params: self.cppMod.out(ti.pcmDestroy('_pcm_' + pname)) # Raise an exception... self.cppMod.out( 'jclass eclazz = env->FindClass("java/lang/RuntimeException");') self.cppMod.out( 'env->ThrowNew(eclazz, "Native code threw exception");') if needRet: self.cppMod.out('return ' + rtype.failure_return + ';') else: self.cppMod.out('return;') self.cppMod.dec_indent() self.cppMod.out('}') # Convert out / inout parameters to JNI... for (pname, ti, dirn) in params: if dirn == jnutils.Type.IN: continue self.cppMod.out( ti.convertToJNI(pname, '_pcm_' + pname, indirectOut=1)) if needRet: self.cppMod.out(rtypeName + ' _jni_ret;') self.cppMod.out(rtype.convertToJNI('_jni_ret', '_pcm_ret')) # Clean up parameters... for (pname, ti, dirn) in params: self.cppMod.out(ti.pcmDestroy('_pcm_' + pname)) if needRet: self.cppMod.out(rtype.pcmDestroy('_pcm_ret')) self.cppMod.out('return _jni_ret;') self.cppMod.dec_indent() self.cppMod.out('}')
def visitInterface(self, node): # If it doesn't have the user-callback pragma, don't bother generating... hasCallback = 0 for p in node.pragmas(): hasCallback = hasCallback or (p.text() == "user-callback") if hasCallback == 0: return self.syncNamespaces() self.hxx.out( 'PUBLIC_%s_PRE class PUBLIC_%s_POST %s' % (self.defname, self.defname, jnutils.CppName(node.identifier()))) isTerminal = 0 # See if this is a terminal interface... for p in node.pragmas(): if p.text() == "terminal-interface": isTerminal = 1 virtual = '' if not isTerminal: virtual = 'virtual ' inh = filter(lambda x: x.repoId() != REPOID_ISUPPORTS, node.inherits()) scopedname = jnutils.ScopedCppName(node) classname = 'p2j::' + scopedname self.classname = classname self.javaclass = string.join(node.scopedName(), '/') self.hxx.out(' : public @virtual@::iface::@scopedname@', virtual=virtual, scopedname=scopedname) if len(inh) == 0: self.hxx.out(' , public @virtual@::p2j::XPCOM::IObject', virtual=virtual) else: for c in inh: if isinstance(c, idlast.Declarator) and c.alias(): c = c.alias().aliasType().unalias().decl() isAmbiguous = 0 iclassname = jnutils.ScopedCppName(c) target = 'ambiguous-inheritance(' + iclassname + ')' for p in node.pragmas(): if p.text() == target: isAmbiguous = 1 break if isAmbiguous: virtual = 'virtual ' else: virtual = '' self.hxx.out(' , public @virtual@::p2j::@classname@', virtual=virtual, classname=iclassname) self.hxx.out('{') self.hxx.out('public:') self.hxx.inc_indent() self.hxx.out(jnutils.CppName(node.identifier()) + '() {}') self.hxx.out('PUBLIC_@defname@_PRE @classname@(JNIEnv* aEnv, ' + 'jobject aObject) PUBLIC_@defname@_POST;', classname=jnutils.CppName(node.identifier()), defname=self.defname) self.cpp.out( classname + '::' + jnutils.CppName(node.identifier()) + '(JNIEnv* aEnv, jobject aObject) : ::p2j::XPCOM::IObject(aEnv, aObject)' ) self.cpp.out('{') self.cpp.out('}') for n in node.contents(): n.accept(self) self.hxx.dec_indent() self.hxx.out('};') fname = jnutils.CppName(string.join(node.scopedName(), '_')) + 'Factory' self.cpp.out('class ' + fname) self.cpp.out(' : public P2JFactory') self.cpp.out('{') self.cpp.out('public:') self.cpp.inc_indent() self.cpp.out(fname + '() : ::P2JFactory("' +\ scopedname + '", "' + self.javaclass +\ '") {}') self.cpp.out('void* create(JNIEnv* env, jobject obj) { return reinterpret_cast<void*>(' +\ 'static_cast< ::iface::' + scopedname + '*>(new ' +\ classname + '(env, obj))); }') self.cpp.dec_indent() self.cpp.out('};') self.cpp.out(fname + ' s' + fname + ';')
def visitForward(self, node): self.syncNamespaces() self.hxx.out('class ' + jnutils.CppName(node.identifier()) + ';')