Java/Kotlin: Enhance 'compilations' support

This commit is contained in:
Ian Lynagh
2021-09-08 11:48:31 +01:00
parent 9e4614e574
commit 651847d202
3 changed files with 115 additions and 1 deletions

View File

@@ -17,9 +17,16 @@ compilations(
* javac A.java B.java C.java
*/
unique int id : @compilation,
string cwd : string ref
int kind: int ref,
string cwd : string ref,
string name : string ref
);
case @compilation.kind of
1 = @javacompilation
| 2 = @kotlincompilation
;
compilation_started(
int id : @compilation ref
)

View File

@@ -5,6 +5,7 @@ import semmle.code.FileSystem
import semmle.code.Location
import semmle.code.Unit
import semmle.code.java.Annotation
import semmle.code.java.Compilation
import semmle.code.java.CompilationUnit
import semmle.code.java.ControlFlowGraph
import semmle.code.java.Dependency

View File

@@ -0,0 +1,106 @@
/**
* Provides a class representing individual compiler invocations that occurred during the build.
*/
import semmle.code.FileSystem
/**
* An invocation of the compiler. Note that more than one file may be
* compiled per invocation. For example, this command compiles three
* source files:
*
* javac Foo.java Bar.java Baz.java
*
* Two things happen to each file during a compilation:
*
* 1. The file is compiled by a real compiler, such as javac or kotlinc.
* 2. The file is parsed by the CodeQL front-end.
* 3. The parsed representation is converted to database tables by
* the CodeQL extractor.
*
* This class provides CPU and elapsed time information for steps 2 and 3,
* but not for step 1.
*/
class Compilation extends @compilation {
/** Gets a textual representation of this element. */
string toString() {
exists(string name |
compilations(this, _, _, name) and
result = "<compilation " + name + ">"
)
}
/** Gets a file compiled during this invocation. */
File getAFileCompiled() { result = getFileCompiled(_) }
/** Gets the `i`th file compiled during this invocation */
File getFileCompiled(int i) { compilation_compiling_files(this, i, result) }
/**
* Gets the amount of CPU time spent processing file number `i` in the
* front-end.
*/
float getFrontendCpuSeconds(int i) { compilation_time(this, i, 1, result) }
/**
* Gets the amount of elapsed time while processing file number `i` in the
* front-end.
*/
float getFrontendElapsedSeconds(int i) { compilation_time(this, i, 2, result) }
/**
* Gets the amount of CPU time spent processing file number `i` in the
* extractor.
*/
float getExtractorCpuSeconds(int i) { compilation_time(this, i, 3, result) }
/**
* Gets the amount of elapsed time while processing file number `i` in the
* extractor.
*/
float getExtractorElapsedSeconds(int i) { compilation_time(this, i, 4, result) }
/**
* Gets an argument passed to the extractor on this invocation.
*/
string getAnArgument() { result = getArgument(_) }
/**
* Gets the `i`th argument passed to the extractor on this invocation.
*/
string getArgument(int i) { compilation_args(this, i, result) }
/**
* Gets the total amount of CPU time spent processing all the files in the
* front-end and extractor.
*/
float getTotalCpuSeconds() { compilation_finished(this, result, _) }
/**
* Gets the total amount of elapsed time while processing all the files in
* the front-end and extractor.
*/
float getTotalElapsedSeconds() { compilation_finished(this, _, result) }
/**
* Holds if this is a compilation of Java code.
*/
predicate isJava() { this instanceof @javacompilation }
/**
* Holds if this is a compilation of Kotlin code.
*/
predicate isKotlin() { this instanceof @kotlincompilation }
/**
* Holds if extraction for the compilation started.
*/
predicate extractionStarted() { compilation_started(this) }
/**
* Holds if the extractor terminated normally. Terminating with an exit
* code indicating that an error occurred is considered normal
* termination, but crashing due to something like a segfault is not.
*/
predicate normalTermination() { compilation_finished(this, _, _) }
}