From 8fbedc29f3dccd49c02a51f53adcb6cc792b9637 Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 5 Feb 2019 13:12:58 +0300 Subject: [PATCH] tests: move InMemoryCompiler to intellij.java.testFramework module so it can be reused in other tests --- .../compiler/JavaInMemoryCompiler.java | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 java/testFramework/src/com/intellij/compiler/JavaInMemoryCompiler.java diff --git a/java/testFramework/src/com/intellij/compiler/JavaInMemoryCompiler.java b/java/testFramework/src/com/intellij/compiler/JavaInMemoryCompiler.java new file mode 100644 index 000000000000..442d2a12c2f0 --- /dev/null +++ b/java/testFramework/src/com/intellij/compiler/JavaInMemoryCompiler.java @@ -0,0 +1,115 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.compiler; + +import org.intellij.lang.annotations.Language; + +import javax.tools.*; +import java.io.*; +import java.net.URI; +import java.util.*; + +/** + * @author Bas Leijdekkers + */ +public class JavaInMemoryCompiler { + + @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") + private final JavaMemFileManager myFileManager = new JavaMemFileManager(); + private final JavaCompiler myCompiler = ToolProvider.getSystemJavaCompiler(); + + public Map compile(String className, @Language("JAVA") String code) { + final DiagnosticCollector diagnostics = new DiagnosticCollector<>(); + final Iterable compilationUnits = Collections.singletonList(new JavaSourceFromString(className, code)); + final Iterable options = Arrays.asList("-g"); // generate debugging info. + @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") + final OutputStreamWriter out = new OutputStreamWriter(System.err); + final Boolean success = myCompiler.getTask(out, myFileManager, diagnostics, options, null, compilationUnits).call(); + + if (!success.booleanValue()) { + final StringWriter writer = new StringWriter(); + for (Diagnostic diagnostic : diagnostics.getDiagnostics()) { + writer.write(diagnostic.getMessage(Locale.ENGLISH)); + writer.write(" on line " + diagnostic.getLineNumber()); + writer.write("\n"); + } + throw new RuntimeException(writer.toString()); + } + final List classFiles = myFileManager.getClassFiles(); + final Map result = new HashMap<>(2); + for (InMemoryClassFile classFile : classFiles) { + result.put(classFile.getClassName(), classFile.getBytes()); + } + return result; + } + + public static class JavaSourceFromString extends SimpleJavaFileObject { + + final String myCode; + + JavaSourceFromString(String className, String code) { + super(URI.create("string:///" + className.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE); + this.myCode = code; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return myCode; + } + } + + public static class InMemoryClassFile extends SimpleJavaFileObject { + + private final String myClassName; + ByteArrayOutputStream myOutputStream = new ByteArrayOutputStream(); + + public InMemoryClassFile(String className) { + super(URI.create("class:///" + className.replace('.', '/') + ".class"), Kind.CLASS); + myClassName = className; + } + + public String getClassName() { + return myClassName; + } + + public byte[] getBytes() { + return myOutputStream.toByteArray(); + } + + @Override + public OutputStream openOutputStream() { + myOutputStream.reset(); + return myOutputStream; + } + } + + public static class JavaMemFileManager extends ForwardingJavaFileManager { + + private final List myClassFiles = new ArrayList<>(2); + + public JavaMemFileManager() { + super(ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null)); + } + + @Override + public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) + throws IOException { + if (StandardLocation.CLASS_OUTPUT == location && JavaFileObject.Kind.CLASS == kind) { + final InMemoryClassFile file = new InMemoryClassFile(className); + myClassFiles.add(file); + return file; + } + else { + return super.getJavaFileForOutput(location, className, kind, sibling); + } + } + + public List getClassFiles() { + return myClassFiles; + } + + @Override + public ClassLoader getClassLoader(Location location) { + return null; + } + } +} \ No newline at end of file