]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/StringInterpolation.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / constants / StringInterpolation.java
index 9b3bbca92a342dfa6a0fa774f9d10c82d60d57d7..ab4bafbc4af7d9eaaeecc14d1b608c9f269994e2 100644 (file)
-package org.simantics.scl.compiler.constants;\r
-\r
-import java.util.Arrays;\r
-\r
-import org.cojen.classfile.TypeDesc;\r
-import org.objectweb.asm.Label;\r
-import org.objectweb.asm.Opcodes;\r
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
-import org.simantics.scl.compiler.internal.codegen.continuations.Cont;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.references.Val;\r
-import org.simantics.scl.compiler.internal.codegen.utils.Constants;\r
-import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable;\r
-import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
-import org.simantics.scl.compiler.types.TVar;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-\r
-public class StringInterpolation extends FunctionValue {\r
-\r
-    public static final TypeDesc STRING_BUILDER = TypeDesc.forClass(StringBuilder.class);\r
-    \r
-    private final String[] textParts;\r
-    \r
-    public StringInterpolation(Type[] parameterTypes, String[] textParts) {\r
-        super(TVar.EMPTY_ARRAY, Types.NO_EFFECTS, Types.STRING, parameterTypes);\r
-        this.textParts = textParts;\r
-    }\r
-    \r
-    public StringInterpolation(String[] textParts) {\r
-        this(stringTypeArray(textParts.length-1), textParts);\r
-    }\r
-    \r
-    @Override\r
-    public String toString() {\r
-        StringBuilder b = new StringBuilder();\r
-        b.append('"');\r
-        boolean first = true;\r
-        for(String textPart : textParts) {\r
-            if(first)\r
-                first = false;\r
-            else\r
-                b.append("\\(.)");\r
-            b.append(textPart);\r
-        }\r
-        b.append('"');\r
-        return b.toString();\r
-    }\r
-\r
-    private static Type[] stringTypeArray(int length) {\r
-        Type[] result = new Type[length];\r
-        for(int i=0;i<length;++i)\r
-            result[i] = Types.STRING;\r
-        return result;\r
-    }\r
-\r
-    @Override\r
-    public Type applyExact(MethodBuilder mb, Val[] parameters) {\r
-        if(textParts.length==1) {\r
-            mb.loadConstant(textParts[0]);\r
-        }\r
-        else if(textParts.length==2) {\r
-            if(parameters[0].getType() == Types.STRING) {\r
-                // Optimized special cases "asd" + x, x + "asd"\r
-                if(textParts[0].isEmpty()) {\r
-                    mb.push(parameters[0], Types.STRING);\r
-                    if(!textParts[1].isEmpty()) {\r
-                        mb.loadConstant(textParts[1]);\r
-                        mb.invokeVirtual("java/lang/String", "concat", TypeDesc.STRING, new TypeDesc[] {TypeDesc.STRING});\r
-                    }\r
-                    return Types.STRING;\r
-                }\r
-                else if(textParts[1].isEmpty()) {\r
-                    mb.loadConstant(textParts[0]);\r
-                    mb.push(parameters[0], Types.STRING);\r
-                    mb.invokeVirtual("java/lang/String", "concat", TypeDesc.STRING, new TypeDesc[] {TypeDesc.STRING});\r
-                    return Types.STRING;\r
-                }\r
-            }\r
-        }\r
-        else if(textParts.length==3) {\r
-            if(parameters[0].getType() == Types.STRING && parameters[1].getType() == Types.STRING\r
-                    && textParts[0].isEmpty() && textParts[1].isEmpty() && textParts[2].isEmpty()) {\r
-                mb.push(parameters[0], Types.STRING);\r
-                mb.push(parameters[1], Types.STRING);\r
-                mb.invokeVirtual("java/lang/String", "concat", TypeDesc.STRING, new TypeDesc[] {TypeDesc.STRING});\r
-                return Types.STRING;\r
-            }\r
-        }\r
-        mb.newObject(STRING_BUILDER);\r
-        mb.dup();\r
-        mb.invokeConstructor(STRING_BUILDER, Constants.EMPTY_TYPEDESC_ARRAY);\r
-        \r
-        for(int i=0;i<parameters.length;++i) {\r
-            String textPart = textParts[i]; \r
-            if(!textPart.isEmpty()) {\r
-                mb.loadConstant(textPart);\r
-                mb.invokeVirtual(STRING_BUILDER, "append", STRING_BUILDER, new TypeDesc[] {TypeDesc.STRING});\r
-            }\r
-            \r
-            mb.push(parameters[i], parameterTypes[i]);\r
-            mb.invokeVirtual(STRING_BUILDER, "append", STRING_BUILDER,\r
-                    new TypeDesc[] {mb.getJavaTypeTranslator().toTypeDesc(parameterTypes[i])});\r
-        }\r
-        \r
-        {\r
-            String textPart = textParts[parameters.length]; \r
-            if(!textPart.isEmpty()) {\r
-                mb.loadConstant(textPart);\r
-                mb.invokeVirtual(STRING_BUILDER, "append", STRING_BUILDER, new TypeDesc[] {TypeDesc.STRING});\r
-            }\r
-        }\r
-        \r
-        mb.invokeVirtual(STRING_BUILDER, "toString", TypeDesc.STRING, Constants.EMPTY_TYPEDESC_ARRAY);\r
-        \r
-        return Types.STRING;\r
-    }\r
-    \r
-    @Override\r
-    public int hashCode() {\r
-        return Arrays.hashCode(textParts) ^ Arrays.hashCode(parameterTypes);\r
-    }\r
-\r
-    @Override\r
-    public boolean equals(Object obj) {\r
-        if(this == obj)\r
-            return true;\r
-        if(obj == null || obj.getClass() != getClass())\r
-            return false;\r
-        StringInterpolation other = (StringInterpolation)obj;\r
-        return Arrays.equals(textParts, other.textParts) && Arrays.equals(parameterTypes, other.parameterTypes);\r
-    }\r
-    \r
-    @Override\r
-    public int constructorTag() {\r
-        return textParts.length == 2 && parameterTypes[0] == Types.STRING ? 0 : -1;\r
-    }\r
-    \r
-    @Override\r
-    public void deconstruct(MethodBuilder mb, IVal parameter, Cont success, Label failure) {\r
-        if(textParts.length != 2)\r
-            throw new InternalCompilerError("String interpolation with more than one open string parts cannot be used as a pattern.");\r
-        mb.push(parameter, Types.STRING);\r
-        LocalVariable temp = mb.createLocalVariable(null, TypeDesc.STRING);\r
-        mb.storeLocal(temp);\r
-        if(!textParts[0].isEmpty()) {\r
-            mb.loadLocal(temp);\r
-            mb.loadConstant(textParts[0]);\r
-            mb.invokeVirtual("java/lang/String", "startsWith", TypeDesc.BOOLEAN, new TypeDesc[] {TypeDesc.STRING});\r
-            mb.ifZeroComparisonBranch(failure, "==");\r
-        }\r
-        if(!textParts[1].isEmpty()) {\r
-            mb.loadLocal(temp);\r
-            mb.loadConstant(textParts[1]);\r
-            mb.invokeVirtual("java/lang/String", "endsWith", TypeDesc.BOOLEAN, new TypeDesc[] {TypeDesc.STRING});\r
-            mb.ifZeroComparisonBranch(failure, "==");\r
-        }\r
-        mb.loadLocal(temp);\r
-        mb.loadConstant(textParts[0].length());\r
-        mb.loadLocal(temp);\r
-        mb.invokeVirtual("java/lang/String", "length", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);\r
-        mb.loadConstant(textParts[1].length());\r
-        mb.math(Opcodes.ISUB);\r
-        mb.invokeVirtual("java/lang/String", "substring", TypeDesc.STRING, new TypeDesc[] {TypeDesc.INT, TypeDesc.INT});\r
-        mb.storeLocal(temp);\r
-        mb.jump(success, new LocalVariableConstant(Types.STRING, temp));\r
-    }\r
-    \r
-}\r
+package org.simantics.scl.compiler.constants;
+
+import java.util.Arrays;
+
+import org.cojen.classfile.TypeDesc;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.references.Val;
+import org.simantics.scl.compiler.internal.codegen.utils.Constants;
+import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable;
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
+import org.simantics.scl.compiler.types.TVar;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+
+public class StringInterpolation extends FunctionValue {
+
+    public static final TypeDesc STRING_BUILDER = TypeDesc.forClass(StringBuilder.class);
+    
+    private final String[] textParts;
+    
+    public StringInterpolation(Type[] parameterTypes, String[] textParts) {
+        super(TVar.EMPTY_ARRAY, Types.NO_EFFECTS, Types.STRING, parameterTypes);
+        this.textParts = textParts;
+    }
+    
+    public StringInterpolation(String[] textParts) {
+        this(stringTypeArray(textParts.length-1), textParts);
+    }
+    
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder();
+        b.append('"');
+        boolean first = true;
+        for(String textPart : textParts) {
+            if(first)
+                first = false;
+            else
+                b.append("\\(.)");
+            b.append(textPart);
+        }
+        b.append('"');
+        return b.toString();
+    }
+
+    private static Type[] stringTypeArray(int length) {
+        Type[] result = new Type[length];
+        for(int i=0;i<length;++i)
+            result[i] = Types.STRING;
+        return result;
+    }
+
+    @Override
+    public Type applyExact(MethodBuilder mb, Val[] parameters) {
+        if(textParts.length==1) {
+            mb.loadConstant(textParts[0]);
+        }
+        else if(textParts.length==2) {
+            if(parameters[0].getType() == Types.STRING) {
+                // Optimized special cases "asd" + x, x + "asd"
+                if(textParts[0].isEmpty()) {
+                    mb.push(parameters[0], Types.STRING);
+                    if(!textParts[1].isEmpty()) {
+                        mb.loadConstant(textParts[1]);
+                        mb.invokeVirtual("java/lang/String", "concat", TypeDesc.STRING, new TypeDesc[] {TypeDesc.STRING});
+                    }
+                    return Types.STRING;
+                }
+                else if(textParts[1].isEmpty()) {
+                    mb.loadConstant(textParts[0]);
+                    mb.push(parameters[0], Types.STRING);
+                    mb.invokeVirtual("java/lang/String", "concat", TypeDesc.STRING, new TypeDesc[] {TypeDesc.STRING});
+                    return Types.STRING;
+                }
+            }
+        }
+        else if(textParts.length==3) {
+            if(parameters[0].getType() == Types.STRING && parameters[1].getType() == Types.STRING
+                    && textParts[0].isEmpty() && textParts[1].isEmpty() && textParts[2].isEmpty()) {
+                mb.push(parameters[0], Types.STRING);
+                mb.push(parameters[1], Types.STRING);
+                mb.invokeVirtual("java/lang/String", "concat", TypeDesc.STRING, new TypeDesc[] {TypeDesc.STRING});
+                return Types.STRING;
+            }
+        }
+        mb.newObject(STRING_BUILDER);
+        mb.dup();
+        mb.invokeConstructor(STRING_BUILDER, Constants.EMPTY_TYPEDESC_ARRAY);
+        
+        for(int i=0;i<parameters.length;++i) {
+            String textPart = textParts[i]; 
+            if(!textPart.isEmpty()) {
+                mb.loadConstant(textPart);
+                mb.invokeVirtual(STRING_BUILDER, "append", STRING_BUILDER, new TypeDesc[] {TypeDesc.STRING});
+            }
+            
+            mb.push(parameters[i], parameterTypes[i]);
+            mb.invokeVirtual(STRING_BUILDER, "append", STRING_BUILDER,
+                    new TypeDesc[] {mb.getJavaTypeTranslator().toTypeDesc(parameterTypes[i])});
+        }
+        
+        {
+            String textPart = textParts[parameters.length]; 
+            if(!textPart.isEmpty()) {
+                mb.loadConstant(textPart);
+                mb.invokeVirtual(STRING_BUILDER, "append", STRING_BUILDER, new TypeDesc[] {TypeDesc.STRING});
+            }
+        }
+        
+        mb.invokeVirtual(STRING_BUILDER, "toString", TypeDesc.STRING, Constants.EMPTY_TYPEDESC_ARRAY);
+        
+        return Types.STRING;
+    }
+    
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(textParts) ^ Arrays.hashCode(parameterTypes);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if(this == obj)
+            return true;
+        if(obj == null || obj.getClass() != getClass())
+            return false;
+        StringInterpolation other = (StringInterpolation)obj;
+        return Arrays.equals(textParts, other.textParts) && Arrays.equals(parameterTypes, other.parameterTypes);
+    }
+    
+    @Override
+    public int constructorTag() {
+        return textParts.length == 2 && parameterTypes[0] == Types.STRING ? 0 : -1;
+    }
+    
+    @Override
+    public void deconstruct(MethodBuilder mb, IVal parameter, Cont success, Label failure) {
+        if(textParts.length != 2)
+            throw new InternalCompilerError("String interpolation with more than one open string parts cannot be used as a pattern.");
+        mb.push(parameter, Types.STRING);
+        LocalVariable temp = mb.createLocalVariable(null, TypeDesc.STRING);
+        mb.storeLocal(temp);
+        if(!textParts[0].isEmpty()) {
+            mb.loadLocal(temp);
+            mb.loadConstant(textParts[0]);
+            mb.invokeVirtual("java/lang/String", "startsWith", TypeDesc.BOOLEAN, new TypeDesc[] {TypeDesc.STRING});
+            mb.ifZeroComparisonBranch(failure, "==");
+        }
+        if(!textParts[1].isEmpty()) {
+            mb.loadLocal(temp);
+            mb.loadConstant(textParts[1]);
+            mb.invokeVirtual("java/lang/String", "endsWith", TypeDesc.BOOLEAN, new TypeDesc[] {TypeDesc.STRING});
+            mb.ifZeroComparisonBranch(failure, "==");
+        }
+        mb.loadLocal(temp);
+        mb.loadConstant(textParts[0].length());
+        mb.loadLocal(temp);
+        mb.invokeVirtual("java/lang/String", "length", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
+        mb.loadConstant(textParts[1].length());
+        mb.math(Opcodes.ISUB);
+        mb.invokeVirtual("java/lang/String", "substring", TypeDesc.STRING, new TypeDesc[] {TypeDesc.INT, TypeDesc.INT});
+        mb.storeLocal(temp);
+        mb.jump(success, new LocalVariableConstant(Types.STRING, temp));
+    }
+    
+}