Package seph.lang.anno

Source Code of seph.lang.anno.AnnotationBimCreator$AnnotationBimCreatorProcessor$SephClassVisitor

/*
* See LICENSE file in distribution for copyright and licensing information.
*/
package seph.lang.anno;

import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.*;
import com.sun.mirror.type.ReferenceType;
import com.sun.mirror.util.*;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Collection;
import java.util.Set;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import static java.util.Collections.*;
import static com.sun.mirror.util.DeclarationVisitors.*;

import seph.lang.SephMethod;
import seph.lang.SephCell;
import seph.lang.SephKind;
import seph.lang.SephSingleton;

/**
* @author <a href="mailto:ola.bini@gmail.com">Ola Bini</a>
*/
public class AnnotationBimCreator implements AnnotationProcessorFactory {
    private static final Collection<String> supportedAnnotations = unmodifiableCollection(Arrays.asList("seph.lang.SephMethod", "seph.lang.SephCell", "seph.lang.SephSingleton", "seph.lang.SephKind"));
    private static final Collection<String> supportedOptions = emptySet();

    public Collection<String> supportedAnnotationTypes() {
        return supportedAnnotations;
    }

    public Collection<String> supportedOptions() {
        return supportedOptions;
    }

    public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration> atds, AnnotationProcessorEnvironment env) {
        return new AnnotationBimCreatorProcessor(env);
    }

    private static class AnnotationBimCreatorProcessor implements AnnotationProcessor {
        private final AnnotationProcessorEnvironment env;

        AnnotationBimCreatorProcessor(AnnotationProcessorEnvironment env) {
            this.env = env;
        }

        public void process() {
            for(TypeDeclaration typeDecl : env.getSpecifiedTypeDeclarations()) {
                typeDecl.accept(getDeclarationScanner(new SephClassVisitor(), NO_OP));
            }
        }

        private class SephClassVisitor extends SimpleDeclarationVisitor {
            private PrintStream out;
            private StringBuilder tempOut;
            private static final boolean DEBUG = false;

            @Override
            public void visitClassDeclaration(ClassDeclaration cd) {
                try {
                    SephSingleton ss = cd.getAnnotation(SephSingleton.class);
                    SephKind sk = cd.getAnnotation(SephKind.class);
                    if(ss == null && sk == null) {
                        return;
                    }

                    final boolean kind = sk != null;
               
                    String[] parents = ss != null ? ss.parents() : sk.parents();

                    Map<String, MethodDeclaration> methods = new LinkedHashMap<String, MethodDeclaration>();

                    for(MethodDeclaration md : cd.getMethods()) {
                        SephMethod anno = md.getAnnotation(SephMethod.class);
                        if (anno == null) {
                            continue;
                        }

                        String name = md.getSimpleName();
                        methods.put(name, md);
                    }

                    Map<String, FieldDeclaration> fields = new LinkedHashMap<String, FieldDeclaration>();

                    for(FieldDeclaration fd : cd.getFields()) {
                        SephCell anno = fd.getAnnotation(SephCell.class);
                        if (anno == null) {
                            continue;
                        }

                        String name = fd.getSimpleName();
                        fields.put(name, fd);
                    }

                    ByteArrayOutputStream bytes = new ByteArrayOutputStream(1024);
                    out = new PrintStream(bytes);

                    out.println("/* THIS FILE IS GENERATED. DO NOT EDIT */");
                    out.println("package seph.lang.bim;");
                    out.println();
                    out.println("import java.lang.invoke.*;");
                    out.println("import seph.lang.*;");
                    out.println("import seph.lang.persistent.*;");
                    out.println("import static seph.lang.Types.*;");
                    out.println("import static seph.lang.ActivationHelpers.*;");
                    out.println();
                    out.println("public class " + cd.getSimpleName() + "Base {");
                    out.println();
                    for(String parent : parents) {
                        out.println("    public final static SephObject parent_" + parent + " = " + parent + ".instance;");
                    }
                    out.println();
                    for(String cell : methods.keySet()) {
                        out.println("    public final static SephObject cell_" + cell + " = getSephMethodHandleObject_" + cell + "();");
                    }
                    out.println();
                    for(String cell : fields.keySet()) {
                        out.println("    public final static SephObject cell_" + cell + " = " + cell + ".instance;");
                    }
                    out.println();
                    out.println("    public final static Object IDENTITY = new Object();");
                    out.println();
                    out.println("    public static SephObject get(String name) {");
                    out.println("        name = name.intern();");
                    for(Map.Entry<String,MethodDeclaration> entry : methods.entrySet()) {
                        String name = entry.getKey();
                        SephMethod anno = entry.getValue().getAnnotation(SephMethod.class);
                        if(anno.name().length > 0) {
                            name = anno.name()[0];
                        }
                        out.println("        if(name == \"" + name + "\") return cell_" + entry.getKey() + ";");
                    }
                    for(Map.Entry<String,FieldDeclaration> entry : fields.entrySet()) {
                        SephCell c = entry.getValue().getAnnotation(SephCell.class);
                        String realName = entry.getKey();
                        String cell = c.name().length > 0 ? c.name()[0] : realName;
                        out.println("        if(name == \"" + cell + "\") return cell_" + realName + ";");
                    }
                    out.println();
                    out.println("        SephObject result;");
                    for(String parent : parents) {
                        out.println("        if((result = parent_" + parent + ".get(name)) != null) return result;");
                    }
                    out.println("        return null;");
                    out.println("    }");
                    out.println();
                    for(Map.Entry<String, MethodDeclaration> entry : methods.entrySet()) {
                        String name = entry.getKey();
                        SephMethod anno = entry.getValue().getAnnotation(SephMethod.class);
                        if(anno.name().length > 0) {
                            name = anno.name()[0];
                        }

                        generateMethod(cd, entry.getKey(), entry.getValue(), name);
                    }
                    out.println();
                    out.println("}");
                    out.close();
                    out = null;

                    FileOutputStream fos = new FileOutputStream("src/gen/seph/lang/bim/" + cd.getSimpleName() + "Base.java");
                    fos.write(bytes.toByteArray());
                    fos.close();
                } catch (IOException ioe) {
                    System.err.println("Failed to generate:");
                    ioe.printStackTrace();
                    System.exit(1);
                }
            }

            private int generateRegularArgumentEvaluation(MethodDeclaration md, StringBuilder sb) throws IOException {
                boolean hasRestKeywords = false;
                boolean hasRestPositional = false;
                int positionalArity = 0;
                boolean hasReceiver = false;

                String sep = "";
                for(ParameterDeclaration pd : md.getParameters()) {
                    sb.append(sep);
                    String tname = pd.getType().toString();
                    if(tname.equals("seph.lang.LexicalScope")) {
                        sb.append("scope");
                    } else if(tname.equals("seph.lang.SephObject")) {
                        if(!hasReceiver) {
                            sb.append("receiver");
                            hasReceiver = true;
                        } else {
                            sb.append("args.arg" + positionalArity);
                            positionalArity++;
                        }
                    } else if(tname.equals("seph.lang.SThread")) {
                        sb.append("thread");
                    } else if(tname.equals("java.lang.String[]")) {
                        sb.append("args.restKeywordNames");
                        hasRestKeywords = true;
                    } else if(hasRestKeywords && tname.equals("java.lang.invoke.MethodHandle[]")) {
                        sb.append("args.restKeywordMHs");
                        hasRestKeywords = true;
                    } else if(tname.equals("seph.lang.SephObject[]")) {
                        sb.append("args.restPositional");
                        hasRestPositional = true;
                    }
                    sep = ", ";
                }

                if(positionalArity > 5) {
                    throw new RuntimeException("Built in functions can't take more than five positional arguments. Use a rest argument instead (for " + md + ")");
                }

                out.println("        SephMethodObject.ArgumentResult args = SephMethodObject.parseAndEvaluateArguments(thread, scope, arguments, "+positionalArity+", "+hasRestPositional+", " +hasRestKeywords+ ");");
                return positionalArity;
            }

            private int generateUnevaluatedArguments(MethodDeclaration md, StringBuilder sb) throws IOException {
                boolean hasReceiver = false;
                int positionalArity = 0;
                boolean restArgs = false;
                String sep = "";
                for(ParameterDeclaration pd : md.getParameters()) {
                    sb.append(sep);
                    String tname = pd.getType().toString();
                    if(tname.equals("seph.lang.LexicalScope")) {
                        sb.append("scope");
                    } else if(tname.equals("seph.lang.SephObject")) {
                        sb.append("receiver");
                    } else if(tname.equals("seph.lang.SThread")) {
                        sb.append("thread");
                    } else if(tname.equals("java.lang.invoke.MethodHandle[]")) {
                        sb.append("arguments");
                        restArgs = true;
                    } else if(tname.equals("java.lang.invoke.MethodHandle")) {
                        sb.append("args.argMH" + positionalArity);
                        positionalArity++;
                    }
                    sep = ", ";
                }

                if(positionalArity > 5) {
                    throw new RuntimeException("Built in functions can't take more than five positional arguments. Use a rest argument instead (for " + md + ")");
                }

                out.println("        SephMethodObject.ArgumentResult args = SephMethodObject.parseAndEvaluateArgumentsUneval(thread, scope, arguments, "+positionalArity+");");
                return restArgs ? -1 : positionalArity;
            }

            private int generateForArityMH(int arity, int currentArity, MethodDeclaration md, ClassDeclaration cd, boolean eval, boolean key) throws IOException {
                if(arity == currentArity) {
                    int args = 0;
                    StringBuilder sb = new StringBuilder();
                    String sep = "";
                    boolean haveReceiver = false;
                    List<String> parameterTypes = new LinkedList<String>();
                    List<String> outputTypes = new LinkedList<String>();

                    for(ParameterDeclaration pd : md.getParameters()) {
                        sb.append(sep);
                        String tname = pd.getType().toString();
                        parameterTypes.add(tname);
                        if(tname.equals("seph.lang.LexicalScope")) {
                            sb.append("scope");
                            outputTypes.add("seph.lang.LexicalScope");
                        } else if(tname.equals("seph.lang.SephObject")) {
                            if(haveReceiver) {
                                sb.append("invokeExact(arg" + (args++)).append(", thread, scope)");;
                                outputTypes.add("invokeExact(SephObject)");
                            } else {
                                haveReceiver = true;
                                sb.append("receiver");
                                outputTypes.add("seph.lang.SephObject");
                            }
                        } else if(tname.equals("java.lang.invoke.MethodHandle")) {
                            sb.append("arg" + (args++));
                            outputTypes.add("java.lang.invoke.MethodHandle");
                        } else if(key && tname.equals("java.lang.invoke.MethodHandle[]")) {
                            sb.append("keywordArguments");
                            outputTypes.add("java.lang.invoke.MethodHandle[]");
                        } else if(key && tname.equals("java.lang.String[]")) {
                            sb.append("keywordNames");
                            outputTypes.add("java.lang.String[]");
                        } else if(tname.equals("seph.lang.SThread")) {
                            sb.append("thread");
                            outputTypes.add("seph.lang.SThread");
                        } else {
                            tempOut.append("        throw new RuntimeException(\"Unexpected argument type: " + tname + ". This is most likely a compiler bug\");").append("\n");
                            return 1;
                        }

                        sep = ", ";
                    }
                    tempOut.append("        return " + cd.getQualifiedName() + "." + md.getSimpleName() + "(" + sb + ");").append("\n");
               
                    if(!eval && !key && parameterTypes.equals(outputTypes)) {
                        return -2;
                    }
                } else if(arity < 0) {
                    int args = 0;
                    StringBuilder sb = new StringBuilder();
                    String sep = "";
                    boolean haveReceiver = false;
                    boolean createArgs = false;
                    for(ParameterDeclaration pd : md.getParameters()) {
                        sb.append(sep);
                        String tname = pd.getType().toString();
                        if(tname.equals("seph.lang.LexicalScope")) {
                            sb.append("scope");
                        } else if(!createArgs && tname.equals("java.lang.invoke.MethodHandle[]")) {
                            sb.append("arguments");
                            createArgs = true;
                        } else if(tname.equals("seph.lang.SephObject")) {
                            if(haveReceiver) {
                                sb.append("invokeExact(arg" + (args++)).append(", thread, scope)");;
                            } else {
                                haveReceiver = true;
                                sb.append("receiver");
                            }
                        } else if(tname.equals("java.lang.invoke.MethodHandle")) {
                            sb.append("arg" + (args++));
                        } else if(key && tname.equals("java.lang.invoke.MethodHandle[]")) {
                            sb.append("keywordArguments");
                        } else if(key && tname.equals("java.lang.String[]")) {
                            sb.append("keywordNames");
                        } else if(tname.equals("seph.lang.SThread")) {
                            sb.append("thread");
                        } else {
                            tempOut.append("        throw new RuntimeException(\"Unexpected argument type: " + tname + ". This is most likely a compiler bug\");").append("\n");
                            return 1;
                        }

                        sep = ", ";
                    }
                    if(createArgs) {
                        tempOut.append("        MethodHandle[] arguments = new MethodHandle[" + currentArity + "];").append("\n");
                        for(int i = 0; i < currentArity; i++) {
                            tempOut.append("        arguments[" + i + "] = arg" + i + ";").append("\n");
                        }
                    }
                    tempOut.append("        return " + cd.getQualifiedName() + "." + md.getSimpleName() + "(" + sb + ");").append("\n");
                } else {
                    return 0;
                }
                return 1;
            }

            private void generateMethod(ClassDeclaration cd, String name, MethodDeclaration md, String realName) throws IOException {
                String[] getters = new String[14];
                int ix = 0;
                int result = 0;

                out.println("    public static SephObject " + name + "(SephObject receiver, SThread thread, LexicalScope scope, MethodHandle[] arguments) {");

                SephMethod sm = md.getAnnotation(SephMethod.class);

                StringBuilder sb = new StringBuilder();

                boolean eval = true;
                int arity = -1;
                if(sm.evaluateArguments()) {
                    arity = generateRegularArgumentEvaluation(md, sb);
                } else {
                    arity = generateUnevaluatedArguments(md, sb);
                    eval = false;
                }

                out.println("        return " + cd.getQualifiedName() + "." + md.getSimpleName() + "(" + sb + ");");
                out.println("    }");
                out.println();
                getters[ix++] = "                             l.findStatic(" + cd.getSimpleName() + "Base.class, \"" + name + "\", ACTIVATE_METHOD_TYPE_N)";

                tempOut = new StringBuilder();
                tempOut.append("    public static SephObject " + name + "(SephObject receiver, SThread thread, LexicalScope scope) {").append("\n");
                result = generateForArityMH(arity, 0, md, cd, eval, false);
                tempOut.append("    }").append("\n");
                if(result == 1) {
                    out.print(tempOut.toString());
                    getters[ix++] = "                             l.findStatic(" + cd.getSimpleName() + "Base.class, \"" + name + "\", ACTIVATE_METHOD_TYPE_0)";
                } else if(result == -2) {
                    getters[ix++] = "                             l.findStatic(" + cd.getQualifiedName() + ".class, \"" + md.getSimpleName() + "\", ACTIVATE_METHOD_TYPE_0)";
                } else {
                    getters[ix++] = "                             arityError(" + arity + ", 0, \"" + realName + "\", false)";
                }


                tempOut = new StringBuilder();
                tempOut.append("    public static SephObject " + name + "(SephObject receiver, SThread thread, LexicalScope scope, MethodHandle arg0) {").append("\n");
                result = generateForArityMH(arity, 1, md, cd, eval, false);
                tempOut.append("    }").append("\n");
                if(result == 1) {
                    out.print(tempOut.toString());
                    getters[ix++] = "                             l.findStatic(" + cd.getSimpleName() + "Base.class, \"" + name + "\", ACTIVATE_METHOD_TYPE_1)";
                } else if(result == -2) {
                    getters[ix++] = "                             l.findStatic(" + cd.getQualifiedName() + ".class, \"" + md.getSimpleName() + "\", ACTIVATE_METHOD_TYPE_1)";
                } else {
                    getters[ix++] = "                             arityError(" + arity + ", 1, \"" + realName + "\", false)";
                }

                tempOut = new StringBuilder();
                tempOut.append("    public static SephObject " + name + "(SephObject receiver, SThread thread, LexicalScope scope, MethodHandle arg0, MethodHandle arg1) {").append("\n");
                result = generateForArityMH(arity, 2, md, cd, eval, false);
                tempOut.append("    }").append("\n");
                if(result == 1) {
                    out.print(tempOut.toString());
                    getters[ix++] = "                             l.findStatic(" + cd.getSimpleName() + "Base.class, \"" + name + "\", ACTIVATE_METHOD_TYPE_2)";
                } else if(result == -2) {
                    getters[ix++] = "                             l.findStatic(" + cd.getQualifiedName() + ".class, \"" + md.getSimpleName() + "\", ACTIVATE_METHOD_TYPE_2)";
                } else {
                    getters[ix++] = "                             arityError(" + arity + ", 2, \"" + realName + "\", false)";
                }

                tempOut = new StringBuilder();
                tempOut.append("    public static SephObject " + name + "(SephObject receiver, SThread thread, LexicalScope scope, MethodHandle arg0, MethodHandle arg1, MethodHandle arg2) {").append("\n");
                result = generateForArityMH(arity, 3, md, cd, eval, false);
                tempOut.append("    }").append("\n");
                if(result == 1) {
                    out.print(tempOut.toString());
                    getters[ix++] = "                             l.findStatic(" + cd.getSimpleName() + "Base.class, \"" + name + "\", ACTIVATE_METHOD_TYPE_3)";
                } else if(result == -2) {
                    getters[ix++] = "                             l.findStatic(" + cd.getQualifiedName() + ".class, \"" + md.getSimpleName() + "\", ACTIVATE_METHOD_TYPE_3)";
                } else {
                    getters[ix++] = "                             arityError(" + arity + ", 3, \"" + realName + "\", false)";
                }

                tempOut = new StringBuilder();
                tempOut.append("    public static SephObject " + name + "(SephObject receiver, SThread thread, LexicalScope scope, MethodHandle arg0, MethodHandle arg1, MethodHandle arg2, MethodHandle arg3) {").append("\n");
                result = generateForArityMH(arity, 4, md, cd, eval, false);
                tempOut.append("    }").append("\n");
                if(result == 1) {
                    out.print(tempOut.toString());
                    getters[ix++] = "                             l.findStatic(" + cd.getSimpleName() + "Base.class, \"" + name + "\", ACTIVATE_METHOD_TYPE_4)";
                } else if(result == -2) {
                    getters[ix++] = "                             l.findStatic(" + cd.getQualifiedName() + ".class, \"" + md.getSimpleName() + "\", ACTIVATE_METHOD_TYPE_4)";
                } else {
                    getters[ix++] = "                             arityError(" + arity + ", 4, \"" + realName + "\", false)";
                }

                tempOut = new StringBuilder();
                tempOut.append("    public static SephObject " + name + "(SephObject receiver, SThread thread, LexicalScope scope, MethodHandle arg0, MethodHandle arg1, MethodHandle arg2, MethodHandle arg3, MethodHandle arg4) {").append("\n");
                result = generateForArityMH(arity, 5, md, cd, eval, false);
                tempOut.append("    }").append("\n");
                if(result == 1) {
                    out.print(tempOut.toString());
                    getters[ix++] = "                             l.findStatic(" + cd.getSimpleName() + "Base.class, \"" + name + "\", ACTIVATE_METHOD_TYPE_5)";
                } else if(result == -2) {
                    getters[ix++] = "                             l.findStatic(" + cd.getQualifiedName() + ".class, \"" + md.getSimpleName() + "\", ACTIVATE_METHOD_TYPE_5)";
                } else {
                    getters[ix++] = "                             arityError(" + arity + ", 5, \"" + realName + "\", false)";
                }


                out.println("    public static SephObject " + name + "(SephObject receiver, SThread thread, LexicalScope scope, MethodHandle[] arguments, String[] keywordNames, MethodHandle[] keywordArguments) {");

                sb = new StringBuilder();

                eval = true;
                arity = -1;
                if(sm.evaluateArguments()) {
                    arity = generateRegularArgumentEvaluation(md, sb);
                } else {
                    arity = generateUnevaluatedArguments(md, sb);
                    eval = false;
                }

                out.println("        return " + cd.getQualifiedName() + "." + md.getSimpleName() + "(" + sb + ");");
                out.println("    }");
                out.println();
                getters[ix++] = "                             l.findStatic(" + cd.getSimpleName() + "Base.class, \"" + name + "\", ACTIVATE_METHOD_TYPE_N_K)";
               
                tempOut = new StringBuilder();
                tempOut.append("    public static SephObject " + name + "(SephObject receiver, SThread thread, LexicalScope scope, String[] keywordNames, MethodHandle[] keywordArguments) {").append("\n");
                result = generateForArityMH(arity, 0, md, cd, eval, true);
                tempOut.append("    }").append("\n");
                if(result == 1) {
                    out.print(tempOut.toString());
                    getters[ix++] = "                             l.findStatic(" + cd.getSimpleName() + "Base.class, \"" + name + "\", ACTIVATE_METHOD_TYPE_0_K)";
                } else if(result == -2) {
                    getters[ix++] = "                             l.findStatic(" + cd.getQualifiedName() + ".class, \"" + md.getSimpleName() + "\", ACTIVATE_METHOD_TYPE_0_K)";
                } else {
                    getters[ix++] = "                             arityError(" + arity + ", 0, \"" + realName + "\", true)";
                }

                tempOut = new StringBuilder();
                tempOut.append("    public static SephObject " + name + "(SephObject receiver, SThread thread, LexicalScope scope, MethodHandle arg0, String[] keywordNames, MethodHandle[] keywordArguments) {").append("\n");
                result = generateForArityMH(arity, 1, md, cd, eval, true);
                tempOut.append("    }").append("\n");
                if(result == 1) {
                    out.print(tempOut.toString());
                    getters[ix++] = "                             l.findStatic(" + cd.getSimpleName() + "Base.class, \"" + name + "\", ACTIVATE_METHOD_TYPE_1_K)";
                } else if(result == -2) {
                    getters[ix++] = "                             l.findStatic(" + cd.getQualifiedName() + ".class, \"" + md.getSimpleName() + "\", ACTIVATE_METHOD_TYPE_1_K)";
                } else {
                    getters[ix++] = "                             arityError(" + arity + ", 1, \"" + realName + "\", true)";
                }

                tempOut = new StringBuilder();
                tempOut.append("    public static SephObject " + name + "(SephObject receiver, SThread thread, LexicalScope scope, MethodHandle arg0, MethodHandle arg1, String[] keywordNames, MethodHandle[] keywordArguments) {").append("\n");
                result = generateForArityMH(arity, 2, md, cd, eval, true);
                tempOut.append("    }").append("\n");
                if(result == 1) {
                    out.print(tempOut.toString());
                    getters[ix++] = "                             l.findStatic(" + cd.getSimpleName() + "Base.class, \"" + name + "\", ACTIVATE_METHOD_TYPE_2_K)";
                } else if(result == -2) {
                    getters[ix++] = "                             l.findStatic(" + cd.getQualifiedName() + ".class, \"" + md.getSimpleName() + "\", ACTIVATE_METHOD_TYPE_2_K)";
                } else {
                    getters[ix++] = "                             arityError(" + arity + ", 2, \"" + realName + "\", true)";
                }

                tempOut = new StringBuilder();
                tempOut.append("    public static SephObject " + name + "(SephObject receiver, SThread thread, LexicalScope scope, MethodHandle arg0, MethodHandle arg1, MethodHandle arg2, String[] keywordNames, MethodHandle[] keywordArguments) {").append("\n");
                result = generateForArityMH(arity, 3, md, cd, eval, true);
                tempOut.append("    }").append("\n");
                if(result == 1) {
                    out.print(tempOut.toString());
                    getters[ix++] = "                             l.findStatic(" + cd.getSimpleName() + "Base.class, \"" + name + "\", ACTIVATE_METHOD_TYPE_3_K)";
                } else if(result == -2) {
                    getters[ix++] = "                             l.findStatic(" + cd.getQualifiedName() + ".class, \"" + md.getSimpleName() + "\", ACTIVATE_METHOD_TYPE_3_K)";
                } else {
                    getters[ix++] = "                             arityError(" + arity + ", 3, \"" + realName + "\", true)";
                }

                tempOut = new StringBuilder();
                tempOut.append("    public static SephObject " + name + "(SephObject receiver, SThread thread, LexicalScope scope, MethodHandle arg0, MethodHandle arg1, MethodHandle arg2, MethodHandle arg3, String[] keywordNames, MethodHandle[] keywordArguments) {").append("\n");
                result = generateForArityMH(arity, 4, md, cd, eval, true);
                tempOut.append("    }").append("\n");
                if(result == 1) {
                    out.print(tempOut.toString());
                    getters[ix++] = "                             l.findStatic(" + cd.getSimpleName() + "Base.class, \"" + name + "\", ACTIVATE_METHOD_TYPE_4_K)";
                } else if(result == -2) {
                    getters[ix++] = "                             l.findStatic(" + cd.getQualifiedName() + ".class, \"" + md.getSimpleName() + "\", ACTIVATE_METHOD_TYPE_4_K)";
                } else {
                    getters[ix++] = "                             arityError(" + arity + ", 4, \"" + realName + "\", true)";
                }

                tempOut = new StringBuilder();
                tempOut.append("    public static SephObject " + name + "(SephObject receiver, SThread thread, LexicalScope scope, MethodHandle arg0, MethodHandle arg1, MethodHandle arg2, MethodHandle arg3, MethodHandle arg4, String[] keywordNames, MethodHandle[] keywordArguments) {").append("\n");
                result = generateForArityMH(arity, 5, md, cd, eval, true);
                tempOut.append("    }").append("\n");
                if(result == 1) {
                    out.print(tempOut.toString());
                    getters[ix++] = "                             l.findStatic(" + cd.getSimpleName() + "Base.class, \"" + name + "\", ACTIVATE_METHOD_TYPE_5_K)";
                } else if(result == -2) {
                    getters[ix++] = "                             l.findStatic(" + cd.getQualifiedName() + ".class, \"" + md.getSimpleName() + "\", ACTIVATE_METHOD_TYPE_5_K)";
                } else {
                    getters[ix++] = "                             arityError(" + arity + ", 5, \"" + realName + "\", true)";
                }



                out.println("    private static SephMethodHandleObject getSephMethodHandleObject_" + name + "() {");
                out.println("        try {");
                out.println("            MethodHandles.Lookup l = MethodHandles.lookup();");
                out.println("            return new SephMethodHandleObject(");
                for(int i = 0; i < getters.length; i++) {
                    out.print(getters[i]);
                    if(i == getters.length - 1) {
                        out.println(");");
                    } else {
                        out.println(",");
                    }
                }
                out.println("        } catch(Throwable e) {");
                out.println("            e.printStackTrace();");
                out.println("            throw new RuntimeException(e);");
                out.println("        }");
                out.println("    }");
            }
        }
    }
}// AnnotationBimCreator
TOP

Related Classes of seph.lang.anno.AnnotationBimCreator$AnnotationBimCreatorProcessor$SephClassVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.