2017-08-25 12 views
8

अब तक मैंमैं स्मृति में कोटलिन फ़ाइल को संकलित करने के परीक्षण कैसे चला सकता हूं और परिणाम जांच सकता हूं?

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?*/) } 

है यह मैन्युअल रूप से संकलक शुरू होता है, लेकिन मैं पहले संकलक से उत्पन्न स्ट्रिंग संकलित करने के लिए चाहते हैं में स्मृति (MyProjectCompiler जो kotlin स्रोत उत्पन्न करता है) और एक के लिए लिख बिना परिणाम की जाँच फ़ाइल।

यदि संभव हो तो मैं वर्तमान क्लासपाथ पर सबकुछ शामिल करना चाहता हूं।

उत्तर

1

मुझे मूल प्रश्न में कोड की तरह कुछ उपयोग करने और java.io.tmpdir का उपयोग करने का सबसे आसान तरीका मिल गया है। यहाँ एक फिर से प्रयोग करने योग्य समाधान है: संकलित वर्गों से वस्तुओं बनाने के लिए

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: संकलक के लिए

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

आवरण:

एक परीक्षण निर्भरता के रूप में kotlin संकलक जोड़े

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 

} 

उदाहरण परीक्षण केस:

पहले एक kotlin स्रोत फ़ाइल बनाने

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

सुनिश्चित करें कि यह संकलित:

assertTrue(JvmCompile.exe(codegenOutputFile, compileOutputDir)) 

लोड इंटरफ़ेस उदाहरण के रूप में वर्ग

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

उत्पादन की उम्मीद होगी के रूप में: found: 'Hello, world!'

0

K2JVMCompiler वर्ग के स्रोत को पढ़ना, ऐसा लगता है कि संकलक केवल फ़ाइलों के लिए संकलन का समर्थन करता है। गहराई से खोना, यह org.jetbrains.kotlin.codegen.KotlinCodegenFacade स्थैतिक विधि compileCorrectFiles की प्रविष्टियों को नकली करने के लिए जटिल लगता है।

ऐसा करने के लिए फ़ाइल सिस्टम का उपयोग करने के लिए आपका सबसे अच्छा अनुमान है। एक अस्थायी रैम डिस्क आपकी आवश्यकताओं के अनुरूप हो सकती है। (यह अंतर्निहित मैकोज़ for example)

+0

क्या वें का उपयोग करने का कोई तरीका है ई जेएसआर 223 एपीआई ऐसा करने के लिए? मैं इसके साथ बहुत परिचित नहीं हूं –

+0

जेएसआर 223 आपको अपने एप्लिकेशन में स्क्रिप्टिंग क्षमता जोड़ने देगा, लेकिन आपके एप्लिकेशन को ट्यून करना आसान होगा, लेकिन यह रैम ड्राइव या रैम में संकलन करने में आपकी सहायता नहीं करेगा। – Xvolks

+0

Thats क्या आरपीएल के साथ चलता है, नहीं? प्रत्येक प्रकार को परिभाषित करने के लिए इसका उपयोग करना संभव है जिसे मैं एक-एक करके संकलित करता हूं और फिर उस तरह से परीक्षण करता हूं? मैं कोटलिन स्रोत के माध्यम से रहा हूं लेकिन मैं वास्तव में यह नहीं समझ सकता कि आरईपीएल को प्रोग्रामेटिक रूप से –

संबंधित मुद्दे

 संबंधित मुद्दे