Skip to content

Commit 280a907

Browse files
ashfordiumjohannescoetzeempollmeier
authored
Delete Location and NewLocation (#1819)
* Add deprecation comment to `location` in schema * Delete location and new location nodes from the CPG spec * Generate code * Remove unused node properties and fix formatting * introduce TempFileCopy and use in test with flatgraphCpg fixes PR build, since flatgraph writes to the test file on '.close' which leads to changes in the repo, which is not permitted for PR builds --------- Co-authored-by: Johannes Coetzee <[email protected]> Co-authored-by: Michael Pollmeier <[email protected]>
1 parent 56ece06 commit 280a907

File tree

129 files changed

+2102
-4095
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+2102
-4095
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.shiftleft.utils
2+
3+
import java.nio.file.Path
4+
import java.nio.file.Files
5+
import java.nio.file.StandardCopyOption
6+
7+
class TempFileCopy(sourcePath: Path, prefix: String = "resource", suffix: String = ".tmp") extends AutoCloseable {
8+
val path: Path = {
9+
val temp = Files.createTempFile(prefix, suffix)
10+
Files.copy(sourcePath, temp, StandardCopyOption.REPLACE_EXISTING)
11+
temp
12+
}
13+
14+
override def close() = Files.deleteIfExists(path)
15+
}

codepropertygraph/src/test/scala/io/shiftleft/codepropertygraph/cpgloading/CpgLoaderTests.scala

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package io.shiftleft.codepropertygraph.cpgloading
33
import flatgraph.{Accessors, DiffGraphApplier}
44
import io.shiftleft.codepropertygraph.generated.Cpg
55
import io.shiftleft.codepropertygraph.generated.nodes.NewMethod
6-
import io.shiftleft.utils.ProjectRoot
6+
import io.shiftleft.utils.{ProjectRoot, TempFileCopy}
77
import io.shiftleft.codepropertygraph.generated.nodes.Type
88
import org.scalatest.BeforeAndAfterAll
99
import org.scalatest.matchers.should.Matchers
@@ -44,16 +44,15 @@ class CpgLoaderTests extends AnyWordSpec with Matchers with BeforeAndAfterAll {
4444
}
4545

4646
"allow loading of CPG in flatgraph format" in {
47-
val flatgraphCpg = ProjectRoot.relativise("codepropertygraph/src/test/resources/cpg.fg")
48-
Using.resource(CpgLoader.load(flatgraphCpg)) { cpg =>
49-
// the test graph was created by c2cpg for https://github.com/joernio/joern/blob/master/tests/code/c/test.c
47+
Using.Manager { use =>
48+
val flatgraphCpg = use(temporaryFlatgraphCpg()).path
49+
val cpg = use(CpgLoader.load(flatgraphCpg))
5050
cpg.graph.nodes("METHOD").size shouldBe 4
51-
}
51+
}.get
5252
}
5353

5454
"allow loading of CPG in flatgraph format and persist changes to separate file" in {
55-
val flatgraphCpg = Paths.get(ProjectRoot.relativise("codepropertygraph/src/test/resources/cpg.fg"))
56-
val persistTo = Files.createTempFile(getClass.getSimpleName, "persistToTest")
55+
val persistTo = Files.createTempFile(getClass.getSimpleName, "persistToTest")
5756

5857
Using.resource(CpgLoader.load(flatgraphCpg, persistTo)) { cpg =>
5958
DiffGraphApplier.applyDiff(cpg.graph, Cpg.newDiffGraphBuilder.addNode(NewMethod()))
@@ -63,14 +62,22 @@ class CpgLoaderTests extends AnyWordSpec with Matchers with BeforeAndAfterAll {
6362
cpg.graph.nodes("METHOD").size shouldBe 5
6463
}
6564

66-
Using.resource(CpgLoader.load(flatgraphCpg)) { cpg =>
65+
Using.Manager { use =>
66+
val flatgraphCpg = use(temporaryFlatgraphCpg()).path
67+
val cpg = use(CpgLoader.load(flatgraphCpg))
6768
// original cpg should be unchanged
6869
cpg.graph.nodes("METHOD").size shouldBe 4
69-
}
70+
}.get
7071
}
7172

7273
"throw an appropriate exception if the provided filename that refers to a non-existing file" in {
7374
a[FileNotFoundException] should be thrownBy CpgLoader.load("invalid/path/cpg.bin.zip")
7475
}
7576

77+
/** this test graph was created by c2cpg for https://github.com/joernio/joern/blob/master/tests/code/c/test.c */
78+
val flatgraphCpg = Paths.get(ProjectRoot.relativise("codepropertygraph/src/test/resources/cpg.fg"))
79+
80+
/** flatgraph writes to this file on 'close', so we'll create a temporary copy */
81+
private def temporaryFlatgraphCpg(): TempFileCopy =
82+
TempFileCopy(flatgraphCpg)
7683
}

domainClasses/src/main/generated/io/shiftleft/codepropertygraph/generated/Cpg.scala

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -331,17 +331,13 @@ contains the entire local variable declaration without initialization, e.g., for
331331
/** Shorthand for local.name */
332332
def local(name: String): Iterator[nodes.Local] = local.name(name)
333333

334-
/** A location node summarizes a source code location. */
335-
@flatgraph.help.Doc(info = """A location node summarizes a source code location.""")
336-
def location: Iterator[nodes.Location] = wrappedCpg.graph._nodes(23).asInstanceOf[Iterator[nodes.Location]]
337-
338334
/** This node represents a type member of a class, struct or union, e.g., for the type declaration
339335
* `class Foo{ int i ; }`, it represents the declaration of the variable `i`.
340336
*/
341337
@flatgraph.help.Doc(info = """This node represents a type member of a class, struct or union, e.g., for the
342338
type declaration `class Foo{ int i ; }`, it represents the declaration of the
343339
variable `i`.""")
344-
def member: Iterator[nodes.Member] = wrappedCpg.graph._nodes(24).asInstanceOf[Iterator[nodes.Member]]
340+
def member: Iterator[nodes.Member] = wrappedCpg.graph._nodes(23).asInstanceOf[Iterator[nodes.Member]]
345341

346342
/** Shorthand for member.name */
347343
def member(name: String): Iterator[nodes.Member] = member.name(name)
@@ -357,7 +353,7 @@ over the source files this CPG was generated from. The `VERSION` MUST be
357353
set to the version of the specification ("1.1"). The language field indicates
358354
which language frontend was used to generate the CPG and the list property
359355
`OVERLAYS` specifies which overlays have been applied to the CPG.""")
360-
def metaData: Iterator[nodes.MetaData] = wrappedCpg.graph._nodes(25).asInstanceOf[Iterator[nodes.MetaData]]
356+
def metaData: Iterator[nodes.MetaData] = wrappedCpg.graph._nodes(24).asInstanceOf[Iterator[nodes.MetaData]]
361357

362358
/** Programming languages offer many closely-related concepts for describing blocks of code that can be executed with
363359
* input parameters and return output parameters, possibly causing side effects. In the CPG specification, we refer
@@ -400,7 +396,7 @@ Finally, the fully qualified name of the program constructs that the method
400396
is immediately contained in is stored in the `AST_PARENT_FULL_NAME` field
401397
and its type is indicated in the `AST_PARENT_TYPE` field to be one of
402398
`METHOD`, `TYPE_DECL` or `NAMESPACE_BLOCK`.""")
403-
def method: Iterator[nodes.Method] = wrappedCpg.graph._nodes(26).asInstanceOf[Iterator[nodes.Method]]
399+
def method: Iterator[nodes.Method] = wrappedCpg.graph._nodes(25).asInstanceOf[Iterator[nodes.Method]]
404400

405401
/** Shorthand for method.name */
406402
def method(name: String): Iterator[nodes.Method] = method.name(name)
@@ -411,7 +407,7 @@ and its type is indicated in the `AST_PARENT_TYPE` field to be one of
411407
@flatgraph.help.Doc(info = """This node represents a formal input parameter. The field `NAME` contains its
412408
name, while the field `TYPE_FULL_NAME` contains the fully qualified type name.""")
413409
def methodParameterIn: Iterator[nodes.MethodParameterIn] =
414-
wrappedCpg.graph._nodes(27).asInstanceOf[Iterator[nodes.MethodParameterIn]]
410+
wrappedCpg.graph._nodes(26).asInstanceOf[Iterator[nodes.MethodParameterIn]]
415411

416412
/** Shorthand for methodParameterIn.name */
417413
def methodParameterIn(name: String): Iterator[nodes.MethodParameterIn] = methodParameterIn.name(name)
@@ -423,7 +419,7 @@ name, while the field `TYPE_FULL_NAME` contains the fully qualified type name.""
423419
for input parameters MUST NOT be created by the frontend as they are automatically
424420
created upon first loading the CPG.""")
425421
def methodParameterOut: Iterator[nodes.MethodParameterOut] =
426-
wrappedCpg.graph._nodes(28).asInstanceOf[Iterator[nodes.MethodParameterOut]]
422+
wrappedCpg.graph._nodes(27).asInstanceOf[Iterator[nodes.MethodParameterOut]]
427423

428424
/** This node represents a reference to a method/function/procedure as it appears when a method is passed as an
429425
* argument in a call. The `METHOD_FULL_NAME` field holds the fully-qualified name of the referenced method and the
@@ -433,7 +429,7 @@ created upon first loading the CPG.""")
433429
appears when a method is passed as an argument in a call. The `METHOD_FULL_NAME`
434430
field holds the fully-qualified name of the referenced method and the
435431
`TYPE_FULL_NAME` holds its fully-qualified type name.""")
436-
def methodRef: Iterator[nodes.MethodRef] = wrappedCpg.graph._nodes(29).asInstanceOf[Iterator[nodes.MethodRef]]
432+
def methodRef: Iterator[nodes.MethodRef] = wrappedCpg.graph._nodes(28).asInstanceOf[Iterator[nodes.MethodRef]]
437433

438434
/** This node represents an (unnamed) formal method return parameter. It carries its fully qualified type name in
439435
* `TYPE_FULL_NAME`. The `CODE` field MAY be set freely, e.g., to the constant `RET`, however, subsequent layer
@@ -444,7 +440,7 @@ fully qualified type name in `TYPE_FULL_NAME`. The `CODE` field MAY be set freel
444440
e.g., to the constant `RET`, however, subsequent layer creators MUST NOT depend
445441
on this value.""")
446442
def methodReturn: Iterator[nodes.MethodReturn] =
447-
wrappedCpg.graph._nodes(30).asInstanceOf[Iterator[nodes.MethodReturn]]
443+
wrappedCpg.graph._nodes(29).asInstanceOf[Iterator[nodes.MethodReturn]]
448444

449445
/** This field represents a (language-dependent) modifier such as `static`, `private` or `public`. Unlike most other
450446
* AST nodes, it is NOT an expression, that is, it cannot be evaluated and cannot be passed as an argument in
@@ -453,7 +449,7 @@ on this value.""")
453449
@flatgraph.help.Doc(info = """This field represents a (language-dependent) modifier such as `static`, `private`
454450
or `public`. Unlike most other AST nodes, it is NOT an expression, that is, it
455451
cannot be evaluated and cannot be passed as an argument in function calls.""")
456-
def modifier: Iterator[nodes.Modifier] = wrappedCpg.graph._nodes(31).asInstanceOf[Iterator[nodes.Modifier]]
452+
def modifier: Iterator[nodes.Modifier] = wrappedCpg.graph._nodes(30).asInstanceOf[Iterator[nodes.Modifier]]
457453

458454
/** This node represents a namespace. Similar to FILE nodes, NAMESPACE nodes serve as indices that allow all
459455
* definitions inside a namespace to be obtained by following outgoing edges from a NAMESPACE node.
@@ -468,7 +464,7 @@ obtained by following outgoing edges from a NAMESPACE node.
468464
NAMESPACE nodes MUST NOT be created by language frontends. Instead,
469465
they are generated from NAMESPACE_BLOCK nodes automatically upon
470466
first loading of the CPG.""")
471-
def namespace: Iterator[nodes.Namespace] = wrappedCpg.graph._nodes(32).asInstanceOf[Iterator[nodes.Namespace]]
467+
def namespace: Iterator[nodes.Namespace] = wrappedCpg.graph._nodes(31).asInstanceOf[Iterator[nodes.Namespace]]
472468

473469
/** Shorthand for namespace.name */
474470
def namespace(name: String): Iterator[nodes.Namespace] = namespace.name(name)
@@ -500,7 +496,7 @@ The name should be given in dot-separated form where a dot indicates
500496
that the right hand side is a sub namespace of the left hand side, e.g.,
501497
`foo.bar` denotes the namespace `bar` contained in the namespace `foo`.""")
502498
def namespaceBlock: Iterator[nodes.NamespaceBlock] =
503-
wrappedCpg.graph._nodes(33).asInstanceOf[Iterator[nodes.NamespaceBlock]]
499+
wrappedCpg.graph._nodes(32).asInstanceOf[Iterator[nodes.NamespaceBlock]]
504500

505501
/** Shorthand for namespaceBlock.name */
506502
def namespaceBlock(name: String): Iterator[nodes.NamespaceBlock] = namespaceBlock.name(name)
@@ -511,31 +507,31 @@ that the right hand side is a sub namespace of the left hand side, e.g.,
511507
@flatgraph.help.Doc(info = """This node represents a return instruction, e.g., `return x`. Note that it does
512508
NOT represent a formal return parameter as formal return parameters are
513509
represented via `METHOD_RETURN` nodes.""")
514-
def ret: Iterator[nodes.Return] = wrappedCpg.graph._nodes(34).asInstanceOf[Iterator[nodes.Return]]
510+
def ret: Iterator[nodes.Return] = wrappedCpg.graph._nodes(33).asInstanceOf[Iterator[nodes.Return]]
515511

516512
/** Shorthand for ret.code */
517513
def ret(code: String): Iterator[nodes.Return] = ret.code(code)
518514

519515
/** This node represents a tag. */
520516
@flatgraph.help.Doc(info = """This node represents a tag.""")
521-
def tag: Iterator[nodes.Tag] = wrappedCpg.graph._nodes(35).asInstanceOf[Iterator[nodes.Tag]]
517+
def tag: Iterator[nodes.Tag] = wrappedCpg.graph._nodes(34).asInstanceOf[Iterator[nodes.Tag]]
522518

523519
/** Shorthand for tag.name */
524520
def tag(name: String): Iterator[nodes.Tag] = tag.name(name)
525521

526522
/** This node contains an arbitrary node and an associated tag node. */
527523
@flatgraph.help.Doc(info = """This node contains an arbitrary node and an associated tag node.""")
528-
def tagNodePair: Iterator[nodes.TagNodePair] = wrappedCpg.graph._nodes(36).asInstanceOf[Iterator[nodes.TagNodePair]]
524+
def tagNodePair: Iterator[nodes.TagNodePair] = wrappedCpg.graph._nodes(35).asInstanceOf[Iterator[nodes.TagNodePair]]
529525

530526
/** This node represents a DOM node used in template languages, e.g., JSX/TSX */
531527
@flatgraph.help.Doc(info = """This node represents a DOM node used in template languages, e.g., JSX/TSX""")
532-
def templateDom: Iterator[nodes.TemplateDom] = wrappedCpg.graph._nodes(37).asInstanceOf[Iterator[nodes.TemplateDom]]
528+
def templateDom: Iterator[nodes.TemplateDom] = wrappedCpg.graph._nodes(36).asInstanceOf[Iterator[nodes.TemplateDom]]
533529

534530
/** This node represents a type instance, that is, a concrete instantiation of a type declaration.
535531
*/
536532
@flatgraph.help.Doc(info = """This node represents a type instance, that is, a concrete instantiation
537533
of a type declaration.""")
538-
def typ: Iterator[nodes.Type] = wrappedCpg.graph._nodes(38).asInstanceOf[Iterator[nodes.Type]]
534+
def typ: Iterator[nodes.Type] = wrappedCpg.graph._nodes(37).asInstanceOf[Iterator[nodes.Type]]
539535

540536
/** Shorthand for typ.name */
541537
def typ(name: String): Iterator[nodes.Type] = typ.name(name)
@@ -550,7 +546,7 @@ at method call sites. As it true for arguments, the method is not expected
550546
to interpret the type argument. It MUST however store its code in the
551547
`CODE` field.""")
552548
def typeArgument: Iterator[nodes.TypeArgument] =
553-
wrappedCpg.graph._nodes(39).asInstanceOf[Iterator[nodes.TypeArgument]]
549+
wrappedCpg.graph._nodes(38).asInstanceOf[Iterator[nodes.TypeArgument]]
554550

