mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-07-04 14:40:53 +00:00
[imp-AddKotlinDynamicCompiler] add kotlin compiler (#4544)
This commit is contained in:
parent
b0d6110686
commit
f434b5fa13
@ -200,6 +200,7 @@
|
|||||||
<generex-version>1.0.2</generex-version>
|
<generex-version>1.0.2</generex-version>
|
||||||
<jackson-version>2.9.10</jackson-version>
|
<jackson-version>2.9.10</jackson-version>
|
||||||
<jackson-threetenbp-version>2.9.10</jackson-threetenbp-version>
|
<jackson-threetenbp-version>2.9.10</jackson-threetenbp-version>
|
||||||
|
<kotlin-version>1.3.41</kotlin-version>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -328,6 +329,24 @@
|
|||||||
<artifactId>openapi-generator-core</artifactId>
|
<artifactId>openapi-generator-core</artifactId>
|
||||||
<version>${project.parent.version}</version>
|
<version>${project.parent.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||||
|
<version>${kotlin-version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-compiler-embeddable</artifactId>
|
||||||
|
<version>${kotlin-version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-script-util</artifactId>
|
||||||
|
<version>${kotlin-version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
|
@ -0,0 +1,104 @@
|
|||||||
|
package org.openapitools.codegen.kotlin;
|
||||||
|
|
||||||
|
import kotlin.script.experimental.jvm.util.KotlinJars;
|
||||||
|
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys;
|
||||||
|
import org.jetbrains.kotlin.cli.common.config.ContentRootsKt;
|
||||||
|
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer;
|
||||||
|
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector;
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler;
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.config.JvmContentRootsKt;
|
||||||
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
|
import org.jetbrains.kotlin.com.intellij.openapi.Disposable;
|
||||||
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys;
|
||||||
|
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||||
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys;
|
||||||
|
import org.jetbrains.kotlin.config.JvmTarget;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static kotlin.script.experimental.jvm.util.JvmClasspathUtilKt.classpathFromClassloader;
|
||||||
|
|
||||||
|
public class KotlinTestUtils {
|
||||||
|
|
||||||
|
public static ClassLoader buildModule(List<String> sourcePath, ClassLoader classLoader) {
|
||||||
|
|
||||||
|
String moduleName = UUID.randomUUID().toString().replaceAll("-", "");
|
||||||
|
File saveClassesDir;
|
||||||
|
try {
|
||||||
|
saveClassesDir = Files.createTempDirectory("kotlin" + moduleName).toFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
compileModule(moduleName, sourcePath, saveClassesDir, classLoader, true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new URLClassLoader(new URL[]{saveClassesDir.toURI().toURL()}, classLoader);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GenerationState compileModule(String moduleName, List<String> sourcePath, File saveClassesDir, ClassLoader classLoader, boolean forcedAddKotlinStd) {
|
||||||
|
Disposable stubDisposable = new StubDisposable();
|
||||||
|
CompilerConfiguration configuration = new CompilerConfiguration();
|
||||||
|
configuration.put(CommonConfigurationKeys.MODULE_NAME, moduleName);
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
PrintStream ps = null;
|
||||||
|
try {
|
||||||
|
ps = new PrintStream(baos, true, "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, new PrintingMessageCollector(ps, MessageRenderer.PLAIN_FULL_PATHS, true));
|
||||||
|
configuration.put(JVMConfigurationKeys.OUTPUT_DIRECTORY, saveClassesDir);
|
||||||
|
// configuration.put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true)
|
||||||
|
configuration.put(JVMConfigurationKeys.JVM_TARGET, JvmTarget.JVM_1_8);
|
||||||
|
Set<File> classPath = new HashSet<>();
|
||||||
|
if (classLoader != null) {
|
||||||
|
classPath.addAll(classpathFromClassloader(classLoader, false));
|
||||||
|
}
|
||||||
|
if (forcedAddKotlinStd) {
|
||||||
|
classPath.add(KotlinJars.INSTANCE.getStdlib());
|
||||||
|
}
|
||||||
|
JvmContentRootsKt.addJvmClasspathRoots(configuration, new ArrayList<>(classPath));
|
||||||
|
ContentRootsKt.addKotlinSourceRoots(configuration, sourcePath);
|
||||||
|
|
||||||
|
KotlinCoreEnvironment env = KotlinCoreEnvironment.createForProduction(stubDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES);
|
||||||
|
GenerationState result = KotlinToJVMBytecodeCompiler.INSTANCE.analyzeAndGenerate(env);
|
||||||
|
ps.flush();
|
||||||
|
if (result != null) {
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
String s;
|
||||||
|
try {
|
||||||
|
s = new String(baos.toByteArray(), "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Compilation error. Details:\n" + s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class StubDisposable implements Disposable {
|
||||||
|
|
||||||
|
volatile boolean isDisposed = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
isDisposed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDisposed() {
|
||||||
|
return isDisposed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package org.openapitools.codegen.kotlin;
|
||||||
|
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
public class KotlinTestUtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNormalCompile() throws Exception {
|
||||||
|
ClassLoader classLoader = KotlinTestUtils.buildModule(Collections.singletonList(getClass().getResource("KotlinTestUtilsTest/normalPack").getFile()), Thread.currentThread().getContextClassLoader());
|
||||||
|
Class<?> clazz = classLoader.loadClass("com.example.SimpleClass");
|
||||||
|
Constructor<?>[] constructors = clazz.getConstructors();
|
||||||
|
Assert.assertEquals(1, constructors.length);
|
||||||
|
Constructor<?> constr = constructors[0];
|
||||||
|
Object testObj = constr.newInstance("test");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = Exception.class)
|
||||||
|
public void testBadCompile() {
|
||||||
|
KotlinTestUtils.buildModule(Collections.singletonList(getClass().getResource("KotlinTestUtilsTest/badPack").getFile()), Thread.currentThread().getContextClassLoader());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.example
|
||||||
|
|
||||||
|
|
||||||
|
class SimpleClass {
|
||||||
|
fun void testFun(){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.example
|
||||||
|
|
||||||
|
class SimpleClass (val someStr:String) {
|
||||||
|
fun testFun(str: String) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user