/** Determines if the exported method can be used as-is. */ private static boolean isIdentityFunction(FragmentGeneratorContext context, JMethod m) throws UnableToCompleteException { TreeLogger logger = context.parentLogger.branch( TreeLogger.DEBUG, "Determining identity status of " + m.getName(), null); FragmentGeneratorOracle fgo = context.fragmentGeneratorOracle; boolean identityOnly = m.isStatic(); JParameter[] parameters = m.getParameters(); identityOnly &= context .fragmentGeneratorOracle .findFragmentGenerator(logger, context.typeOracle, m.getReturnType()) .isIdentity(); for (int i = 0; i < parameters.length && identityOnly; i++) { FragmentGenerator fragmentGenerator = fgo.findFragmentGenerator(logger, context.typeOracle, parameters[i].getType()); identityOnly &= fragmentGenerator.isIdentity(); } return identityOnly; }
/** Writes a linkage function object that will invoke the exported function. */ private static void writeLinkageInvocation(FragmentGeneratorContext context, JMethod m) throws UnableToCompleteException { TreeLogger logger = context.parentLogger.branch( TreeLogger.DEBUG, "Writing function() for " + m.getName(), null); SourceWriter sw = context.sw; JParameter[] parameters = m.getParameters(); FragmentGeneratorOracle fgo = context.fragmentGeneratorOracle; FragmentGenerator returnFragmentGenerator = fgo.findFragmentGenerator(logger, context.typeOracle, m.getReturnType()); sw.print("function("); for (int i = 0; i < parameters.length; i++) { sw.print("arg"); sw.print(String.valueOf(i)); if (i < parameters.length - 1) { sw.print(", "); } } sw.println(") {"); sw.indent(); if (returnFragmentGenerator.isIdentity()) { sw.print("return "); } else { sw.print("var javaReturn = "); } // Don't need to reference the instance on a static method if (!m.isStatic()) { sw.print(context.parameterName); sw.print("."); } sw.print("@"); sw.print(m.getEnclosingType().getQualifiedSourceName()); sw.print("::"); sw.print(m.getName()); sw.print("("); // Argument list for the Java invocation for (int i = 0; i < parameters.length; i++) { sw.print(parameters[i].getType().getJNISignature()); } sw.println(")("); // Indent the parameters, each on its own like to improve readability sw.indent(); sw.indent(); for (int i = 0; i < parameters.length; i++) { // Create a sub-context to generate the wrap/unwrap logic JType returnType = parameters[i].getType(); FragmentGeneratorContext subParams = new FragmentGeneratorContext(context); subParams.returnType = returnType; subParams.parameterName = "arg" + i; FragmentGenerator fragmentGenerator = fgo.findFragmentGenerator(logger, context.typeOracle, returnType); if (fragmentGenerator == null) { logger.log( TreeLogger.ERROR, "No fragment generator for " + returnType.getQualifiedSourceName(), null); throw new UnableToCompleteException(); } fragmentGenerator.fromJS(subParams); if (i < parameters.length - 1) { sw.println(", "); } } sw.outdent(); sw.outdent(); sw.println(");"); if (!returnFragmentGenerator.isIdentity()) { FragmentGeneratorContext returnContext = new FragmentGeneratorContext(context); returnContext.parameterName = "javaReturn"; returnContext.returnType = m.getReturnType(); sw.print("return "); returnFragmentGenerator.toJS(returnContext); sw.println(";"); } sw.outdent(); sw.print("}"); }