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

com.jtransc.ast.ast_annotation.kt Maven / Gradle / Ivy

Go to download

JVM AOT compiler currently generating JavaScript, C++, Haxe, with initial focus on Kotlin and games.

There is a newer version: 0.6.8
Show newest version
package com.jtransc.ast

import com.jtransc.annotation.JTranscMethodBodyList
import com.jtransc.gen.TargetName
import java.lang.reflect.Proxy
import kotlin.reflect.KProperty1

data class AstAnnotation(
	val type: AstType.REF,
	val elements: Map,
	val runtimeVisible: Boolean
) {
	private var typedObject: Any? = null

	private fun getAllDescendantAnnotations(value: Any?): List {
		return when (value) {
			is AstAnnotation -> getAllDescendantAnnotations(elements.values.toList())
			is List<*> -> value.filterIsInstance() + value.filterIsInstance>().flatMap { getAllDescendantAnnotations(it) }
			else -> listOf()
		}
	}

	fun getAllDescendantAnnotations(): List {
		var out = arrayListOf()
		out.add(this)
		out.addAll(getAllDescendantAnnotations(this))
		return out
	}

	inline fun  toObject(): T? {
		return this.toObject(T::class.java)
	}

	fun  toObject(clazz: Class): T? {
		return if (clazz.name == this.type.fqname) toAnyObject() as T else null
	}

	fun toAnyObject(): Any? {
		if (typedObject == null) {
			val classLoader = this.javaClass.classLoader

			fun minicast(it: Any?, type: Class<*>): Any? {
				return when (it) {
					is List<*> -> {
						val array = java.lang.reflect.Array.newInstance(type.componentType, it.size)
						for (n in 0 until it.size) java.lang.reflect.Array.set(array, n, minicast(it[n], type.componentType))
						array
					}
					is AstAnnotation -> {
						it.toAnyObject()
					}
					else -> {
						it
					}
				}
			}

			typedObject = Proxy.newProxyInstance(classLoader, arrayOf(classLoader.loadClass(this.type.fqname))) { proxy, method, args ->
				val valueUncasted = this.elements[method.name] ?: method.defaultValue
				val returnType = method.returnType
				minicast(valueUncasted, returnType)
			}
		}
		return typedObject!!
	}
}

fun AstAnnotation.getRefTypesFqName(): List {
	val out = hashSetOf()
	out += this.type.getRefTypesFqName()
	for (e in this.elements.values) {
		when (e) {
			is AstAnnotation -> {
				out += e.getRefTypesFqName()
			}
			is List<*> -> {
				for (i in e) {
					when (i) {
						is AstAnnotation -> {
							out += i.getRefTypesFqName()
						}
					}
				}
			}
		}
		//println("" + e + " : " + e?.javaClass)
	}
	return out.toList()
}


class AstAnnotationList(val containerRef: AstRef, val list: List) {
	val byClassName by lazy { list.groupBy { it.type.fqname } }

	inline fun  getTypedList(field: KProperty1>): List {
		val single = this.getTyped()
		val list = this.getTyped()
		return listOf(single).filterNotNull() + (if (list != null) field.get(list).toList() else listOf())
	}

	inline fun  getTyped(): T? = byClassName[T::class.java.name]?.firstOrNull()?.toObject()
	inline fun  getAllTyped(): List = byClassName[T::class.java.name]?.map { it.toObject() }?.filterNotNull() ?: listOf()
	operator fun get(name: FqName): AstAnnotation? = byClassName[name.fqname]?.firstOrNull()
	inline fun  contains(): Boolean = T::class.java.name in byClassName
}

class NativeBody(val lines: List, val cond: String = "") {
	val value = lines.joinToString("\n")
}

fun AstAnnotationList.getBodiesForTarget(targetName: TargetName): List {
	val extra = when (targetName.name) {
		"js" -> this.list.filter { it.type.name.simpleName == "JsMethodBody" }.map { NativeBody(listOf(it.elements["value"]?.toString() ?: "")) }
		else -> listOf()
	}
	return this.getTypedList(JTranscMethodBodyList::value).filter { targetName.matches(it.target) }.map { NativeBody(it.value.toList(), it.cond) } + extra
}

fun AstAnnotationList.getCallSiteBodiesForTarget(targetName: TargetName): String? {
	return this.getTypedList(com.jtransc.annotation.JTranscCallSiteBodyList::value).filter { targetName.matches(it.target) }.map { it.value.joinToString("\n") }.firstOrNull()
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy