[Editor] Enable JDKCompiler and make it default compiler

This commit is contained in:
2021-03-08 08:49:29 +01:00
parent b259fc1a10
commit cb40c10f99
17 changed files with 135 additions and 50 deletions

View File

@@ -12,8 +12,3 @@ repositories {
dependencies {
implementation "org.joml:joml:${jomlVersion}"
}
task relayDependencies(type: Copy) {
from configurations.runtimeClasspath
into file("build/dependencies")
}

View File

@@ -32,7 +32,9 @@ compileTestKotlin {
}
dependencies {
implementation project(":api")
implementation project(":proto")
implementation "org.jetbrains.kotlin:kotlin-stdlib"
implementation "no.tornado:tornadofx:${tornadoFxVersion}"
implementation platform("org.kordamp.ikonli:ikonli-bom:${ikonliVersion}")
@@ -55,14 +57,15 @@ task provideGameEngine(type: Copy) {
into file("build/resources/main/engine")
}
task provideApiDependencies(type: Copy) {
dependsOn(":api:relayDependencies")
task provideAPIWithDependences(type: Copy) {
dependsOn(":api:build")
from project(':api').file('build/dependencies')
from project(':api').file('build/libs')
from project(':api').configurations.runtimeClasspath
into file("build/resources/main/dependencies")
}
task provideApi(type: Copy) {
task provideAPISources(type: Copy) {
from project(':api').file('src/main/java')
into file('build/resources/main/api')
@@ -81,6 +84,6 @@ task provideApi(type: Copy) {
processResources {
dependsOn(provideGameEngine)
dependsOn(provideApiDependencies)
dependsOn(provideApi)
dependsOn(provideAPIWithDependences)
dependsOn(provideAPISources)
}

View File

@@ -0,0 +1,66 @@
package com.bartlomiejpluta.base.editor.code.build.compiler
import com.bartlomiejpluta.base.editor.code.build.exception.BuildException
import com.bartlomiejpluta.base.editor.common.logs.enumeration.Severity
import com.bartlomiejpluta.base.editor.common.logs.model.Location
import com.bartlomiejpluta.base.editor.event.AppendBuildLogsEvent
import com.bartlomiejpluta.base.editor.file.model.FileSystemNode
import com.bartlomiejpluta.base.editor.file.model.FileType
import org.springframework.context.annotation.Primary
import org.springframework.stereotype.Component
import tornadofx.FX
import java.io.File
import java.util.*
import javax.tools.Diagnostic
import javax.tools.DiagnosticCollector
import javax.tools.JavaFileObject
import javax.tools.ToolProvider
@Primary
@Component
class JDKCompiler : Compiler {
private val compiler = ToolProvider.getSystemJavaCompiler()
override fun compile(sourceDirectory: FileSystemNode, targetDirectory: File, classPath: Array<File>) {
val classpath = classPath.joinToString(";") { it.absolutePath }
val options = listOf("-g", "-d", targetDirectory.absolutePath, "-classpath", classpath)
val collector = DiagnosticCollector<JavaFileObject>()
val manager = compiler.getStandardFileManager(collector, null, null)
val sources = sourceDirectory.allChildren
.filter { it.type == FileType.FILE }
.mapNotNull { it as? FileSystemNode }
.map { it.file }
.let { manager.getJavaFileObjects(*it.toTypedArray()) }
val task = compiler.getTask(null, manager, collector, options, null, sources)
val success = task.call()
collector.diagnostics.forEach(this::fireDiagnosticEvent)
if (!success) {
throw BuildException()
}
}
private fun fireDiagnosticEvent(diagnostic: Diagnostic<out JavaFileObject>) {
val severity = when (diagnostic.kind!!) {
Diagnostic.Kind.ERROR -> Severity.ERROR
Diagnostic.Kind.WARNING -> Severity.WARNING
Diagnostic.Kind.MANDATORY_WARNING -> Severity.WARNING
Diagnostic.Kind.NOTE -> Severity.NOTE
Diagnostic.Kind.OTHER -> Severity.INFO
}
val location = Location(diagnostic.source.name, diagnostic.lineNumber, diagnostic.columnNumber)
FX.eventbus.fire(AppendBuildLogsEvent(severity, diagnostic.getMessage(null), location, TAG))
}
companion object {
private const val TAG = "Compiler"
}
}

View File

@@ -1,16 +1,14 @@
package com.bartlomiejpluta.base.editor.code.build.compiler
import com.bartlomiejpluta.base.editor.code.api.APIProvider
import com.bartlomiejpluta.base.editor.code.build.exception.BuildException
import com.bartlomiejpluta.base.editor.code.build.model.FileNodeResourceAdapter
import com.bartlomiejpluta.base.editor.common.logs.enumeration.Severity
import com.bartlomiejpluta.base.editor.common.logs.model.Location
import com.bartlomiejpluta.base.editor.event.AppendBuildLogsEvent
import com.bartlomiejpluta.base.editor.file.model.FileSystemNode
import com.bartlomiejpluta.base.editor.file.model.FileType
import org.codehaus.commons.compiler.CompileException
import org.codehaus.commons.compiler.util.resource.Resource
import org.codehaus.janino.CompilerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import tornadofx.FX.Companion.eventbus
import java.io.File
@@ -19,9 +17,6 @@ import java.io.File
class JaninoCompiler : Compiler {
private val compilerFactory = CompilerFactory()
@Autowired
private lateinit var apiProvider: APIProvider
override fun compile(sourceDirectory: FileSystemNode, targetDirectory: File, classPath: Array<File>) = try {
tryToCompile(sourceDirectory, targetDirectory, classPath)
@@ -38,32 +33,32 @@ class JaninoCompiler : Compiler {
} catch (e: CompileException) {
val locationIndex = e.location?.toString()?.length?.plus(2) ?: 0
val message = e.message?.substring(locationIndex)
val location = Location(e.location.fileName, e.location.lineNumber.toLong(), e.location.columnNumber.toLong())
throw BuildException(Severity.ERROR, "Compiler", e.location, message, e)
throw BuildException(Severity.ERROR, TAG, location, message, e)
}
private fun tryToCompile(sourceDirectory: FileSystemNode, targetDirectory: File, classPath: Array<File>) {
val compilationUnits = prepareCompilationUnits(sourceDirectory)
val compilationUnits = sourceDirectory.allChildren
.filter { it.type == FileType.FILE }
.map(::FileNodeResourceAdapter)
.toTypedArray()
compilerFactory.newCompiler().apply {
setDestinationDirectory(targetDirectory, false)
setClassPath(classPath)
setWarningHandler { handle, message, location ->
eventbus.fire(AppendBuildLogsEvent(Severity.WARNING, "$message ($handle)", location, "Compiler"))
setWarningHandler { handle, message, loc ->
val location = Location(loc.fileName, loc.lineNumber.toLong(), loc.columnNumber.toLong())
eventbus.fire(AppendBuildLogsEvent(Severity.WARNING, "$message ($handle)", location, TAG))
}
compile(compilationUnits)
}
}
private fun prepareCompilationUnits(sourceDirectory: FileSystemNode): Array<Resource> {
val sources = sourceDirectory.allChildren
val api = apiProvider.apiNode.allChildren
return (sources + api)
.filter { it.type == FileType.FILE }
.map(::FileNodeResourceAdapter)
.toTypedArray()
companion object {
private const val TAG = "Compiler"
}
}

View File

@@ -1,17 +1,19 @@
package com.bartlomiejpluta.base.editor.code.build.exception
import com.bartlomiejpluta.base.editor.common.logs.enumeration.Severity
import org.codehaus.commons.compiler.Location
import com.bartlomiejpluta.base.editor.common.logs.model.Location
class BuildException(
val severity: Severity,
val tag: String,
val severity: Severity?,
val tag: String?,
val location: Location?,
message: String?,
override val cause: Throwable
override val cause: Throwable?
) : Exception() {
constructor(severity: Severity, tag: String, message: String?, cause: Throwable)
constructor(severity: Severity?, tag: String?, message: String?, cause: Throwable?)
: this(severity, tag, null, message, cause)
constructor() : this(null, null, null, null, null)
override val message = message ?: ""
}

View File

@@ -21,7 +21,7 @@ class DefaultGameEngineProvider : GameEngineProvider {
try {
tryToProvide(targetJar)
} catch (e: Exception) {
throw BuildException(Severity.ERROR, "Engine Provider", e.message, e)
throw BuildException(Severity.ERROR, TAG, e.message, e)
}
}
@@ -35,5 +35,6 @@ class DefaultGameEngineProvider : GameEngineProvider {
companion object {
private const val GAME_ENGINE_JAR = "/engine/engine.jar"
private const val TAG = "Engine Provider"
}
}

View File

@@ -5,6 +5,6 @@ import javafx.concurrent.Task
interface BuildPipelineService {
val isRunningProperty: BooleanProperty
fun build(): Task<Unit>
fun build(): Task<Boolean>
fun clean()
}

View File

@@ -56,21 +56,26 @@ class DefaultBuildPipelineService : BuildPipelineService {
override fun build() = runAsync {
latch?.locked?.takeIf { it }?.let {
cancel()
return@runAsync
return@runAsync false
}
latch = Latch()
try {
projectContext.project?.let(this@DefaultBuildPipelineService::runPipeline)
return@runAsync true
} catch (e: BuildException) {
val event = AppendBuildLogsEvent(e.severity, e.message, e.location, e.tag)
eventbus.fire(event)
e.severity?.let {
val event = AppendBuildLogsEvent(it, e.message, e.location, e.tag)
eventbus.fire(event)
}
eventbus.fire(AppendBuildLogsEvent(Severity.ERROR, "Build failed", tag = TAG))
} finally {
latch?.release()
}
Unit
false
}
private fun runPipeline(project: Project) {

View File

@@ -18,7 +18,7 @@ class DefaultProjectAssembler : ProjectAssembler {
try {
tryToAssembly(project, targetJar)
} catch (e: Exception) {
throw BuildException(Severity.ERROR, "Project Assembler", e.message, e)
throw BuildException(Severity.ERROR, TAG, e.message, e)
}
}
@@ -29,4 +29,8 @@ class DefaultProjectAssembler : ProjectAssembler {
packager.pack(project.entitySetsDirectory, targetJar, "BOOT-INF/classes/project/entsets")
packager.copy(project.projectFile, targetJar, "BOOT-INF/classes/project")
}
companion object {
private const val TAG = "Project Assembler"
}
}

View File

@@ -1,14 +1,15 @@
package com.bartlomiejpluta.base.editor.code.view.build
import com.bartlomiejpluta.base.editor.common.logs.component.LogsPane
import com.bartlomiejpluta.base.editor.common.logs.model.Location
import com.bartlomiejpluta.base.editor.event.AppendBuildLogsEvent
import com.bartlomiejpluta.base.editor.event.ClearBuildLogsEvent
import com.bartlomiejpluta.base.editor.main.controller.MainController
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
import org.codehaus.commons.compiler.Location
import org.kordamp.ikonli.javafx.FontIcon
import tornadofx.*
import java.io.File
import kotlin.math.max
class BuildLogsView : View() {
private val projectContext: ProjectContext by di()
@@ -29,8 +30,8 @@ class BuildLogsView : View() {
}
private fun locationClick(location: Location) {
projectContext.project?.codeFSNode?.findByFile(File(location.fileName))?.let {
mainController.openScript(it, location.lineNumber, 1)
projectContext.project?.codeFSNode?.findByFile(File(location.sourceName))?.let {
mainController.openScript(it, max(1, location.lineNumber.toInt()), 1)
}
}

View File

@@ -1,10 +1,10 @@
package com.bartlomiejpluta.base.editor.common.logs.component
import com.bartlomiejpluta.base.editor.common.logs.enumeration.Severity
import com.bartlomiejpluta.base.editor.common.logs.model.Location
import com.bartlomiejpluta.base.editor.common.logs.style.LogsPaneStyle
import com.bartlomiejpluta.base.editor.common.logs.stylesheet.LogsPaneStylesheet
import javafx.scene.layout.StackPane
import org.codehaus.commons.compiler.Location
import org.fxmisc.flowless.VirtualizedScrollPane
import org.fxmisc.richtext.StyledTextArea
import tornadofx.addClass

View File

@@ -2,6 +2,7 @@ package com.bartlomiejpluta.base.editor.common.logs.enumeration
enum class Severity {
INFO,
NOTE,
WARNING,
ERROR
}

View File

@@ -0,0 +1,5 @@
package com.bartlomiejpluta.base.editor.common.logs.model
data class Location(val sourceName: String, val lineNumber: Long, val columnNumber: Long) {
override fun toString() = if(lineNumber < 1) sourceName else "$sourceName:$lineNumber,$columnNumber"
}

View File

@@ -1,10 +1,10 @@
package com.bartlomiejpluta.base.editor.common.logs.style
import com.bartlomiejpluta.base.editor.common.logs.enumeration.Severity
import com.bartlomiejpluta.base.editor.common.logs.model.Location
import javafx.scene.Cursor
import javafx.scene.paint.Color
import javafx.scene.text.Text
import org.codehaus.commons.compiler.Location
class LogsPaneStyle(
private val location: Location? = null,
@@ -23,6 +23,7 @@ class LogsPaneStyle(
text.fill = when (severity) {
Severity.WARNING -> Color.ORANGE
Severity.ERROR -> Color.RED
Severity.NOTE -> Color.DARKGRAY
Severity.INFO -> text.fill
}
}

View File

@@ -1,7 +1,7 @@
package com.bartlomiejpluta.base.editor.event
import com.bartlomiejpluta.base.editor.common.logs.enumeration.Severity
import org.codehaus.commons.compiler.Location
import com.bartlomiejpluta.base.editor.common.logs.model.Location
import tornadofx.EventBus
import tornadofx.FXEvent

View File

@@ -8,7 +8,6 @@ import com.bartlomiejpluta.base.editor.process.runner.jar.JarRunner
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
import com.bartlomiejpluta.base.editor.project.model.Project
import javafx.beans.property.SimpleObjectProperty
import javafx.event.EventHandler
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import tornadofx.*
@@ -43,7 +42,14 @@ class DefaultApplicationRunner : ApplicationRunner {
if (project.buildOutputJarFile.exists() && project.buildOutputJarFile.isFile) {
runApplication(project)
} else {
pipelineService.build().onSucceeded = EventHandler { runApplication(project) }
val build = pipelineService.build()
build.setOnSucceeded {
if (build.value) {
runApplication(project)
} else {
isRunning = false
}
}
}
}
}

View File

@@ -1,7 +1,7 @@
package ${package};
import com.bartlomiejpluta.base.api.runner.GameRunner;
import com.bartlomiejpluta.base.api.context.Context;
import com.bartlomiejpluta.base.api.game.runner.GameRunner;
import com.bartlomiejpluta.base.api.game.context.Context;
public class ${className} implements GameRunner {