555551
/** This node represents a type declaration as for example given by a class-, struct-, or union declaration. In
556552
* contrast to a `TYPE` node, this node does not represent a concrete instantiation of a type, e.g., for the
@@ -598,7 +594,7 @@ Finally, the fully qualified name of the program constructs that the type declar
598594
is immediately contained in is stored in the `AST_PARENT_FULL_NAME` field
599595
and its type is indicated in the `AST_PARENT_TYPE` field to be one of
600596
`METHOD`, `TYPE_DECL` or `NAMESPACE_BLOCK`.""")
601-
def typeDecl: Iterator[nodes.TypeDecl] = wrappedCpg.graph._nodes(40).asInstanceOf[Iterator[nodes.TypeDecl]]
597+
def typeDecl: Iterator[nodes.TypeDecl] = wrappedCpg.graph._nodes(39).asInstanceOf[Iterator[nodes.TypeDecl]]
602598

603599
/** Shorthand for typeDecl.name */
604600
def typeDecl(name: String): Iterator[nodes.TypeDecl] = typeDecl.name(name)
@@ -614,19 +610,19 @@ languages that support type parameters are Java (via Generics) and C++
614610
(via templates). Apart from the standard fields of AST nodes, the type
615611
parameter carries only a `NAME` field that holds the parameters name.""")
616612
def typeParameter: Iterator[nodes.TypeParameter] =
617-
wrappedCpg.graph._nodes(41).asInstanceOf[Iterator[nodes.TypeParameter]]
613+
wrappedCpg.graph._nodes(40).asInstanceOf[Iterator[nodes.TypeParameter]]
618614

619615
/** Reference to a type/class */
620616
@flatgraph.help.Doc(info = """Reference to a type/class""")
621-
def typeRef: Iterator[nodes.TypeRef] = wrappedCpg.graph._nodes(42).asInstanceOf[Iterator[nodes.TypeRef]]
617+
def typeRef: Iterator[nodes.TypeRef] = wrappedCpg.graph._nodes(41).asInstanceOf[Iterator[nodes.TypeRef]]
622618

623619
/** Any AST node that the frontend would like to include in the AST but for which no suitable AST node is specified in
624620
* the CPG specification may be included using a node of type `UNKNOWN`.
625621
*/
626622
@flatgraph.help.Doc(info = """Any AST node that the frontend would like to include in the AST but for
627623
which no suitable AST node is specified in the CPG specification may be
628624
included using a node of type `UNKNOWN`.""")
629-
def unknown: Iterator[nodes.Unknown] = wrappedCpg.graph._nodes(43).asInstanceOf[Iterator[nodes.Unknown]]
625+
def unknown: Iterator[nodes.Unknown] = wrappedCpg.graph._nodes(42).asInstanceOf[Iterator[nodes.Unknown]]
630626

631627
/** This is the base type for all nodes of the abstract syntax tree (AST). An AST node has a `CODE` and an `ORDER`
632628
* field. The `CODE` field contains the code (verbatim) represented by the AST node. The `ORDER` field contains the

0 commit comments

Comments
 (0)