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

miksilo.modularLanguages.deltas.javac.classes.ClassCompiler.scala Maven / Gradle / Ivy

The newest version!
package miksilo.modularLanguages.deltas.javac.classes

import java.util.NoSuchElementException

import miksilo.languageServer.core.language.Compilation
import miksilo.modularLanguages.core.node.Node
import miksilo.modularLanguages.deltas.bytecode.constants._
import miksilo.modularLanguages.deltas.bytecode.extraConstants.TypeConstant
import miksilo.modularLanguages.deltas.bytecode.types.{QualifiedObjectTypeDelta, UnqualifiedObjectTypeDelta}
import miksilo.modularLanguages.deltas.classes.ClassDelta.JavaClass
import miksilo.modularLanguages.deltas.javac.classes.skeleton.{ClassMember, ClassSignature, JavaClassDelta, PackageSignature, QualifiedClassName}
import miksilo.modularLanguages.deltas.method.MethodDelta

case class FieldInfo(parent: ClassSignature, name: String, _static: Boolean, _type: Node) extends ClassMember

case class MethodInfo(_type: Node, _static: Boolean) extends ClassMember

case class MethodQuery(className: QualifiedClassName, methodName: String, argumentTypes: Seq[Node])

case class ClassCompiler(currentClass: Node, compilation: Compilation) {
  val javaCompiler = JavaClassDelta.state(compilation).javaCompiler
  val className: String = currentClass.name
  val myPackage: PackageSignature = javaCompiler.getPackage(currentClass._package.toList)
  val currentClassInfo = ClassSignature(myPackage, className)
  lazy val classNames: Map[String, QualifiedClassName] = getClassMapFromImports(currentClass.imports)

  def bind(): Unit = {
    val previous = JavaClassDelta.state(compilation).classCompiler
    JavaClassDelta.state(compilation).classCompiler = this
    myPackage.content(className) = currentClassInfo

    val javaClass: JavaClass[Node] = currentClass

    JavaClassDelta.getFields(javaClass).foreach(field =>
      FieldDeclarationDelta.bind(compilation, currentClassInfo, field))

    MethodDelta.getMethods(javaClass).foreach(method =>
      MethodDelta.bind(compilation, currentClassInfo, method))

    JavaClassDelta.state(compilation).classCompiler = previous
  }

  def findClass(className: String): ClassSignature = javaCompiler.find(fullyQualify(className).parts).asInstanceOf[ClassSignature]

  def fullyQualify(className: String): QualifiedClassName = {
    try
      {
        classNames(className)
      }
    catch {
      case _:NoSuchElementException =>
        throw new NoSuchElementException(s"Could not find $className in $classNames")
    }
  }

  def getMethodRefIndex(methodKey: MethodQuery) = {
    val classRef = ClassInfoConstant.classRef(methodKey.className)
    val nameAndTypeIndex = getMethodNameAndTypeIndex(methodKey)
    MethodRefConstant.methodRef(classRef, nameAndTypeIndex)
  }

  def getMethodNameAndTypeIndex(methodKey: MethodQuery) = {
    val methodNameIndex = getNameIndex(methodKey.methodName)
    NameAndTypeConstant.nameAndType(methodNameIndex, TypeConstant.constructor(javaCompiler.find(methodKey)._type))
  }

  def getNameIndex(methodName: String) = {
    Utf8ConstantDelta.create(methodName)
  }

  def getClassRef(info: ClassSignature): Node = {
    ClassInfoConstant.classRef(info.getQualifiedName)
  }

  def findClass(objectType: Node): ClassSignature = {
    val qualifiedName = objectType.shape match {
      case QualifiedObjectTypeDelta.Shape => QualifiedObjectTypeDelta.getName(objectType)
      case UnqualifiedObjectTypeDelta.Shape => fullyQualify(UnqualifiedObjectTypeDelta.getName(objectType))
    }
    javaCompiler.find(qualifiedName.parts).asInstanceOf[ClassSignature]
  }

  private def getClassMapFromImports(imports: Seq[Node]): Map[String, QualifiedClassName] = {
    imports.flatMap(_import => {
      JavaClassDelta.importToClassMap(compilation, _import.shape)(compilation, _import)
    }).toMap ++ Map(className -> JavaClassDelta.getQualifiedClassName(currentClass))
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy