Generate FunctionN and FunctionImplN classes in Kotlin
This commit is contained in:
@@ -1,241 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.generators.runtime;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.utils.ExceptionUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class GenerateFunctions {
|
||||
public static final int MAX_PARAM_COUNT = 22;
|
||||
public static final File JET_SRC_DIR = new File("compiler/frontend/builtins/jet/");
|
||||
public static final File RUNTIME_SRC_DIR = new File("runtime/src/jet/");
|
||||
|
||||
private final PrintWriter out;
|
||||
private final FunctionKind kind;
|
||||
|
||||
private GenerateFunctions(PrintWriter out, FunctionKind kind) {
|
||||
this.out = out;
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
private enum FunctionKind {
|
||||
FUNCTION("Function", false, null),
|
||||
EXTENSION_FUNCTION("ExtensionFunction", true, null),
|
||||
|
||||
K_FUNCTION("KFunction", false, "Function"),
|
||||
K_MEMBER_FUNCTION("KMemberFunction", true, "ExtensionFunction"),
|
||||
K_EXTENSION_FUNCTION("KExtensionFunction", true, "ExtensionFunction");
|
||||
|
||||
private final String classNamePrefix;
|
||||
private final boolean hasReceiverParameter;
|
||||
private final String superClassNamePrefix;
|
||||
|
||||
private FunctionKind(String classNamePrefix, boolean hasReceiverParameter, String superClassNamePrefix) {
|
||||
this.classNamePrefix = classNamePrefix;
|
||||
this.hasReceiverParameter = hasReceiverParameter;
|
||||
this.superClassNamePrefix = superClassNamePrefix;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return classNamePrefix + "s.kt";
|
||||
}
|
||||
|
||||
public String getClassName(int i) {
|
||||
return classNamePrefix + i;
|
||||
}
|
||||
|
||||
public String getImplClassName(int i) {
|
||||
return classNamePrefix + "Impl" + i;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getSuperClassName(int i) {
|
||||
return superClassNamePrefix != null ? superClassNamePrefix + i : null;
|
||||
}
|
||||
}
|
||||
|
||||
private void generateBuiltInFunctions() {
|
||||
generated();
|
||||
for (int i = 0; i <= MAX_PARAM_COUNT; i++) {
|
||||
out.print("public trait " + kind.getClassName(i));
|
||||
generateTypeParameters(i, true);
|
||||
generateSuperClass(i, true);
|
||||
generateFunctionClassBody(i, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateSuperClass(int i, boolean kotlin) {
|
||||
String name = kind.getSuperClassName(i);
|
||||
if (name == null) return;
|
||||
|
||||
out.print(kotlin ? " : " : " extends ");
|
||||
out.print(name);
|
||||
generateTypeParameters(i, false);
|
||||
}
|
||||
|
||||
private void generateFunctionClassBody(int i, boolean kotlin) {
|
||||
switch (kind) {
|
||||
case FUNCTION:
|
||||
case EXTENSION_FUNCTION: {
|
||||
out.println(" {");
|
||||
if (kotlin) {
|
||||
generateKotlinInvokeSignature(i);
|
||||
} else {
|
||||
generateJavaInvokeSignature(i);
|
||||
}
|
||||
out.println("}");
|
||||
break;
|
||||
}
|
||||
|
||||
case K_FUNCTION:
|
||||
case K_MEMBER_FUNCTION:
|
||||
case K_EXTENSION_FUNCTION: {
|
||||
if (kotlin) {
|
||||
out.println();
|
||||
}
|
||||
else {
|
||||
out.println(" {");
|
||||
out.println("}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new IllegalStateException("Unknown kind: " + kind);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateKotlinInvokeSignature(int i) {
|
||||
out.print(" public fun " + (kind.hasReceiverParameter ? "T." : "") + "invoke(");
|
||||
for (int j = 1; j <= i; j++) {
|
||||
out.print("p" + j + ": " + "P" + j);
|
||||
if (j < i) {
|
||||
out.print(", ");
|
||||
}
|
||||
}
|
||||
out.println(") : R");
|
||||
}
|
||||
|
||||
private void generateRuntimeFunction(int i) {
|
||||
generateRuntimeClassHeader();
|
||||
|
||||
out.println("import org.jetbrains.jet.rt.annotation.AssertInvisibleInResolver;");
|
||||
out.println();
|
||||
out.println("@AssertInvisibleInResolver");
|
||||
|
||||
out.print("public interface " + kind.getClassName(i));
|
||||
generateTypeParameters(i, false);
|
||||
generateSuperClass(i, false);
|
||||
generateFunctionClassBody(i, false);
|
||||
}
|
||||
|
||||
private void generateJavaInvokeSignature(int i) {
|
||||
out.print(" R invoke(");
|
||||
if (kind.hasReceiverParameter) {
|
||||
out.print("T receiver");
|
||||
if (i > 0) {
|
||||
out.print(", ");
|
||||
}
|
||||
}
|
||||
for (int j = 1; j <= i; j++) {
|
||||
out.print("P" + j + " p" + j);
|
||||
if (j < i) {
|
||||
out.print(", ");
|
||||
}
|
||||
}
|
||||
out.println(");");
|
||||
}
|
||||
|
||||
private void generateTypeParameters(int i, boolean kotlinVariance) {
|
||||
out.print("<");
|
||||
if (kind.hasReceiverParameter) {
|
||||
if (kotlinVariance) out.print("in ");
|
||||
out.print("T, ");
|
||||
}
|
||||
for (int j = 1; j <= i; j++) {
|
||||
if (kotlinVariance) out.print("in ");
|
||||
out.print("P" + j + ", ");
|
||||
}
|
||||
if (kotlinVariance) out.print("out ");
|
||||
out.print("R>");
|
||||
}
|
||||
|
||||
private void generateRuntimeFunctionImpl(int i) {
|
||||
generateRuntimeClassHeader();
|
||||
|
||||
out.print("public abstract class " + kind.getImplClassName(i));
|
||||
generateTypeParameters(i, false);
|
||||
out.print(" extends DefaultJetObject");
|
||||
out.print(" implements " + kind.getClassName(i));
|
||||
generateTypeParameters(i, false);
|
||||
out.println(" {");
|
||||
generateToStringForFunctionImpl();
|
||||
out.println("}");
|
||||
}
|
||||
|
||||
private void generateToStringForFunctionImpl() {
|
||||
out.println(" @Override");
|
||||
out.println(" public String toString() {");
|
||||
out.println(" return getClass().getGenericSuperclass().toString();");
|
||||
out.println(" }");
|
||||
}
|
||||
|
||||
private void generateRuntimeClassHeader() {
|
||||
try {
|
||||
out.println(FileUtil.loadFile(new File("injector-generator/copyright.txt")));
|
||||
}
|
||||
catch (IOException e) {
|
||||
ExceptionUtils.rethrow(e);
|
||||
}
|
||||
out.println("package jet;");
|
||||
out.println();
|
||||
}
|
||||
|
||||
private void generated() {
|
||||
out.println("// Generated by " + GenerateFunctions.class.getName());
|
||||
out.println();
|
||||
out.println("package jet");
|
||||
out.println();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws FileNotFoundException {
|
||||
assert JET_SRC_DIR.exists() : "jet.* src dir does not exist: " + JET_SRC_DIR.getAbsolutePath();
|
||||
assert RUNTIME_SRC_DIR.exists() : "Runtime src dir does not exist: " + RUNTIME_SRC_DIR.getAbsolutePath();
|
||||
|
||||
for (FunctionKind kind : FunctionKind.values()) {
|
||||
PrintWriter functions = new PrintWriter(new File(JET_SRC_DIR, kind.getFileName()));
|
||||
new GenerateFunctions(functions, kind).generateBuiltInFunctions();
|
||||
functions.close();
|
||||
|
||||
for (int i = 0; i <= MAX_PARAM_COUNT; i++) {
|
||||
PrintWriter function = new PrintWriter(new File(RUNTIME_SRC_DIR, kind.getClassName(i) + ".java"));
|
||||
new GenerateFunctions(function, kind).generateRuntimeFunction(i);
|
||||
function.close();
|
||||
|
||||
PrintWriter functionImpl = new PrintWriter(new File(RUNTIME_SRC_DIR, kind.getImplClassName(i) + ".java"));
|
||||
new GenerateFunctions(functionImpl, kind).generateRuntimeFunctionImpl(i);
|
||||
functionImpl.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.generators.runtime
|
||||
|
||||
import java.io.File
|
||||
import kotlin.properties.Delegates
|
||||
import java.io.PrintWriter
|
||||
|
||||
val OUTPUT_DIR: File by Delegates.lazy {
|
||||
val result = File("runtime/kt/")
|
||||
if (!result.exists()) {
|
||||
throw IllegalStateException("Output dir does not exist: ${result.getAbsolutePath()}")
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fun generateRuntimeFile(name: String, generate: (PrintWriter) -> Unit) {
|
||||
val file = File(OUTPUT_DIR, name)
|
||||
println("generating $file")
|
||||
PrintWriter(file) use generate
|
||||
}
|
||||
|
||||
fun generatedBy(out: PrintWriter, generator: String) {
|
||||
out.println("// Generated by $generator")
|
||||
out.println()
|
||||
out.println("package jet")
|
||||
out.println()
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.generators.runtime.functions
|
||||
|
||||
import java.io.PrintWriter
|
||||
import org.jetbrains.jet.generators.runtime.functions.FunctionKind.*
|
||||
import org.jetbrains.jet.generators.runtime.*
|
||||
|
||||
val MAX_PARAM_COUNT = 22
|
||||
|
||||
enum class FunctionKind(
|
||||
private val classNamePrefix: String,
|
||||
val hasReceiverParameter: Boolean,
|
||||
private val superClassNamePrefix: String?
|
||||
) {
|
||||
FUNCTION : FunctionKind("Function", false, null)
|
||||
EXTENSION_FUNCTION : FunctionKind("ExtensionFunction", true, null)
|
||||
K_FUNCTION : FunctionKind("KFunction", false, "Function")
|
||||
K_MEMBER_FUNCTION : FunctionKind("KMemberFunction", true, "ExtensionFunction")
|
||||
K_EXTENSION_FUNCTION : FunctionKind("KExtensionFunction", true, "ExtensionFunction")
|
||||
|
||||
fun getFileName() = classNamePrefix + "s.kt"
|
||||
fun getImplFileName() = classNamePrefix + "sImpl.kt"
|
||||
fun getClassName(i: Int) = classNamePrefix + i
|
||||
fun getImplClassName(i: Int) = classNamePrefix + "Impl" + i
|
||||
fun getSuperClassName(i: Int) = superClassNamePrefix?.plus(i)
|
||||
}
|
||||
|
||||
class GenerateFunctions(val out: PrintWriter, val kind: FunctionKind) {
|
||||
fun generateFunctionClasses() {
|
||||
generatedBy(out, javaClass.getName())
|
||||
for (i in 0..MAX_PARAM_COUNT) {
|
||||
out.print("public trait " + kind.getClassName(i))
|
||||
generateTypeParameters(i, true)
|
||||
generateSuperClass(i)
|
||||
generateFunctionClassBody(i)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateFunctionImplClasses() {
|
||||
generatedBy(out, javaClass.getName())
|
||||
for (i in 0..MAX_PARAM_COUNT) {
|
||||
out.print("public abstract class " + kind.getImplClassName(i))
|
||||
generateTypeParameters(i, true)
|
||||
out.print(" : ")
|
||||
out.print(kind.getClassName(i))
|
||||
generateTypeParameters(i, false)
|
||||
out.println(", DefaultJetObject() {")
|
||||
generateToStringForFunctionImpl()
|
||||
out.println("}")
|
||||
}
|
||||
}
|
||||
|
||||
fun generateSuperClass(i: Int) {
|
||||
val superClass = kind.getSuperClassName(i)
|
||||
if (superClass != null) {
|
||||
out.print(" : $superClass")
|
||||
generateTypeParameters(i, false)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateFunctionClassBody(i: Int): Unit = when (kind) {
|
||||
FUNCTION, EXTENSION_FUNCTION -> {
|
||||
out.println(" {")
|
||||
generateInvokeSignature(i)
|
||||
out.println("}")
|
||||
}
|
||||
K_FUNCTION, K_MEMBER_FUNCTION, K_EXTENSION_FUNCTION -> {
|
||||
out.println()
|
||||
}
|
||||
else -> {
|
||||
throw IllegalStateException("Unknown kind: " + kind)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateInvokeSignature(i: Int) {
|
||||
out.print(" public fun ${if (kind.hasReceiverParameter) "T." else ""}invoke(")
|
||||
for (j in 1..i) {
|
||||
out.print("p$j: P$j")
|
||||
if (j < i) {
|
||||
out.print(", ")
|
||||
}
|
||||
}
|
||||
out.println("): R")
|
||||
}
|
||||
|
||||
fun generateTypeParameters(i: Int, variance: Boolean) {
|
||||
out.print("<")
|
||||
if (kind.hasReceiverParameter) {
|
||||
if (variance) out.print("in ")
|
||||
out.print("T, ")
|
||||
}
|
||||
|
||||
for (j in 1..i) {
|
||||
if (variance) out.print("in ")
|
||||
out.print("P$j, ")
|
||||
}
|
||||
|
||||
if (variance) out.print("out ")
|
||||
out.print("R>")
|
||||
}
|
||||
|
||||
fun generateToStringForFunctionImpl() {
|
||||
// TODO: don't generate this in every function, create a common superclass for all functions / extension functions
|
||||
out.println(" override fun toString() = \"\${getClass().getGenericSuperclass()}\"")
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
for (kind in FunctionKind.values()) {
|
||||
generateRuntimeFile(kind.getFileName()) {
|
||||
GenerateFunctions(it, kind).generateFunctionClasses()
|
||||
}
|
||||
|
||||
generateRuntimeFile(kind.getImplFileName()) {
|
||||
GenerateFunctions(it, kind).generateFunctionImplClasses()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user