@@ -30,20 +30,28 @@ import com.fasterxml.jackson.core.JsonGenerator
30
30
import com.fasterxml.jackson.databind.JsonSerializer
31
31
import com.fasterxml.jackson.databind.SerializerProvider
32
32
import com.fasterxml.jackson.databind.annotation.JsonSerialize
33
- import de.fraunhofer.aisec.cpg.*
33
+ import de.fraunhofer.aisec.cpg.CallResolutionResult
34
+ import de.fraunhofer.aisec.cpg.SignatureResult
35
+ import de.fraunhofer.aisec.cpg.TranslationContext
36
+ import de.fraunhofer.aisec.cpg.ancestors
34
37
import de.fraunhofer.aisec.cpg.graph.Name
35
38
import de.fraunhofer.aisec.cpg.graph.Node
36
39
import de.fraunhofer.aisec.cpg.graph.OverlayNode
37
40
import de.fraunhofer.aisec.cpg.graph.declarations.Declaration
38
41
import de.fraunhofer.aisec.cpg.graph.declarations.FunctionDeclaration
42
+ import de.fraunhofer.aisec.cpg.graph.declarations.NamespaceDeclaration
43
+ import de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration
39
44
import de.fraunhofer.aisec.cpg.graph.edges.ast.TemplateArguments
45
+ import de.fraunhofer.aisec.cpg.graph.scopes.GlobalScope
46
+ import de.fraunhofer.aisec.cpg.graph.scopes.Scope
40
47
import de.fraunhofer.aisec.cpg.graph.statements.expressions.BinaryOperator
41
48
import de.fraunhofer.aisec.cpg.graph.statements.expressions.CallExpression
42
49
import de.fraunhofer.aisec.cpg.graph.statements.expressions.Reference
43
50
import de.fraunhofer.aisec.cpg.graph.types.*
44
51
import de.fraunhofer.aisec.cpg.graph.unknownType
45
52
import de.fraunhofer.aisec.cpg.helpers.Util
46
53
import de.fraunhofer.aisec.cpg.passes.SymbolResolver
54
+ import de.fraunhofer.aisec.cpg.passes.inference.Inference
47
55
import java.io.File
48
56
import kotlin.reflect.KClass
49
57
import kotlin.reflect.full.primaryConstructor
@@ -388,6 +396,35 @@ abstract class Language<T : LanguageFrontend<*, *>> : Node() {
388
396
ref.candidates.singleOrNull()
389
397
}
390
398
}
399
+
400
+ /* *
401
+ * There are some cases where our [Inference] system needs to place declarations, e.g., a
402
+ * [NamespaceDeclaration] in the [GlobalScope]. The issue with that is that the [Scope.astNode]
403
+ * of the global scope is always the last parsed [TranslationUnitDeclaration] and we might end
404
+ * up adding the declaration to some random translation unit, where it does not really belong.
405
+ *
406
+ * Therefore, we give the language a chance to return a [TranslationUnitDeclaration] where the
407
+ * declaration should be placed. If the language does not override this function, the default
408
+ * implementation will return the first [TranslationUnitDeclaration] in
409
+ * [TranslationContext.currentComponent].
410
+ *
411
+ * But languages might choose to take the information of [TypeToInfer] and [source] and create a
412
+ * specific [TranslationUnitDeclaration], e.g., for each namespace that is inferred globally or
413
+ * try to put all inferred declarations into one specific (inferred) new translation unit.
414
+ *
415
+ * @param TypeToInfer the type of the node that should be inferred
416
+ * @param source the source that was responsible for the inference
417
+ */
418
+ fun <TypeToInfer : Node > translationUnitForInference (source : Node ): TranslationUnitDeclaration {
419
+ val tu = source.ctx?.currentComponent?.translationUnits?.firstOrNull()
420
+ if (tu == null ) {
421
+ throw TranslationException (
422
+ " No translation unit found that should be used for inference"
423
+ )
424
+ }
425
+
426
+ return tu
427
+ }
391
428
}
392
429
393
430
/* *
0 commit comments