New module script DSL

This commit is contained in:
Maxim Shafirov
2012-01-16 20:59:06 +04:00
parent fb463da84b
commit d51c030803
7 changed files with 47 additions and 90 deletions
@@ -7,9 +7,8 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function; import com.intellij.util.Function;
import com.intellij.util.Processor; import com.intellij.util.Processor;
import jet.ExtensionFunction0; import jet.modules.AllModules;
import jet.modules.IModuleBuilder; import jet.modules.Module;
import jet.modules.IModuleSetBuilder;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.ClassFileFactory; import org.jetbrains.jet.codegen.ClassFileFactory;
import org.jetbrains.jet.codegen.GeneratedClassLoader; import org.jetbrains.jet.codegen.GeneratedClassLoader;
@@ -19,7 +18,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.plugin.JetMainDetector; import org.jetbrains.jet.plugin.JetMainDetector;
import java.io.*; import java.io.*;
import java.lang.reflect.Field; import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.List; import java.util.List;
@@ -174,13 +173,14 @@ public class CompileEnvironment {
e.printStackTrace(); e.printStackTrace();
} }
final IModuleSetBuilder moduleSetBuilder = loadModuleScript(moduleFile); final List<Module> modules = loadModuleScript(moduleFile);
if (moduleSetBuilder == null) {
return; if (modules == null) {
throw new CompileEnvironmentException("Module script " + moduleFile + " compilation failed");
} }
final String directory = new File(moduleFile).getParent(); final String directory = new File(moduleFile).getParent();
for (IModuleBuilder moduleBuilder : moduleSetBuilder.getModules()) { for (Module moduleBuilder : modules) {
ClassFileFactory moduleFactory = compileModule(moduleBuilder, directory); ClassFileFactory moduleFactory = compileModule(moduleBuilder, directory);
final String path = jarPath != null ? jarPath : new File(directory, moduleBuilder.getModuleName() + ".jar").getPath(); final String path = jarPath != null ? jarPath : new File(directory, moduleBuilder.getModuleName() + ".jar").getPath();
try { try {
@@ -191,7 +191,7 @@ public class CompileEnvironment {
} }
} }
public IModuleSetBuilder loadModuleScript(String moduleFile) { public List<Module> loadModuleScript(String moduleFile) {
CompileSession scriptCompileSession = new CompileSession(myEnvironment); CompileSession scriptCompileSession = new CompileSession(myEnvironment);
scriptCompileSession.addSources(moduleFile); scriptCompileSession.addSources(moduleFile);
scriptCompileSession.addStdLibSources(true); scriptCompileSession.addStdLibSources(true);
@@ -204,34 +204,25 @@ public class CompileEnvironment {
return runDefineModules(moduleFile, factory); return runDefineModules(moduleFile, factory);
} }
private static IModuleSetBuilder runDefineModules(String moduleFile, ClassFileFactory factory) { private static List<Module> runDefineModules(String moduleFile, ClassFileFactory factory) {
GeneratedClassLoader loader = new GeneratedClassLoader(factory); GeneratedClassLoader loader = new GeneratedClassLoader(factory);
try { try {
Class moduleSetBuilderClass = loader.loadClass("kotlin.modules.ModuleSetBuilder");
final IModuleSetBuilder moduleSetBuilder = (IModuleSetBuilder) moduleSetBuilderClass.newInstance();
Class namespaceClass = loader.loadClass(JvmAbi.PACKAGE_CLASS); Class namespaceClass = loader.loadClass(JvmAbi.PACKAGE_CLASS);
final Field[] fields = namespaceClass.getDeclaredFields(); final Method method = namespaceClass.getDeclaredMethod("project");
boolean modulesDefined = false; if (method == null) {
for (Field field : fields) { throw new CompileEnvironmentException("Module script " + moduleFile + " must define project() function");
if (field.getName().equals("modules")) {
field.setAccessible(true);
ExtensionFunction0 defineMudules = (ExtensionFunction0) field.get(null);
defineMudules.invoke(moduleSetBuilder);
modulesDefined = true;
break;
}
} }
if (!modulesDefined) {
throw new CompileEnvironmentException("Module script " + moduleFile + " must define a modules() property"); method.setAccessible(true);
} method.invoke(null);
return moduleSetBuilder;
return AllModules.modules;
} catch (Exception e) { } catch (Exception e) {
throw new CompileEnvironmentException(e); throw new CompileEnvironmentException(e);
} }
} }
public ClassFileFactory compileModule(IModuleBuilder moduleBuilder, String directory) { public ClassFileFactory compileModule(Module moduleBuilder, String directory) {
CompileSession moduleCompileSession = new CompileSession(myEnvironment); CompileSession moduleCompileSession = new CompileSession(myEnvironment);
if (!"stdlib".equals(moduleBuilder.getModuleName())) { if (!"stdlib".equals(moduleBuilder.getModuleName())) {
moduleCompileSession.addStdLibSources(false); moduleCompileSession.addStdLibSources(false);
+4 -3
View File
@@ -1,6 +1,7 @@
import kotlin.modules.* import kotlin.modules.*
val modules = module("smoke") { fun project() {
source files "Smoke.kt" module("smoke") {
jar name System.getProperty("java.io.tmpdir") + "/smoke.jar" sources += "Smoke.kt"
}
} }
@@ -1,7 +1,6 @@
package org.jetbrains.jet.compiler; package org.jetbrains.jet.compiler;
import jet.modules.IModuleBuilder; import jet.modules.Module;
import jet.modules.IModuleSetBuilder;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.jetbrains.jet.cli.KotlinCompiler; import org.jetbrains.jet.cli.KotlinCompiler;
import org.jetbrains.jet.codegen.ClassFileFactory; import org.jetbrains.jet.codegen.ClassFileFactory;
@@ -37,9 +36,9 @@ public class CompileEnvironmentTest extends TestCase {
environment.setJavaRuntime(activeRtJar); environment.setJavaRuntime(activeRtJar);
environment.initializeKotlinRuntime(); environment.initializeKotlinRuntime();
final String testDataDir = JetParsingTest.getTestDataDir() + "/compiler/smoke/"; final String testDataDir = JetParsingTest.getTestDataDir() + "/compiler/smoke/";
final IModuleSetBuilder setBuilder = environment.loadModuleScript(testDataDir + "Smoke.kts"); final List<Module> modules = environment.loadModuleScript(testDataDir + "Smoke.kts");
assertEquals(1, setBuilder.getModules().size()); assertEquals(1, modules.size());
final IModuleBuilder moduleBuilder = setBuilder.getModules().get(0); final Module moduleBuilder = modules.get(0);
final ClassFileFactory factory = environment.compileModule(moduleBuilder, testDataDir); final ClassFileFactory factory = environment.compileModule(moduleBuilder, testDataDir);
assertNotNull(factory); assertNotNull(factory);
assertNotNull(factory.asBytes("Smoke/namespace.class")); assertNotNull(factory.asBytes("Smoke/namespace.class"));
@@ -51,7 +50,7 @@ public class CompileEnvironmentTest extends TestCase {
assertTrue(entries.contains("Smoke/namespace.class")); assertTrue(entries.contains("Smoke/namespace.class"));
} }
public void _testSmokeWithCompilerJar() throws IOException { public void testSmokeWithCompilerJar() throws IOException {
File tempFile = File.createTempFile("compilerTest", "compilerTest"); File tempFile = File.createTempFile("compilerTest", "compilerTest");
try { try {
KotlinCompiler.main(Arrays.asList("-module", JetParsingTest.getTestDataDir() + "/compiler/smoke/Smoke.kts", "-jar", tempFile.getAbsolutePath()).toArray(new String[0])); KotlinCompiler.main(Arrays.asList("-module", JetParsingTest.getTestDataDir() + "/compiler/smoke/Smoke.kts", "-jar", tempFile.getAbsolutePath()).toArray(new String[0]));
+8 -41
View File
@@ -3,57 +3,35 @@ package kotlin.modules
import java.util.* import java.util.*
import jet.modules.* import jet.modules.*
fun moduleSet(description: ModuleSetBuilder.() -> Unit) = description fun module(name: String, callback: ModuleBuilder.() -> Unit) {
val builder = ModuleBuilder(name)
fun module(name: String, description: ModuleBuilder.() -> Unit) = moduleSet { builder.callback()
module(name, description) AllModules.modules?.add(builder)
}
class ModuleSetBuilder(): IModuleSetBuilder {
private val modules = ArrayList<IModuleBuilder?>()
fun module(name: String, callback: ModuleBuilder.() -> Unit) {
val builder = ModuleBuilder(name)
builder.callback()
modules.add(builder)
}
override fun getModules(): List<IModuleBuilder?>? = modules
} }
class SourcesBuilder(val parent: ModuleBuilder) { class SourcesBuilder(val parent: ModuleBuilder) {
fun files(pattern: String) { fun plusAssign(pattern: String) {
parent.addSourceFiles(pattern) parent.addSourceFiles(pattern)
} }
} }
class ClasspathBuilder(val parent: ModuleBuilder) { class ClasspathBuilder(val parent: ModuleBuilder) {
fun entry(name: String) { fun plusAssign(name: String) {
parent.addClasspathEntry(name) parent.addClasspathEntry(name)
} }
} }
class JarBuilder(val parent: ModuleBuilder) { open class ModuleBuilder(val name: String): Module {
fun name(jarName: String) {
parent.setJarName(jarName)
}
}
open class ModuleBuilder(val name: String): IModuleBuilder {
// http://youtrack.jetbrains.net/issue/KT-904 // http://youtrack.jetbrains.net/issue/KT-904
private val sourceFiles0: ArrayList<String?> = ArrayList<String?>() private val sourceFiles0: ArrayList<String?> = ArrayList<String?>()
private val classpathRoots0: ArrayList<String?> = ArrayList<String?>() private val classpathRoots0: ArrayList<String?> = ArrayList<String?>()
var _jarName: String? = null
val source: SourcesBuilder val sources: SourcesBuilder
get() = SourcesBuilder(this) get() = SourcesBuilder(this)
val classpath: ClasspathBuilder val classpath: ClasspathBuilder
get() = ClasspathBuilder(this) get() = ClasspathBuilder(this)
val jar: JarBuilder
get() = JarBuilder(this)
fun addSourceFiles(pattern: String) { fun addSourceFiles(pattern: String) {
sourceFiles0.add(pattern) sourceFiles0.add(pattern)
} }
@@ -62,19 +40,8 @@ open class ModuleBuilder(val name: String): IModuleBuilder {
classpathRoots0.add(name) classpathRoots0.add(name)
} }
fun setJarName(name: String) {
_jarName = name
}
override fun getSourceFiles(): List<String?>? = sourceFiles0 override fun getSourceFiles(): List<String?>? = sourceFiles0
override fun getClasspathRoots(): List<String?>? = classpathRoots0 override fun getClasspathRoots(): List<String?>? = classpathRoots0
override fun getModuleName(): String? = name override fun getModuleName(): String? = name
override fun getJarName(): String? = _jarName
}
class ModuleBuilder2(name: String): ModuleBuilder(name) {
} }
+10
View File
@@ -0,0 +1,10 @@
/*
* @author max
*/
package jet.modules;
import java.util.ArrayList;
public class AllModules {
public static final ArrayList<Module> modules = new ArrayList<Module>();
}
@@ -1,10 +0,0 @@
package jet.modules;
import java.util.List;
/**
* @author yole
*/
public interface IModuleSetBuilder {
List<IModuleBuilder> getModules();
}
@@ -5,9 +5,8 @@ import java.util.List;
/** /**
* @author yole * @author yole
*/ */
public interface IModuleBuilder { public interface Module {
String getModuleName(); String getModuleName();
List<String> getSourceFiles(); List<String> getSourceFiles();
List<String> getClasspathRoots(); List<String> getClasspathRoots();
String getJarName();
} }