Skip to content

Commit

Permalink
Introducing an UnknownLanguage
Browse files Browse the repository at this point in the history
  • Loading branch information
oxisto committed Dec 21, 2024
1 parent 57ba291 commit 6e601b6
Show file tree
Hide file tree
Showing 18 changed files with 93 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ class TypeManager {
fun createOrGetTypeParameter(
templateDeclaration: TemplateDeclaration,
typeName: String,
language: Language<*>?
language: Language<*>
): ParameterizedType {
var parameterizedType = getTypeParameter(templateDeclaration, typeName)
if (parameterizedType == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2024, 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 de.fraunhofer.aisec.cpg.graph.types.Type
import kotlin.reflect.KClass

/**
* Represents a language definition with no known implementation or specifics. The class is used as
* a placeholder or to handle cases where the language is not explicitly defined or supported.
*/
object UnknownLanguage : Language<Nothing>() {
override val fileExtensions: List<String>
get() = listOf()

override val namespaceDelimiter: String
get() = ""

override val frontend: KClass<out Nothing> = Nothing::class
override val builtInTypes: Map<String, Type> = mapOf()
override val compoundAssignmentOperators: Set<String> = setOf()
}

/**
* Represents a composite language definition composed of multiple languages.
*
* @property languages A list of languages that are part of this composite language definition.
*/
class MultipleLanguages(val languages: Set<Language<*>>) : Language<Nothing>() {
override val fileExtensions = languages.flatMap { it.fileExtensions }
override val namespaceDelimiter: String = ""
override val frontend: KClass<out Nothing> = Nothing::class
override val builtInTypes: Map<String, Type> = mapOf()
override val compoundAssignmentOperators: Set<String> = setOf()
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
package de.fraunhofer.aisec.cpg.graph

import de.fraunhofer.aisec.cpg.PopulatedByPass
import de.fraunhofer.aisec.cpg.frontends.MultipleLanguages
import de.fraunhofer.aisec.cpg.frontends.UnknownLanguage
import de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration
import de.fraunhofer.aisec.cpg.graph.edges.ast.astEdgesOf
import de.fraunhofer.aisec.cpg.graph.edges.unwrapping
Expand Down Expand Up @@ -54,6 +56,14 @@ open class Component : Node() {
@Synchronized
fun addTranslationUnit(tu: TranslationUnitDeclaration) {
translationUnits.add(tu)

// Check, if this component is of a particular single language or multi-language
val languages = translationUnitEdges.map { it.end.language }.toSet()
if (languages.size == 1) {
this.language = languages.singleOrNull() ?: UnknownLanguage
} else if (languages.size > 1) {
this.language = MultipleLanguages(languages = languages)
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import de.fraunhofer.aisec.cpg.sarif.PhysicalLocation
/** A simple interface that a node has [language]. */
interface HasLanguage {

var language: Language<*>?
var language: Language<*>
}

/** A simple interface that a node has [name] and [location]. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import de.fraunhofer.aisec.cpg.TranslationContext
import de.fraunhofer.aisec.cpg.TypeManager
import de.fraunhofer.aisec.cpg.frontends.Handler
import de.fraunhofer.aisec.cpg.frontends.Language
import de.fraunhofer.aisec.cpg.frontends.UnknownLanguage
import de.fraunhofer.aisec.cpg.graph.declarations.MethodDeclaration
import de.fraunhofer.aisec.cpg.graph.declarations.RecordDeclaration
import de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration
Expand Down Expand Up @@ -93,7 +94,7 @@ abstract class Node :
*/
@Relationship(value = "LANGUAGE", direction = Relationship.Direction.OUTGOING)
@JsonBackReference
override var language: Language<*>? = null
override var language: Language<*> = UnknownLanguage

/**
* The scope this node "lives" in / in which it is defined. This property is set in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ interface MetadataProvider
* each [Node], but also transformation steps, such as [Handler].
*/
interface LanguageProvider : MetadataProvider {
val language: Language<*>?
val language: Language<*>
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ package de.fraunhofer.aisec.cpg.graph.declarations

import de.fraunhofer.aisec.cpg.PopulatedByPass
import de.fraunhofer.aisec.cpg.frontends.Language
import de.fraunhofer.aisec.cpg.frontends.UnknownLanguage
import de.fraunhofer.aisec.cpg.graph.*
import de.fraunhofer.aisec.cpg.graph.edges.flows.Usages
import de.fraunhofer.aisec.cpg.graph.edges.unwrapping
Expand All @@ -44,11 +45,11 @@ abstract class ValueDeclaration : Declaration(), HasType, HasAliases {

override val typeObservers: MutableSet<HasType.TypeObserver> = identitySetOf()

override var language: Language<*>? = null
override var language: Language<*> = UnknownLanguage
set(value) {
// We need to adjust an eventual unknown type, once we know the language
field = value
if (value != null && type is UnknownType) {
if (type is UnknownType) {
type = UnknownType.getUnknownType(value)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
package de.fraunhofer.aisec.cpg.graph.statements.expressions

import de.fraunhofer.aisec.cpg.frontends.Language
import de.fraunhofer.aisec.cpg.frontends.UnknownLanguage
import de.fraunhofer.aisec.cpg.graph.*
import de.fraunhofer.aisec.cpg.graph.statements.Statement
import de.fraunhofer.aisec.cpg.graph.types.*
Expand All @@ -49,11 +50,11 @@ import org.neo4j.ogm.annotation.Transient
abstract class Expression : Statement(), HasType {
@Transient override val typeObservers: MutableSet<HasType.TypeObserver> = identitySetOf()

override var language: Language<*>? = null
override var language: Language<*> = UnknownLanguage
set(value) {
// We need to adjust an eventual unknown type, once we know the language
field = value
if (value != null && type is UnknownType) {
if (type is UnknownType) {
type = UnknownType.getUnknownType(value)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import de.fraunhofer.aisec.cpg.graph.unknownType
*
* Note: This is intentionally a distinct type and not the [UnknownType].
*/
class AutoType(override var language: Language<*>?) : Type("auto", language) {
class AutoType(override var language: Language<*>) : Type("auto", language) {
override fun reference(pointer: PointerType.PointerOrigin?): Type {
return PointerType(this, pointer)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ import de.fraunhofer.aisec.cpg.frontends.Language
class BooleanType(
typeName: CharSequence = "bool",
bitWidth: Int? = 1,
language: Language<*>? = null,
language: Language<*>,
modifier: Modifier = Modifier.NOT_APPLICABLE
) : NumericType(typeName, bitWidth, language, modifier)
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ import de.fraunhofer.aisec.cpg.frontends.Language
class FloatingPointType(
typeName: CharSequence = "",
bitWidth: Int? = null,
language: Language<*>? = null,
language: Language<*>,
modifier: Modifier = Modifier.SIGNED
) : NumericType(typeName, bitWidth, language, modifier)
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
package de.fraunhofer.aisec.cpg.graph.types

import de.fraunhofer.aisec.cpg.frontends.Language
import de.fraunhofer.aisec.cpg.frontends.UnknownLanguage
import de.fraunhofer.aisec.cpg.graph.types.PointerType.PointerOrigin
import java.util.*
import org.apache.commons.lang3.builder.ToStringBuilder
Expand All @@ -48,7 +49,7 @@ class FunctionPointerType : Type {

constructor(
parameters: List<Type> = listOf(),
language: Language<*>? = null,
language: Language<*>,
returnType: Type = UnknownType.getUnknownType(language)
) : super(EMPTY_NAME, language) {
this.parameters = parameters
Expand All @@ -58,7 +59,7 @@ class FunctionPointerType : Type {
constructor(
type: Type,
parameters: List<Type> = listOf(),
language: Language<*>? = null,
language: Language<*> = UnknownLanguage,
returnType: Type = UnknownType.getUnknownType(language)
) : super(type) {
this.parameters = parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ import de.fraunhofer.aisec.cpg.frontends.Language
class IntegerType(
typeName: CharSequence = "",
bitWidth: Int? = null,
language: Language<*>? = null,
language: Language<*>,
modifier: Modifier = Modifier.SIGNED
) : NumericType(typeName, bitWidth, language, modifier)
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import java.util.*
open class NumericType(
typeName: CharSequence = "",
val bitWidth: Int? = null,
language: Language<*>? = null,
language: Language<*>,
val modifier: Modifier = Modifier.SIGNED
) : ObjectType(typeName, listOf(), true, language) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ open class ObjectType : Type {
typeName: CharSequence,
generics: List<Type>,
primitive: Boolean,
language: Language<*>?
language: Language<*>
) : super(typeName, language) {
this.generics = generics
isPrimitive = primitive
Expand All @@ -71,7 +71,7 @@ open class ObjectType : Type {
type: Type?,
generics: List<Type>,
primitive: Boolean,
language: Language<*>?
language: Language<*>
) : super(type) {
this.language = language
this.generics = generics
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ParameterizedType : Type {
language = type.language
}

constructor(typeName: String?, language: Language<*>?) : super(typeName) {
constructor(typeName: String?, language: Language<*>) : super(typeName) {
this.language = language
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import de.fraunhofer.aisec.cpg.frontends.Language

class StringType(
typeName: CharSequence = "",
language: Language<*>? = null,
language: Language<*>,
generics: List<Type> = listOf()
) : ObjectType(typeName, generics, false, language) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ abstract class Type : Node {
typeOrigin = type?.typeOrigin
}

constructor(typeName: CharSequence, language: Language<*>?) {
constructor(typeName: CharSequence, language: Language<*>) {
name =
if (this is FunctionType) {
Name(typeName.toString(), null, language)
Expand All @@ -106,7 +106,7 @@ abstract class Type : Node {
typeOrigin = Origin.UNRESOLVED
}

constructor(fullTypeName: Name, language: Language<*>?) {
constructor(fullTypeName: Name, language: Language<*>) {
name = fullTypeName.clone()
typeOrigin = Origin.UNRESOLVED
this.language = language
Expand Down

0 comments on commit 6e601b6

Please sign in to comment.