Browse Source

+ new -varparas option that adds overloads for imported methods whereby
Java array parameters are translated into single element var-parameters

git-svn-id: trunk@21407 -

Jonas Maebe 13 years ago
parent
commit
3a2afe27aa

+ 1 - 0
utils/javapp/src/fpc/tools/javapp/JavapEnvironment.java

@@ -79,6 +79,7 @@ public class JavapEnvironment {
     String prefix_constant = "";
     String prefix_field = "f";
     String prefix_innerclass = "Inner";
+    boolean addVarOverloads = false;
 
     public JavapEnvironment() {
     	excludePrefixes = new ArrayList<String>();

+ 40 - 20
utils/javapp/src/fpc/tools/javapp/JavapPrinter.java

@@ -287,6 +287,42 @@ public class JavapPrinter {
         prefix=prefix.substring(2);
     }
 
+    protected void PrintSignatureVariants(PascalMethodData method, StringBuilder sigStart, StringBuilder sigEnd, boolean useConstOpenArray, boolean forceSingleVarVersion){
+        java.util.Set<PascalTypeSignature.ParaFlags> paraFlags;
+        
+        paraFlags = java.util.EnumSet.noneOf(PascalTypeSignature.ParaFlags.class);
+        String dynArrParas = method.getParameters(paraFlags);
+
+        paraFlags.add(PascalTypeSignature.ParaFlags.OpenArrays);
+        if (useConstOpenArray)
+            paraFlags.add(PascalTypeSignature.ParaFlags.OpenConstArrays);
+        String openArrParas = method.getParameters(paraFlags);
+
+        String regularVarParas = "";
+        if (env.addVarOverloads &&
+                (!useConstOpenArray ||
+                 forceSingleVarVersion)) {
+            paraFlags = java.util.EnumSet.noneOf(PascalTypeSignature.ParaFlags.class);
+            paraFlags.add(PascalTypeSignature.ParaFlags.SingleVar);
+            regularVarParas = method.getParameters(paraFlags);
+        }
+        
+        out.print(sigStart+dynArrParas+sigEnd);
+        printExceptions(method);
+        out.println();
+        if (!dynArrParas.equals(openArrParas)) {
+            out.print(sigStart+openArrParas+sigEnd);
+            printExceptions(method);
+            out.println();
+        }
+        if ((regularVarParas != "") &&
+                !dynArrParas.equals(regularVarParas)) {
+            out.print(sigStart+regularVarParas+sigEnd);
+            printExceptions(method);
+            out.println();
+        }
+    }
+    
     /**
      * Print method signature.
      */
@@ -301,20 +337,12 @@ public class JavapPrinter {
         	sigEnd = new StringBuilder();
             // to fix compilation in Delphi mode
         	sigEnd.append("; overload;");
-        	String dynArrParas = method.getParameters(false,true);
-        	String openArrParas = method.getParameters(true,true);
-            out.print(sigStart+dynArrParas+sigEnd);
-            printExceptions(method);
-            out.println();
-        	if (!dynArrParas.equals(openArrParas)) {
-        		out.print(sigStart+openArrParas+sigEnd);
-                printExceptions(method);
-                out.println();
-        	}
+        	PrintSignatureVariants(method,sigStart,sigEnd,true,true);
         }else if(pascalName.equals("<clinit>")){
         	sigStart.append("class constructor classcreate");
         }else{
         	String rettype = method.getReturnType();
+        	java.util.Set<PascalTypeSignature.ParaFlags> paraFlags;
         	if (method.isStatic())
         		sigStart.append("class ");
         	if (rettype.equals(""))
@@ -335,16 +363,8 @@ public class JavapPrinter {
             // all interface methods are marked as "abstract", and cannot be final
             if (!cls.isInterface())
             	sigEnd.append(method.getModifiers());
-        	String dynArrParas = method.getParameters(false,false);
-        	String openArrParas = method.getParameters(true,varargs);
-        	out.print(sigStart+dynArrParas+sigEnd);
-            printExceptions(method);
-            out.println();
-        	if (!dynArrParas.equals(openArrParas)) {
-        		out.print(sigStart+openArrParas+sigEnd);
-                printExceptions(method);
-                out.println();
-        	}
+            
+            PrintSignatureVariants(method,sigStart,sigEnd,varargs,false);
         }
     }
 

+ 3 - 0
utils/javapp/src/fpc/tools/javapp/Main.java

@@ -112,6 +112,7 @@ public class Main{
 		out.println("   -s                        Print internal type signatures");
 		out.println("   -bootclasspath <pathlist> Override location of class files loaded");
 		out.println("                             by the bootstrap class loader");
+		out.println("   -varparas                Add overloads that translate non-varargs array parameters into single-element 'var' parameters");
 		out.println("   -verbose                  Print stack size, number of locals and args for methods");
 		out.println("                             If verifying, print reasons for failure");
 		out.println();
@@ -227,6 +228,8 @@ public class Main{
 						usage();
 						return false;
 					}
+				} else if (arg.equals("-varparas")) {
+				    env.addVarOverloads = true;
 				} else {
 					error("invalid flag: " + arg);
 					usage();

+ 1 - 1
utils/javapp/src/fpc/tools/javapp/PascalFieldData.java

@@ -46,7 +46,7 @@ public class PascalFieldData extends FieldData {
      * Returns Pascal type signature of a field.
      */
     public String getType(){
-        return new PascalTypeSignature(env,getInternalSig(),cls,false,false).getFieldType();
+        return new PascalTypeSignature(env,getInternalSig(),cls,java.util.EnumSet.noneOf(PascalTypeSignature.ParaFlags.class)).getFieldType();
     }
 
     /**

+ 3 - 3
utils/javapp/src/fpc/tools/javapp/PascalMethodData.java

@@ -41,7 +41,7 @@ public class PascalMethodData extends MethodData {
      */
     public String getReturnType(){
 
-        String rttype = (new PascalTypeSignature(env,getInternalSig(), cls, false, false)).getReturnType();
+        String rttype = (new PascalTypeSignature(env,getInternalSig(), cls, java.util.EnumSet.noneOf(PascalTypeSignature.ParaFlags.class))).getReturnType();
         return rttype;
     }
 
@@ -60,8 +60,8 @@ public class PascalMethodData extends MethodData {
     /**
      * Return java type parameter signature.
      */
-    public String getParameters(boolean useOpenArrays, boolean useConstOpenArrays){
-        String ptype = (new PascalTypeSignature(env,getInternalSig(),cls,useOpenArrays,useConstOpenArrays)).getParameters();
+    public String getParameters(java.util.Set<PascalTypeSignature.ParaFlags> paraFlags){
+        String ptype = (new PascalTypeSignature(env,getInternalSig(),cls,paraFlags)).getParameters();
 
         return ptype;
     }

+ 23 - 12
utils/javapp/src/fpc/tools/javapp/PascalTypeSignature.java

@@ -4,18 +4,23 @@ import java.util.Vector;
 
 public class PascalTypeSignature extends TypeSignature {
 	
-	// use open arrays rather than dynamic arrays for array parameters
-	private boolean useOpenArrays;
-	// when creating open array parameters, declare them as "const" rather than var
-	// (done for constructors, under the assumption that these won't change the
-	//  incoming data)
-	private boolean useConstOpenArrays;
+    private java.util.Set<ParaFlags> paraFlags;
 	private JavapEnvironment env;
 
-	public PascalTypeSignature(JavapEnvironment env, String JVMSignature, ClassData cls, boolean useOpenArrays, boolean useConstOpenArrays) {
-	        this.env = env;
-		this.useOpenArrays = useOpenArrays;
-		this.useConstOpenArrays = useConstOpenArrays;
+	public enum ParaFlags {
+	    // use open arrays rather than dynamic arrays for array parameters
+	    OpenArrays,
+	    // when creating open array parameters, declare them as "const" rather than var
+	    // (done for constructors, under the assumption that these won't change the
+	    //  incoming data)
+	    OpenConstArrays,
+	    // translate array parameters into var parameters of single elements
+	    SingleVar
+	}
+	
+	public PascalTypeSignature(JavapEnvironment env, String JVMSignature, ClassData cls, java.util.Set<ParaFlags> paraFlags) {
+	    this.env = env;
+	    this.paraFlags=paraFlags;
 		init(JVMSignature);
 	}
 
@@ -85,7 +90,8 @@ public class PascalTypeSignature extends TypeSignature {
             }else {
                 componentType = getBaseType(arrayType);
             }
-            if (!useOpenArrays ||
+            if ((!paraFlags.contains(ParaFlags.OpenArrays) &&
+                    !paraFlags.contains(ParaFlags.SingleVar)) ||
             		(dimCount>1))
             	return outerClass+"Arr"+dimCount+componentType;
             else
@@ -106,7 +112,12 @@ public class PascalTypeSignature extends TypeSignature {
         	String paraType = (String)parameters.elementAt(i);
         	// contents of open arrays could be changed -> var parameters
         	if (paraType.contains("array of")) {
-        		if (!useConstOpenArrays)
+                if (paraFlags.contains(ParaFlags.SingleVar))
+                {
+                    parametersignature.append("var ");
+                    paraType = paraType.substring(paraType.indexOf("array of ")+"array of ".length());
+                }
+                else if (!paraFlags.contains(ParaFlags.OpenConstArrays))
         		  parametersignature.append("var ");
         		else
           		  parametersignature.append("const ");