Search in sources :

Example 6 with ClassFormatException

use of org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException in project querydsl by querydsl.

the class ECJEvaluatorFactory method compile.

protected void compile(String source, ClassType projectionType, String[] names, Type[] types, String id, Map<String, Object> constants) throws IOException {
    // create source
    source = createSource(source, projectionType, names, types, id, constants);
    // compile
    final char[] targetContents = source.toCharArray();
    final String targetName = id;
    final ICompilationUnit[] targetCompilationUnits = new ICompilationUnit[] { new ICompilationUnit() {

        @Override
        public char[] getContents() {
            return targetContents;
        }

        @Override
        public char[] getMainTypeName() {
            int dot = targetName.lastIndexOf('.');
            if (dot > 0) {
                return targetName.substring(dot + 1).toCharArray();
            } else {
                return targetName.toCharArray();
            }
        }

        @Override
        public char[][] getPackageName() {
            StringTokenizer tok = new StringTokenizer(targetName, ".");
            char[][] result = new char[tok.countTokens() - 1][];
            for (int j = 0; j < result.length; j++) {
                result[j] = tok.nextToken().toCharArray();
            }
            return result;
        }

        @Override
        public char[] getFileName() {
            return CharOperation.concat(targetName.toCharArray(), ".java".toCharArray());
        }

        @Override
        public boolean ignoreOptionalProblems() {
            return true;
        }
    } };
    INameEnvironment env = new INameEnvironment() {

        private String join(char[][] compoundName, char separator) {
            if (compoundName == null) {
                return "";
            } else {
                List<String> parts = new ArrayList<>(compoundName.length);
                for (char[] part : compoundName) {
                    parts.add(new String(part));
                }
                return parts.stream().collect(Collectors.joining(new String(new char[] { separator })));
            }
        }

        @Override
        public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
            return findType(join(compoundTypeName, '.'));
        }

        @Override
        public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
            return findType(CharOperation.arrayConcat(packageName, typeName));
        }

        private boolean isClass(String result) {
            if (result == null || result.isEmpty()) {
                return false;
            }
            // if it's the class we're compiling, then of course it's a class
            if (result.equals(targetName)) {
                return true;
            }
            InputStream is = null;
            try {
                // if this is a class we've already compiled, it's a class
                is = loader.getResourceAsStream(result);
                if (is == null) {
                    // use our normal class loader now...
                    String resourceName = result.replace('.', '/') + ".class";
                    is = parentClassLoader.getResourceAsStream(resourceName);
                    if (is == null && !result.contains(".")) {
                        // we couldn't find the class, and it has no package; is it a core class?
                        is = parentClassLoader.getResourceAsStream("java/lang/" + resourceName);
                    }
                }
                return is != null;
            } finally {
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException ex) {
                    }
                }
            }
        }

        @Override
        public boolean isPackage(char[][] parentPackageName, char[] packageName) {
            // if the parent is a class, the child can't be a package
            String parent = join(parentPackageName, '.');
            if (isClass(parent)) {
                return false;
            }
            // if the child is a class, it's not a package
            String qualifiedName = (parent.isEmpty() ? "" : parent + ".") + new String(packageName);
            return !isClass(qualifiedName);
        }

        @Override
        public void cleanup() {
        }

        private NameEnvironmentAnswer findType(String className) {
            String resourceName = className.replace('.', '/') + ".class";
            InputStream is = null;
            try {
                // we're only asking ECJ to compile a single class; we shouldn't need this
                if (className.equals(targetName)) {
                    return new NameEnvironmentAnswer(targetCompilationUnits[0], null);
                }
                is = loader.getResourceAsStream(resourceName);
                if (is == null) {
                    is = parentClassLoader.getResourceAsStream(resourceName);
                }
                if (is != null) {
                    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
                    int nRead;
                    byte[] data = new byte[1024];
                    while ((nRead = is.read(data, 0, data.length)) != -1) {
                        buffer.write(data, 0, nRead);
                    }
                    buffer.flush();
                    ClassFileReader cfr = new ClassFileReader(buffer.toByteArray(), className.toCharArray(), true);
                    return new NameEnvironmentAnswer(cfr, null);
                } else {
                    return null;
                }
            } catch (ClassFormatException | IOException ex) {
                throw new RuntimeException(ex);
            } finally {
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                    }
                }
            }
        }
    };
    ICompilerRequestor requestor = new ICompilerRequestor() {

        @Override
        public void acceptResult(CompilationResult result) {
            if (result.hasErrors()) {
                for (CategorizedProblem problem : result.getProblems()) {
                    if (problem.isError()) {
                        problemList.add(problem.getMessage());
                    }
                }
            } else {
                for (ClassFile clazz : result.getClassFiles()) {
                    try {
                        MemJavaFileObject jfo = (MemJavaFileObject) fileManager.getJavaFileForOutput(StandardLocation.CLASS_OUTPUT, new String(clazz.fileName()), JavaFileObject.Kind.CLASS, null);
                        OutputStream os = jfo.openOutputStream();
                        os.write(clazz.getBytes());
                    } catch (IOException ex) {
                        throw new RuntimeException(ex);
                    }
                }
            }
        }
    };
    problemList.clear();
    IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.exitAfterAllProblems();
    IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault());
    try {
        // Compiler compiler = new Compiler(env, policy, getCompilerOptions(), requestor, problemFactory, true);
        Compiler compiler = new Compiler(env, policy, compilerOptions, requestor, problemFactory);
        compiler.compile(targetCompilationUnits);
        if (!problemList.isEmpty()) {
            StringBuilder sb = new StringBuilder();
            for (String problem : problemList) {
                sb.append("\t").append(problem).append("\n");
            }
            throw new CodegenException("Compilation of " + id + " failed:\n" + source + "\n" + sb.toString());
        }
    } catch (RuntimeException ex) {
        // if we encountered an IOException, unbox and throw it;
        // if we encountered a ClassFormatException, box it as an IOException and throw it
        // otherwise, it's a legit RuntimeException,
        // not one of our checked exceptions boxed as unchecked; just rethrow
        Throwable cause = ex.getCause();
        if (cause != null) {
            if (cause instanceof IOException) {
                throw (IOException) cause;
            } else if (cause instanceof ClassFormatException) {
                throw new IOException(cause);
            }
        }
        throw ex;
    }
}
Also used : NameEnvironmentAnswer(org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer) ClassFileReader(org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OutputStream(java.io.OutputStream) ArrayList(java.util.ArrayList) ClassFormatException(org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException) INameEnvironment(org.eclipse.jdt.internal.compiler.env.INameEnvironment) DefaultProblemFactory(org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory) ICompilationUnit(org.eclipse.jdt.internal.compiler.env.ICompilationUnit) Compiler(org.eclipse.jdt.internal.compiler.Compiler) InputStream(java.io.InputStream) IOException(java.io.IOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) CategorizedProblem(org.eclipse.jdt.core.compiler.CategorizedProblem) StringTokenizer(java.util.StringTokenizer)

Aggregations

ClassFileReader (org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader)6 ClassFormatException (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException)6 IOException (java.io.IOException)5 ICompilationUnit (org.eclipse.jdt.internal.compiler.env.ICompilationUnit)5 NameEnvironmentAnswer (org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer)5 ByteArrayOutputStream (java.io.ByteArrayOutputStream)4 InputStream (java.io.InputStream)4 ArrayList (java.util.ArrayList)4 Compiler (org.eclipse.jdt.internal.compiler.Compiler)4 INameEnvironment (org.eclipse.jdt.internal.compiler.env.INameEnvironment)4 DefaultProblemFactory (org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory)4 StringTokenizer (java.util.StringTokenizer)3 IProblem (org.eclipse.jdt.core.compiler.IProblem)3 ClassFile (org.eclipse.jdt.internal.compiler.ClassFile)3 ICompilerRequestor (org.eclipse.jdt.internal.compiler.ICompilerRequestor)3 IErrorHandlingPolicy (org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy)3 IProblemFactory (org.eclipse.jdt.internal.compiler.IProblemFactory)3 CompilerOptions (org.eclipse.jdt.internal.compiler.impl.CompilerOptions)3 File (java.io.File)2 Collection (java.util.Collection)2