![JAR search and dependency download from the Maven repository](/logo.png)
de.fraunhofer.aisec.cpg.frontends.Language.kt Maven / Gradle / Ivy
/*
* Copyright (c) 2022, Fraunhofer AISEC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $$$$$$\ $$$$$$$\ $$$$$$\
* $$ __$$\ $$ __$$\ $$ __$$\
* $$ / \__|$$ | $$ |$$ / \__|
* $$ | $$$$$$$ |$$ |$$$$\
* $$ | $$ ____/ $$ |\_$$ |
* $$ | $$\ $$ | $$ | $$ |
* \$$$$$ |$$ | \$$$$$ |
* \______/ \__| \______/
*
*/
package de.fraunhofer.aisec.cpg.frontends
import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.annotation.JsonSerialize
import com.fasterxml.jackson.databind.ser.std.StdSerializer
import de.fraunhofer.aisec.cpg.ScopeManager
import de.fraunhofer.aisec.cpg.TranslationConfiguration
import de.fraunhofer.aisec.cpg.graph.Node
import de.fraunhofer.aisec.cpg.graph.types.*
import java.io.File
import kotlin.reflect.KClass
import org.neo4j.ogm.annotation.Transient
/**
* Represents a programming language. When creating new languages in the CPG, one must derive custom
* class from this and override the necessary fields and methods.
*
* Furthermore, since this also implements [Node], one node for each programming language used is
* persisted in the final graph (database) and each node links to its corresponding language using
* the [Node.language] property.
*/
abstract class Language : Node() {
/** The file extensions without the dot */
abstract val fileExtensions: List
/** The namespace delimiter used by the language. Often, this is "." */
abstract val namespaceDelimiter: String
@get:JsonSerialize(using = KClassSerializer::class)
/** The class of the frontend which is used to parse files of this language. */
abstract val frontend: KClass
/** The primitive types of this language. */
@get:JsonIgnore
val primitiveTypes: Set
get() = simpleTypes.keys
// TODO: Maybe make this abstract?
@get:JsonIgnore
@Transient
open val simpleTypes: Map =
mapOf(
"boolean" to IntegerType("boolean", 1, this, NumericType.Modifier.SIGNED),
"char" to IntegerType("char", 8, this, NumericType.Modifier.NOT_APPLICABLE),
"byte" to IntegerType("byte", 8, this, NumericType.Modifier.SIGNED),
"short" to IntegerType("short", 16, this, NumericType.Modifier.SIGNED),
"int" to IntegerType("int", 32, this, NumericType.Modifier.SIGNED),
"long" to IntegerType("long", 64, this, NumericType.Modifier.SIGNED),
"float" to FloatingPointType("float", 32, this, NumericType.Modifier.SIGNED),
"double" to FloatingPointType("double", 64, this, NumericType.Modifier.SIGNED),
)
/** The access modifiers of this programming language */
open val accessModifiers: Set
get() = setOf("public", "protected", "private")
/** Creates a new [LanguageFrontend] object to parse the language. */
abstract fun newFrontend(
config: TranslationConfiguration,
scopeManager: ScopeManager = ScopeManager(),
): T
fun getSimpleTypeOf(typeString: String) = simpleTypes[typeString]
/** Returns true if the [file] can be handled by the frontend of this language. */
fun handlesFile(file: File): Boolean {
return file.extension in fileExtensions
}
override fun equals(other: Any?): Boolean {
return other?.javaClass == this.javaClass
}
override fun hashCode(): Int {
var result = super.hashCode()
result = 31 * result + fileExtensions.hashCode()
result = 31 * result + namespaceDelimiter.hashCode()
result = 31 * result + frontend.hashCode()
result = 31 * result + primitiveTypes.hashCode()
result = 31 * result + accessModifiers.hashCode()
return result
}
init {
this.also { this.language = it }
}
}
/**
* We need to bring our own serializer for [KClass] until
* https://github.com/FasterXML/jackson-module-kotlin/issues/361 is resolved.
*/
internal class KClassSerializer : StdSerializer>(KClass::class.java) {
override fun serialize(value: KClass<*>, gen: JsonGenerator, provider: SerializerProvider) {
// Write the fully qualified name as a string
gen.writeString(value.qualifiedName)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy