2017-08-25 15 views
8

Şimdiye kadar bu el derleyici başlar ama önce derleyici kaynaklanan Dize derlemek bellek (KOTLIN kaynağını oluşturur MyProjectCompiler) gibi ve bir karşı yazmadan sonucunu kontrol ediyorumBellekte bir kotlin dosyası derleyen testleri nasıl çalıştırırım ve sonucu kontrol edeyim?

import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler 

    MyProjectCompiler.initialize("SampleKtFileOutput") 
    .packageName("com.test.sample") 
    .compile(File(someFile.path)) 
    .result { ktSource: String -> K2JVMCompiler() 
     .exec(System.out, /** arguments here?*/) } 

var dosya.

Mümkünse mevcut sınıf yoluna her şeyi dahil etmek isterim.

cevap

1

Bunu yapmanın en kolay yolu, orijinal sorudaki kod gibi bir şey kullanmak ve java.io.tmpdir'u kullanmaktır.

bir test bağımlılığı KOTLIN derleyiciniz:

testCompile group: 'org.jetbrains.kotlin', name: 'kotlin-compiler', version: "$kotlin_version" 

Sarıcısını derleyici:

object JvmCompile { 

    fun exe(input: File, output: File): Boolean = K2JVMCompiler().run { 
    val args = K2JVMCompilerArguments().apply { 
     freeArgs = listOf(input.absolutePath) 
     loadBuiltInsFromDependencies = true 
     destination = output.absolutePath 
     classpath = System.getProperty("java.class.path") 
      .split(System.getProperty("path.separator")) 
      .filter { 
      it.asFile().exists() && it.asFile().canRead() 
      }.joinToString(":") 
     noStdlib = true 
     noReflect = true 
     skipRuntimeVersionCheck = true 
     reportPerf = true 
    } 
    output.deleteOnExit() 
    execImpl(
     PrintingMessageCollector(
      System.out, 
      MessageRenderer.WITHOUT_PATHS, true), 
     Services.EMPTY, 
     args) 
    }.code == 0 

} 

ClassLoader derlenmiş sınıflardan nesneler oluşturmak için: Burada yeniden kullanılabilir bir çözüm

class Initializer(private val root: File) { 

    val loader = URLClassLoader(
     listOf(root.toURI().toURL()).toTypedArray(), 
     this::class.java.classLoader) 

    @Suppress("UNCHECKED_CAST") 
    inline fun <reified T> loadCompiledObject(clazzName: String): T? 
     = loader.loadClass(clazzName).kotlin.objectInstance as T 

    @Suppress("UNCHECKED_CAST") 
    inline fun <reified T> createInstance(clazzName: String): T? 
     = loader.loadClass(clazzName).kotlin.createInstance() as T 

} 

Örnek deneme durumu:

Önce bir KOTLIN kaynak dosyası yapmak

MockClasswriter(""" 
    | 
    |package com.test 
    | 
    |class Example : Consumer<String> { 
    | override fun accept(value: String) { 
    | println("found: '$\value'") 
    | } 
    |} 
    """.trimMargin("|")) 
    .writeToFile(codegenOutputFile) 

emin ol derler:

assertTrue(JvmCompile.exe(codegenOutputFile, compileOutputDir)) 

Yük arayüzü örneği olarak sınıf

Initializer(compileOutputDir) 
     .createInstance<Consumer<String>>("com.test.Example") 
     ?.accept("Hello, world!") 

çıkış beklenecektir olarak: found: 'Hello, world!'

0

K2JVMCompiler sınıfının kaynağını okurken, derleyici yalnızca dosyalar için derlemeyi destekliyor gibi görünüyor. Daha derin kazma, org.jetbrains.kotlin.codegen.KotlinCodegenFacade statik yöntem compileCorrectFiles girişlerini sahte olarak aşırı görünüyor.

Bunu yapmak için bir dosya sistemi kullanmayı tahmin et. Geçici bir RAM diski ihtiyaçlarınızı karşılayabilir. (Bu yerleşik makrolar for example)

+0

th kullanımı için herhangi bir yolu var mı e JSR 223 API bunu yapmak için mi? Ben çok aşina değilim ben –

+0

JSR 223 sadece uygulama için komut dosyası oluşturma yeteneği ekleyecektir, uygulamanızı ayarlamak daha kolay olacak, ancak RAM sürücüler veya RAM derleme ile size yardımcı olmaz. – Xvolks

+0

REPL'nin neyle çalıştığı sorun değil, değil mi? Bunu teker teker derlediğim her tür tanımlamak için kullanmak ve sonra sadece bu şekilde test etmek mümkün mü? Ben kotlin kaynağından oldum ama REPL programatik olarak –

İlgili konular