All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tambapps.marcel.compiler.AbstractMarcelCompiler.kt Maven / Gradle / Ivy

package com.tambapps.marcel.compiler

import com.tambapps.marcel.compiler.exception.MarcelCompilerException
import com.tambapps.marcel.dumbbell.Dumbbell
import com.tambapps.marcel.lexer.LexToken
import com.tambapps.marcel.parser.cst.SourceFileCstNode
import com.tambapps.marcel.semantic.MarcelSemantic
import com.tambapps.marcel.semantic.ast.ClassNode
import com.tambapps.marcel.semantic.ast.ModuleNode
import com.tambapps.marcel.semantic.check.ClassNodeChecks
import com.tambapps.marcel.semantic.exception.MarcelSemanticException
import com.tambapps.marcel.semantic.extensions.javaType
import com.tambapps.marcel.semantic.symbol.MarcelSymbolResolver
import marcel.lang.MarcelClassLoader
import marcel.lang.Script

// will enrich it maybe someday if needed
abstract class AbstractMarcelCompiler(protected val configuration: CompilerConfiguration) {

  init {
    if (!Script::class.java.isAssignableFrom(configuration.scriptClass)) {
      throw MarcelSemanticException(LexToken.DUMMY, "Invalid compiler configuration: Class ${configuration.scriptClass} does not extends marcel.lang.Script")
    }
  }
  protected fun defineSymbols(symbolResolver: MarcelSymbolResolver,
                              semantics: MarcelSemantic) {
    defineSymbols(symbolResolver, listOf(semantics))
  }

  protected fun defineSymbols(symbolResolver: MarcelSymbolResolver,
                              semantics: List) {
    symbolResolver.defineSymbols(semantics, configuration.scriptClass.javaType)
  }

  protected fun handleDumbbells(marcelClassLoader: MarcelClassLoader?, cst: SourceFileCstNode) {
    if (cst.dumbbells.isNotEmpty()) {
      if (!configuration.dumbbellEnabled) {
        throw MarcelCompilerException("Cannot use dumbbells because dumbbell feature is not enabled")
      }
      if (marcelClassLoader == null) {
        throw MarcelCompilerException("Cannot use dumbbells because no class loader was provided")
      }
      cst.dumbbells.forEach { handleDumbbell(marcelClassLoader, it) }
    }
  }

  protected fun handleDumbbell(marcelClassLoader: MarcelClassLoader, dumbbell: String) {
    val artifacts = Dumbbell.pull(dumbbell)
    artifacts.forEach {
      if (it.jarFile != null) { // can be null as there could be pom-only artifacs
        marcelClassLoader.addJar(it.jarFile)
      }
    }
  }

  protected fun check(ast: ModuleNode, symbolResolver: MarcelSymbolResolver) {
    ast.classes.forEach { check(it, symbolResolver) }
  }

  protected fun check(classNode: ClassNode, symbolResolver: MarcelSymbolResolver) {
    ClassNodeChecks.ALL.forEach {
      it.visit(classNode, symbolResolver)
    }
    for (innerClassNode in classNode.innerClasses) {
      check(innerClassNode, symbolResolver)
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy