PS: Add 'raw' AST classes coming directly from the extractor.

This commit is contained in:
Mathias Vorreiter Pedersen
2025-03-26 18:04:34 +00:00
parent 665202195c
commit a207c8008b
86 changed files with 3453 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
private import Raw
class ArrayExpr extends @array_expression, Expr {
override SourceLocation getLocation() { array_expression_location(this, result) }
StmtBlock getStmtBlock() { array_expression(this, result) }
final override Ast getChild(ChildIndex i) {
i = ArrayExprStmtBlock() and result = this.getStmtBlock()
}
}

View File

@@ -0,0 +1,16 @@
private import Raw
class ArrayLiteral extends @array_literal, Expr {
override SourceLocation getLocation() { array_literal_location(this, result) }
Expr getElement(int index) { array_literal_element(this, index, result) }
Expr getAnElement() { array_literal_element(this, _, result) }
final override Ast getChild(ChildIndex i) {
exists(int index |
i = ArrayLiteralExpr(index) and
result = this.getElement(index)
)
}
}

View File

@@ -0,0 +1,19 @@
private import Raw
class AssignStmt extends @assignment_statement, PipelineBase {
override SourceLocation getLocation() { assignment_statement_location(this, result) }
int getKind() { assignment_statement(this, result, _, _) }
Expr getLeftHandSide() { assignment_statement(this, _, result, _) }
Stmt getRightHandSide() { assignment_statement(this, _, _, result) }
final override Ast getChild(ChildIndex i) {
i = AssignStmtLeftHandSide() and
result = this.getLeftHandSide()
or
i = AssignStmtRightHandSide() and
result = this.getRightHandSide()
}
}

View File

@@ -0,0 +1,17 @@
private import Raw
import Location
private import Scope
class Ast extends @ast {
final string toString() { none() }
final Ast getParent() { result.getAChild() = this }
Ast getChild(ChildIndex i) { none() }
final Ast getAChild() { result = this.getChild(_) }
Location getLocation() { none() }
Scope getScope() { result = scopeOf(this) }
}

View File

@@ -0,0 +1,33 @@
private import Raw
class Attribute extends @attribute, AttributeBase {
override SourceLocation getLocation() { attribute_location(this, result) }
string getName() { attribute(this, result, _, _) }
int getNumNamedArguments() { attribute(this, _, result, _) }
int getNumPositionalArguments() { attribute(this, _, _, result) }
NamedAttributeArgument getNamedArgument(int i) { attribute_named_argument(this, i, result) }
final override Ast getChild(ChildIndex i) {
exists(int index |
i = AttributeNamedArg(index) and
result = this.getNamedArgument(index)
or
i = AttributePosArg(index) and
result = this.getPositionalArgument(index)
)
}
NamedAttributeArgument getANamedArgument() { result = this.getNamedArgument(_) }
int getNumberOfArguments() { result = count(this.getAPositionalArgument()) }
Expr getPositionalArgument(int i) { attribute_positional_argument(this, i, result) }
Expr getAPositionalArgument() { result = this.getPositionalArgument(_) }
int getNumberOfPositionalArguments() { result = count(this.getAPositionalArgument()) }
}

View File

@@ -0,0 +1,3 @@
private import Raw
class AttributeBase extends @attribute_base, Ast { }

View File

@@ -0,0 +1,17 @@
private import Raw
class AttributedExpr extends AttributedExprBase, @attributed_expression {
final override Expr getExpr() { attributed_expression(this, _, result) }
final override Attribute getAttribute() { attributed_expression(this, result, _) }
override Location getLocation() { attributed_expression_location(this, result) }
override Ast getChild(ChildIndex i) {
i = AttributedExprExpr() and
result = this.getExpr()
or
i = AttributedExprAttr() and
result = this.getAttribute()
}
}

View File

@@ -0,0 +1,7 @@
private import Raw
class AttributedExprBase extends @attributed_expression_ast, Expr {
Expr getExpr() { none() }
AttributeBase getAttribute() { none() }
}

View File

@@ -0,0 +1,10 @@
private import Raw
/** The base class for constant expressions. */
class BaseConstExpr extends @base_constant_expression, Expr {
/** Gets the type of this constant expression. */
string getType() { none() }
/** Gets a string literal of this constant expression. */
StringLiteral getValue() { none() }
}

View File

@@ -0,0 +1,35 @@
private import Raw
class BinaryExpr extends @binary_expression, Expr {
override SourceLocation getLocation() { binary_expression_location(this, result) }
int getKind() { binary_expression(this, result, _, _) }
/** Gets an operand of this binary expression. */
Expr getAnOperand() {
result = this.getLeft()
or
result = this.getRight()
}
final override Ast getChild(ChildIndex i) {
i = BinaryExprLeft() and
result = this.getLeft()
or
i = BinaryExprRight() and
result = this.getRight()
}
/** Holds if this binary expression has the operands `e1` and `e2`. */
predicate hasOperands(Expr e1, Expr e2) {
e1 = this.getLeft() and
e2 = this.getRight()
or
e1 = this.getRight() and
e2 = this.getLeft()
}
Expr getLeft() { binary_expression(this, _, result, _) }
Expr getRight() { binary_expression(this, _, _, result) }
}

View File

@@ -0,0 +1,5 @@
import Raw
class BreakStmt extends GotoStmt, @break_statement {
override SourceLocation getLocation() { break_statement_location(this, result) }
}

View File

@@ -0,0 +1,25 @@
private import Raw
class CatchClause extends @catch_clause, Ast {
override SourceLocation getLocation() { catch_clause_location(this, result) }
StmtBlock getBody() { catch_clause(this, result, _) }
final override Ast getChild(ChildIndex i) {
i = CatchClauseBody() and
result = this.getBody()
or
exists(int index |
i = CatchClauseType(index) and
result = this.getCatchType(index)
)
}
TypeConstraint getCatchType(int i) { catch_clause_catch_type(this, i, result) }
int getNumberOfCatchTypes() { result = count(this.getACatchType()) }
TypeConstraint getACatchType() { result = this.getCatchType(_) }
predicate isCatchAll() { not exists(this.getACatchType()) }
}

View File

@@ -0,0 +1,3 @@
private import Raw
class Chainable extends @chainable, PipelineBase { }

View File

@@ -0,0 +1,101 @@
private import Raw
newtype ChildIndex =
ArrayExprStmtBlock() or
ArrayLiteralExpr(int i) { exists(any(ArrayLiteral lit).getElement(i)) } or
AssignStmtLeftHandSide() or
AssignStmtRightHandSide() or
AttributeNamedArg(int i) { exists(any(Attribute a).getNamedArgument(i)) } or
AttributePosArg(int i) { exists(any(Attribute a).getPositionalArgument(i)) } or
AttributedExprExpr() or
AttributedExprAttr() or
BinaryExprLeft() or
BinaryExprRight() or
CatchClauseBody() or
CatchClauseType(int i) { exists(any(CatchClause c).getCatchType(i)) } or
CmdElement_(int i) { exists(any(Cmd cmd).getElement(i)) } or // TODO: Get rid of this?
CmdCallee() or
CmdRedirection(int i) { exists(any(Cmd cmd).getRedirection(i)) } or
CmdExprExpr() or
ConfigurationName() or
ConfigurationBody() or
ConvertExprExpr() or
ConvertExprType() or
ConvertExprAttr() or
DataStmtBody() or
DataStmtCmdAllowed(int i) { exists(any(DataStmt d).getCmdAllowed(i)) } or
DoUntilStmtCond() or
DoUntilStmtBody() or
DoWhileStmtCond() or
DoWhileStmtBody() or
DynamicStmtName() or
DynamicStmtBody() or
ExitStmtPipeline() or
ExpandableStringExprExpr(int i) { exists(any(ExpandableStringExpr e).getExpr(i)) } or
ForEachStmtVar() or
ForEachStmtIter() or
ForEachStmtBody() or
ForStmtInit() or
ForStmtCond() or
ForStmtIter() or
ForStmtBody() or
FunDefStmtBody() or
FunDefStmtParam(int i) { exists(any(FunctionDefinitionStmt def).getParameter(i)) } or
GotoStmtLabel() or
HashTableExprKey(int i) { exists(any(HashTableExpr e).getKey(i)) } or
HashTableExprStmt(int i) { exists(any(HashTableExpr e).getStmt(i)) } or
IfStmtElse() or
IfStmtCond(int i) { exists(any(IfStmt ifstmt).getCondition(i)) } or
IfStmtThen(int i) { exists(any(IfStmt ifstmt).getThen(i)) } or
IndexExprIndex() or
IndexExprBase() or
InvokeMemberExprQual() or
InvokeMemberExprCallee() or
InvokeMemberExprArg(int i) { exists(any(InvokeMemberExpr e).getArgument(i)) } or
MemberExprQual() or
MemberExprMember() or
NamedAttributeArgVal() or
MemberAttr(int i) { exists(any(Member m).getAttribute(i)) } or
MemberTypeConstraint() or
NamedBlockStmt(int i) { exists(any(NamedBlock b).getStmt(i)) } or
NamedBlockTrap(int i) { exists(any(NamedBlock b).getTrap(i)) } or
ParamBlockAttr(int i) { exists(any(ParamBlock p).getAttribute(i)) } or
ParamBlockParam(int i) { exists(any(ParamBlock p).getParameter(i)) } or
ParamAttr(int i) { exists(any(Parameter p).getAttribute(i)) } or
ParamDefaultVal() or
ParenExprExpr() or
PipelineComp(int i) { exists(any(Pipeline p).getComponent(i)) } or
PipelineChainLeft() or
PipelineChainRight() or
ReturnStmtPipeline() or
RedirectionExpr() or
ScriptBlockUsing(int i) { exists(any(ScriptBlock s).getUsing(i)) } or
ScriptBlockParamBlock() or
ScriptBlockBeginBlock() or
ScriptBlockCleanBlock() or
ScriptBlockDynParamBlock() or
ScriptBlockEndBlock() or
ScriptBlockProcessBlock() or
ScriptBlockExprBody() or
StmtBlockStmt(int i) { exists(any(StmtBlock b).getStmt(i)) } or
StmtBlockTrapStmt(int i) { exists(any(StmtBlock b).getTrapStmt(i)) } or
ExpandableSubExprExpr() or
SwitchStmtCond() or
SwitchStmtDefault() or
SwitchStmtCase(int i) { exists(any(SwitchStmt s).getCase(i)) } or
SwitchStmtPat(int i) { exists(any(SwitchStmt s).getPattern(i)) } or
CondExprCond() or
CondExprTrue() or
CondExprFalse() or
ThrowStmtPipeline() or
TryStmtBody() or
TryStmtCatchClause(int i) { exists(any(TryStmt t).getCatchClause(i)) } or
TryStmtFinally() or
TypeStmtMember(int i) { exists(any(TypeStmt t).getMember(i)) } or
TypeStmtBaseType(int i) { exists(any(TypeStmt t).getBaseType(i)) } or
TrapStmtBody() or
TrapStmtTypeConstraint() or
UnaryExprOp() or
UsingExprExpr() or
WhileStmtCond() or
WhileStmtBody()

View File

@@ -0,0 +1,105 @@
private import Raw
private predicate parseCommandName(Cmd cmd, string namespace, string name) {
exists(string qualified | command(cmd, qualified, _, _, _) |
namespace = qualified.regexpCapture("([^\\\\]+)\\\\([^\\\\]+)", 1) and
name = qualified.regexpCapture("([^\\\\]+)\\\\([^\\\\]+)", 2)
or
// Not a qualified name
not exists(qualified.indexOf("\\")) and
namespace = "" and
name = qualified
)
}
/** A call to a command. */
class Cmd extends @command, CmdBase {
override SourceLocation getLocation() { command_location(this, result) }
final override Ast getChild(ChildIndex i) {
exists(int index |
i = CmdElement_(index) and
result = this.getElement(index)
or
i = CmdRedirection(index) and
result = this.getRedirection(index)
)
}
// TODO: This only make sense for some commands (e.g., not dot-sourcing)
CmdElement getCallee() { result = this.getElement(0) }
/** Gets the name of the command without any qualifiers. */
string getCommandName() { parseCommandName(this, _, result) }
/** Holds if the command is qualified. */
predicate isQualified() { parseCommandName(this, any(string s | s != ""), _) }
/** Gets the (possibly qualified) name of this command. */
string getQualifiedCommandName() { command(this, result, _, _, _) }
int getKind() { command(this, _, result, _, _) }
int getNumElements() { command(this, _, _, result, _) }
int getNumRedirection() { command(this, _, _, _, result) }
CmdElement getElement(int i) { command_command_element(this, i, result) }
/** Gets the expression that determines the command to invoke. */
Expr getCommand() { result = this.getElement(0) }
Redirection getRedirection(int i) { command_redirection(this, i, result) }
Redirection getARedirection() { result = this.getRedirection(_) }
Expr getArgument(int i) {
result =
rank[i + 1](CmdElement e, Expr r, int j |
(
// For most commands the 0'th element is the command name ...
j > 0
or
// ... but for certain commands (such as the call operator or the dot-
// sourcing operator) the 0'th element is not the command name, but
// rather the thing to invoke. These all appear to be commands with
// an empty string as the command name.
this.getCommandName() = ""
) and
e = this.getElement(j) and
(
not e instanceof CmdParameter and
r = e
or
r = e.(CmdParameter).getExpr()
)
|
r order by j
)
}
Expr getNamedArgument(string name) {
exists(CmdParameter p, int index |
result = this.getArgument(index) and
p.getName() = name
|
p.getExpr() = result
or
exists(int jndex |
not exists(p.getExpr()) and
this.getElement(jndex) = p and
this.getElement(jndex + 1) = result
)
)
}
}
/** A call to operator `&`. */
class CallOperator extends Cmd {
CallOperator() { this.getKind() = 28 }
}
/** A call to the dot-sourcing `.`. */
class DotSourcingOperator extends Cmd {
DotSourcingOperator() { this.getKind() = 35 }
}

View File

@@ -0,0 +1,3 @@
private import Raw
class CmdBase extends @command_base, Chainable { }

View File

@@ -0,0 +1,3 @@
private import Raw
class CmdElement extends @command_element, Ast { }

View File

@@ -0,0 +1,18 @@
private import Raw
class CmdExpr extends @command_expression, CmdBase {
override SourceLocation getLocation() { command_expression_location(this, result) }
Expr getExpr() { command_expression(this, result, _) }
final override Ast getChild(ChildIndex i) {
i = CmdExprExpr() and
result = this.getExpr()
}
int getNumRedirections() { command_expression(this, _, result) }
Redirection getRedirection(int i) { command_expression_redirection(this, i, result) }
Redirection getARedirection() { result = this.getRedirection(_) }
}

View File

@@ -0,0 +1,13 @@
private import Raw
class CmdParameter extends @command_parameter, CmdElement {
override SourceLocation getLocation() { command_parameter_location(this, result) }
string getName() { command_parameter(this, result) }
Ast getExpr() {
command_parameter_argument(this, result)
}
Cmd getCmd() { result.getElement(_) = this }
}

View File

@@ -0,0 +1,17 @@
private import Raw
class Comment extends @comment_entity {
Location getLocation() { comment_entity_location(this, result) }
StringLiteral getCommentContents() { comment_entity(this, result) }
string toString() { result = this.getCommentContents().toString() }
}
class SingleLineComment extends Comment {
SingleLineComment() { this.getCommentContents().getNumContinuations() = 1 }
}
class MultiLineComment extends Comment {
MultiLineComment() { this.getCommentContents().getNumContinuations() > 1 }
}

View File

@@ -0,0 +1,21 @@
private import Raw
class Configuration extends @configuration_definition, Stmt {
override SourceLocation getLocation() { configuration_definition_location(this, result) }
Expr getName() { configuration_definition(this, _, _, result) }
ScriptBlockExpr getBody() { configuration_definition(this, result, _, _) }
final override Ast getChild(ChildIndex i) {
i = ConfigurationName() and
result = this.getName()
or
i = ConfigurationBody() and
result = this.getBody()
}
predicate isMeta() { configuration_definition(this, _, 1, _) }
predicate isResource() { configuration_definition(this, _, 0, _) }
}

View File

@@ -0,0 +1,9 @@
private import Raw
class ConstExpr extends @constant_expression, BaseConstExpr {
override SourceLocation getLocation() { constant_expression_location(this, result) }
override string getType() { constant_expression(this, result) }
override StringLiteral getValue() { constant_expression_value(this, result) }
}

View File

@@ -0,0 +1,5 @@
private import Raw
class ContinueStmt extends GotoStmt, @continue_statement {
override SourceLocation getLocation() { continue_statement_location(this, result) }
}

View File

@@ -0,0 +1,22 @@
private import Raw
class ConvertExpr extends @convert_expression, AttributedExprBase {
override SourceLocation getLocation() { convert_expression_location(this, result) }
final override Expr getExpr() { convert_expression(this, _, result, _, _) }
TypeConstraint getType() { convert_expression(this, _, _, result, _) }
final override AttributeBase getAttribute() { convert_expression(this, result, _, _, _) }
final override Ast getChild(ChildIndex i) {
i = ConvertExprExpr() and
result = this.getExpr()
or
i = ConvertExprType() and
result = this.getType()
or
i = ConvertExprAttr() and
result = this.getAttribute()
}
}

View File

@@ -0,0 +1,23 @@
private import Raw
class DataStmt extends @data_statement, Stmt {
override SourceLocation getLocation() { data_statement_location(this, result) }
string getVariableName() { data_statement_variable(this, result) }
Expr getCmdAllowed(int i) { data_statement_commands_allowed(this, i, result) }
Expr getACmdAllowed() { result = this.getCmdAllowed(_) }
StmtBlock getBody() { data_statement(this, result) }
final override Ast getChild(ChildIndex i) {
i = DataStmtBody() and
result = this.getBody()
or
exists(int index |
i = DataStmtCmdAllowed(index) and
result = this.getCmdAllowed(index)
)
}
}

View File

@@ -0,0 +1,17 @@
private import Raw
class DoUntilStmt extends @do_until_statement, LoopStmt {
override SourceLocation getLocation() { do_until_statement_location(this, result) }
PipelineBase getCondition() { do_until_statement_condition(this, result) }
final override StmtBlock getBody() { do_until_statement(this, result) }
final override Ast getChild(ChildIndex i) {
i = DoUntilStmtCond() and
result = this.getCondition()
or
i = DoUntilStmtBody() and
result = this.getBody()
}
}

View File

@@ -0,0 +1,17 @@
private import Raw
class DoWhileStmt extends @do_while_statement, LoopStmt {
override SourceLocation getLocation() { do_while_statement_location(this, result) }
PipelineBase getCondition() { do_while_statement_condition(this, result) }
final override StmtBlock getBody() { do_while_statement(this, result) }
final override Ast getChild(ChildIndex i) {
i = DoWhileStmtCond() and
result = this.getCondition()
or
i = DoWhileStmtBody() and
result = this.getBody()
}
}

View File

@@ -0,0 +1,27 @@
private import Raw
class DynamicStmt extends @dynamic_keyword_statement, Stmt {
override SourceLocation getLocation() { dynamic_keyword_statement_location(this, result) }
CmdElement getName() { dynamic_keyword_statement_command_elements(this, 1, result) }
ScriptBlockExpr getScriptBlock() { dynamic_keyword_statement_command_elements(this, 2, result) }
HashTableExpr getHashTableExpr() { dynamic_keyword_statement_command_elements(this, 2, result) }
predicate hasScriptBlock() { exists(this.getScriptBlock()) }
predicate hasHashTableExpr() { exists(this.getHashTableExpr()) }
final override Ast getChild(ChildIndex i) {
i = DynamicStmtName() and
result = this.getName()
or
i = DynamicStmtBody() and
(
result = this.getScriptBlock()
or
result = this.getHashTableExpr()
)
}
}

View File

@@ -0,0 +1,5 @@
private import Raw
class ErrorExpr extends @error_expression, Expr {
final override SourceLocation getLocation() { error_expression_location(this, result) }
}

View File

@@ -0,0 +1,5 @@
private import Raw
class ErrorStmt extends @error_statement, PipelineBase {
final override SourceLocation getLocation() { error_statement_location(this, result) }
}

View File

@@ -0,0 +1,14 @@
private import Raw
class ExitStmt extends @exit_statement, Stmt {
override SourceLocation getLocation() { exit_statement_location(this, result) }
/** ..., if any. */
PipelineBase getPipeline() { exit_statement_pipeline(this, result) }
predicate hasPipeline() { exists(this.getPipeline()) }
final override Ast getChild(ChildIndex i) {
i = ExitStmtPipeline() and result = this.getPipeline()
}
}

View File

@@ -0,0 +1,20 @@
private import Raw
class ExpandableStringExpr extends @expandable_string_expression, Expr {
override SourceLocation getLocation() { expandable_string_expression_location(this, result) }
StringLiteral getUnexpandedValue() { expandable_string_expression(this, result, _, _) }
int getNumExprs() { result = count(this.getAnExpr()) }
Expr getExpr(int i) { expandable_string_expression_nested_expression(this, i, result) }
Expr getAnExpr() { result = this.getExpr(_) }
final override Ast getChild(ChildIndex i) {
exists(int index |
i = ExpandableStringExprExpr(index) and
result = this.getExpr(index)
)
}
}

View File

@@ -0,0 +1,8 @@
private import Raw
/**
* An expression.
*
* This is the topmost class in the hierachy of all expression in PowerShell.
*/
class Expr extends @expression, CmdElement { }

View File

@@ -0,0 +1,224 @@
/**
* Provides classes representing filesystem files and folders.
* Based on csharp/ql/lib/semmle/code/csharp/File.qll
*/
/** A file or folder. */
class Container extends @container {
/**
* Gets the absolute, canonical path of this container, using forward slashes
* as path separator.
*
* The path starts with a _root prefix_ followed by zero or more _path
* segments_ separated by forward slashes.
*
* The root prefix is of one of the following forms:
*
* 1. A single forward slash `/` (Unix-style)
* 2. An upper-case drive letter followed by a colon and a forward slash,
* such as `C:/` (Windows-style)
* 3. Two forward slashes, a computer name, and then another forward slash,
* such as `//FileServer/` (UNC-style)
*
* Path segments are never empty (that is, absolute paths never contain two
* contiguous slashes, except as part of a UNC-style root prefix). Also, path
* segments never contain forward slashes, and no path segment is of the
* form `.` (one dot) or `..` (two dots).
*
* Note that an absolute path never ends with a forward slash, except if it is
* a bare root prefix, that is, the path has no path segments. A container
* whose absolute path has no segments is always a `Folder`, not a `File`.
*/
string getAbsolutePath() { none() }
/**
* Gets a URL representing the location of this container.
*
* For more information see [Providing URLs](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls).
*/
string getURL() { none() }
/**
* Gets the relative path of this file or folder from the root folder of the
* analyzed source location. The relative path of the root folder itself is
* the empty string.
*
* This has no result if the container is outside the source root, that is,
* if the root folder is not a reflexive, transitive parent of this container.
*/
string getRelativePath() {
exists(string absPath, string pref |
absPath = this.getAbsolutePath() and sourceLocationPrefix(pref)
|
absPath = pref and result = ""
or
absPath = pref.regexpReplaceAll("/$", "") + "/" + result and
not result.matches("/%")
)
}
/**
* Gets the base name of this container including extension, that is, the last
* segment of its absolute path, or the empty string if it has no segments.
*
* Here are some examples of absolute paths and the corresponding base names
* (surrounded with quotes to avoid ambiguity):
*
* <table border="1">
* <tr><th>Absolute path</th><th>Base name</th></tr>
* <tr><td>"/tmp/tst.sql"</td><td>"tst.sql"</td></tr>
* <tr><td>"C:/Program Files (x86)"</td><td>"Program Files (x86)"</td></tr>
* <tr><td>"/"</td><td>""</td></tr>
* <tr><td>"C:/"</td><td>""</td></tr>
* <tr><td>"D:/"</td><td>""</td></tr>
* <tr><td>"//FileServer/"</td><td>""</td></tr>
* </table>
*/
string getBaseName() {
result = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
}
/**
* Gets the extension of this container, that is, the suffix of its base name
* after the last dot character, if any.
*
* In particular,
*
* - if the name does not include a dot, there is no extension, so this
* predicate has no result;
* - if the name ends in a dot, the extension is the empty string;
* - if the name contains multiple dots, the extension follows the last dot.
*
* Here are some examples of absolute paths and the corresponding extensions
* (surrounded with quotes to avoid ambiguity):
*
* <table border="1">
* <tr><th>Absolute path</th><th>Extension</th></tr>
* <tr><td>"/tmp/tst.cs"</td><td>"cs"</td></tr>
* <tr><td>"/tmp/.classpath"</td><td>"classpath"</td></tr>
* <tr><td>"/bin/bash"</td><td>not defined</td></tr>
* <tr><td>"/tmp/tst2."</td><td>""</td></tr>
* <tr><td>"/tmp/x.tar.gz"</td><td>"gz"</td></tr>
* </table>
*/
string getExtension() {
result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3)
}
/**
* Gets the stem of this container, that is, the prefix of its base name up to
* (but not including) the last dot character if there is one, or the entire
* base name if there is not.
*
* Here are some examples of absolute paths and the corresponding stems
* (surrounded with quotes to avoid ambiguity):
*
* <table border="1">
* <tr><th>Absolute path</th><th>Stem</th></tr>
* <tr><td>"/tmp/tst.cs"</td><td>"tst"</td></tr>
* <tr><td>"/tmp/.classpath"</td><td>""</td></tr>
* <tr><td>"/bin/bash"</td><td>"bash"</td></tr>
* <tr><td>"/tmp/tst2."</td><td>"tst2"</td></tr>
* <tr><td>"/tmp/x.tar.gz"</td><td>"x.tar"</td></tr>
* </table>
*/
string getStem() {
result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1)
}
/** Gets the parent container of this file or folder, if any. */
Container getParentContainer() { containerparent(result, this) }
/** Gets a file or sub-folder in this container. */
Container getAChildContainer() { this = result.getParentContainer() }
/** Gets a file in this container. */
File getAFile() { result = this.getAChildContainer() }
/** Gets the file in this container that has the given `baseName`, if any. */
File getFile(string baseName) {
result = this.getAFile() and
result.getBaseName() = baseName
}
/** Gets a sub-folder in this container. */
Folder getAFolder() { result = this.getAChildContainer() }
/** Gets the sub-folder in this container that has the given `baseName`, if any. */
Folder getFolder(string baseName) {
result = this.getAFolder() and
result.getBaseName() = baseName
}
/** Gets the file or sub-folder in this container that has the given `name`, if any. */
Container getChildContainer(string name) {
result = this.getAChildContainer() and
result.getBaseName() = name
}
/** Gets the file in this container that has the given `stem` and `extension`, if any. */
File getFile(string stem, string extension) {
result = this.getAChildContainer() and
result.getStem() = stem and
result.getExtension() = extension
}
/** Gets a sub-folder contained in this container. */
Folder getASubFolder() { result = this.getAChildContainer() }
/**
* Gets a textual representation of the path of this container.
*
* This is the absolute path of the container.
*/
string toString() { result = this.getAbsolutePath() }
}
/** A folder. */
class Folder extends Container, @folder {
override string getAbsolutePath() { folders(this, result) }
override string getURL() { result = "folder://" + this.getAbsolutePath() }
}
/** A file. */
class File extends Container, @file {
override string getAbsolutePath() { files(this, result) }
/** Gets the number of lines in this file. */
int getNumberOfLines() { numlines(this, result, _, _) }
/** Gets the number of lines containing code in this file. */
int getNumberOfLinesOfCode() { numlines(this, _, result, _) }
/** Gets the number of lines containing comments in this file. */
int getNumberOfLinesOfComments() { numlines(this, _, _, result) }
override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" }
/** Holds if this file is a QL test stub file. */
pragma[noinline]
private predicate isStub() {
// this.extractedQlTest() and
this.getAbsolutePath().matches("%resources/stubs/%")
}
/** Holds if this file contains source code. */
predicate fromSource() {
this.getExtension() = "cs" and
not this.isStub()
}
/** Holds if this file is a library. */
predicate fromLibrary() {
not this.getBaseName() = "" and
not this.fromSource()
}
}
/**
* A source file.
*/
class SourceFile extends File {
SourceFile() { this.fromSource() }
}

View File

@@ -0,0 +1,5 @@
private import Raw
class FileRedirection extends @file_redirection, Redirection {
override Location getLocation() { file_redirection_location(this, result) }
}

View File

@@ -0,0 +1,21 @@
private import Raw
class ForEachStmt extends @foreach_statement, LoopStmt {
override SourceLocation getLocation() { foreach_statement_location(this, result) }
final override StmtBlock getBody() { foreach_statement(this, _, _, result, _) }
VarAccess getVarAccess() { foreach_statement(this, result, _, _, _) }
PipelineBase getIterableExpr() { foreach_statement(this, _, result, _, _) }
predicate isParallel() { foreach_statement(this, _, _, _, 1) }
final override Ast getChild(ChildIndex i) {
i = ForEachStmtVar() and result = this.getVarAccess()
or
i = ForEachStmtIter() and result = this.getIterableExpr()
or
i = ForEachStmtBody() and result = this.getBody()
}
}

View File

@@ -0,0 +1,27 @@
private import Raw
class ForStmt extends @for_statement, LoopStmt {
override SourceLocation getLocation() { for_statement_location(this, result) }
PipelineBase getInitializer() { for_statement_initializer(this, result) }
PipelineBase getCondition() { for_statement_condition(this, result) }
PipelineBase getIterator() { for_statement_iterator(this, result) }
final override StmtBlock getBody() { for_statement(this, result) }
final override Ast getChild(ChildIndex i) {
i = ForStmtInit() and
result = this.getInitializer()
or
i = ForStmtCond() and
result = this.getCondition()
or
i = ForStmtIter() and
result = this.getIterator()
or
i = ForStmtBody() and
result = this.getBody()
}
}

View File

@@ -0,0 +1,22 @@
private import Raw
class FunctionDefinitionStmt extends @function_definition, Stmt {
override Location getLocation() { function_definition_location(this, result) }
ScriptBlock getBody() { function_definition(this, result, _, _, _) }
string getName() { function_definition(this, _, result, _, _) }
Parameter getParameter(int i) { function_definition_parameter(this, i, result) }
Parameter getAParameter() { result = this.getParameter(_) }
override Ast getChild(ChildIndex i) {
i = FunDefStmtBody() and result = this.getBody()
or
exists(int index |
i = FunDefStmtParam(index) and
result = this.getParameter(index)
)
}
}

View File

@@ -0,0 +1,9 @@
private import Raw
/** A `break` or `continue` statement. */
class GotoStmt extends @labelled_statement, Stmt {
/** ..., if any. */
Expr getLabel() { statement_label(this, result) }
final override Ast getChild(ChildIndex i) { i = GotoStmtLabel() and result = this.getLabel() }
}

View File

@@ -0,0 +1,23 @@
private import Raw
class HashTableExpr extends @hash_table, Expr {
final override Location getLocation() { hash_table_location(this, result) }
Expr getKey(int i) { hash_table_key_value_pairs(this, i, result, _) }
Expr getAKey() { result = this.getKey(_) }
Stmt getStmt(int i) { hash_table_key_value_pairs(this, i, _, result) }
Stmt getAStmt() { result = this.getStmt(_) }
final override Ast getChild(ChildIndex i) {
exists(int index |
i = HashTableExprKey(index) and
result = this.getKey(index)
or
i = HashTableExprStmt(index) and
result = this.getStmt(index)
)
}
}

View File

@@ -0,0 +1,33 @@
private import Raw
class IfStmt extends @if_statement, Stmt {
override SourceLocation getLocation() { if_statement_location(this, result) }
PipelineBase getCondition(int i) { if_statement_clause(this, i, result, _) }
PipelineBase getACondition() { result = this.getCondition(_) }
StmtBlock getThen(int i) { if_statement_clause(this, i, _, result) }
int getNumberOfConditions() { result = count(this.getACondition()) }
StmtBlock getAThen() { result = this.getThen(_) }
/** ..., if any. */
StmtBlock getElse() { if_statement_else(this, result) }
predicate hasElse() { exists(this.getElse()) }
final override Ast getChild(ChildIndex i) {
i = IfStmtElse() and
result = this.getElse()
or
exists(int index |
i = IfStmtCond(index) and
result = this.getCondition(index)
or
i = IfStmtThen(index) and
result = this.getThen(index)
)
}
}

View File

@@ -0,0 +1,18 @@
private import Raw
class IndexExpr extends @index_expression, Expr {
override SourceLocation getLocation() { index_expression_location(this, result) }
Expr getIndex() { index_expression(this, result, _, _) } // TODO: Change @ast to @expr in the dbscheme
Expr getBase() { index_expression(this, _, result, _) } // TODO: Change @ast to @expr in the dbscheme
predicate isNullConditional() { index_expression(this, _, _, true) }
final override Ast getChild(ChildIndex i) {
i = IndexExprIndex() and
result = this.getIndex()
or
i = IndexExprBase() and result = this.getBase()
}
}

View File

@@ -0,0 +1,32 @@
private import Raw
class InvokeMemberExpr extends @invoke_member_expression, MemberExprBase {
override SourceLocation getLocation() { invoke_member_expression_location(this, result) }
Expr getQualifier() { invoke_member_expression(this, result, _) }
string getName() { result = this.getCallee().(StringConstExpr).getValue().getValue() }
Expr getCallee() { invoke_member_expression(this, _, result) }
string getMemberName() { result = this.getCallee().(StringConstExpr).getValue().getValue() }
Expr getArgument(int i) { invoke_member_expression_argument(this, i, result) }
Expr getAnArgument() { invoke_member_expression_argument(this, _, result) }
final override Ast getChild(ChildIndex i) {
i = InvokeMemberExprQual() and
result = this.getQualifier()
or
i = InvokeMemberExprCallee() and
result = this.getCallee()
or
exists(int index |
i = InvokeMemberExprArg(index) and
result = this.getArgument(index)
)
}
override predicate isStatic() { this.getQualifier() instanceof TypeNameExpr }
}

View File

@@ -0,0 +1,5 @@
private import Raw
class LabeledStmt extends @labeled_statement, Stmt {
string getLabel() { label(this, result) }
}

View File

@@ -0,0 +1,60 @@
/**
* Provides the `Location` class to give a location for each
* program element.
*
* A `SourceLocation` provides a section of text in a source file
* containing the program element.
*
* Based on csharp/ql/lib/semmle/code/csharp/Location.qll
*/
import File
/**
* A location of a program element.
*/
class Location extends @location {
/** Gets the file of the location. */
File getFile() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets a textual representation of this location. */
string toString() { none() }
/** Gets the 1-based line number (inclusive) where this location starts. */
int getStartLine() { this.hasLocationInfo(_, result, _, _, _) }
/** Gets the 1-based line number (inclusive) where this location ends. */
int getEndLine() { this.hasLocationInfo(_, _, _, result, _) }
/** Gets the 1-based column number (inclusive) where this location starts. */
int getStartColumn() { this.hasLocationInfo(_, _, result, _, _) }
/** Gets the 1-based column number (inclusive) where this location ends. */
int getEndColumn() { this.hasLocationInfo(_, _, _, _, result) }
/** Holds if this location starts strictly before the specified location. */
pragma[inline]
predicate strictlyBefore(Location other) {
this.getStartLine() < other.getStartLine()
or
this.getStartLine() = other.getStartLine() and this.getStartColumn() < other.getStartColumn()
}
}
/** An empty location. */
class EmptyLocation extends Location {
EmptyLocation() { this.hasLocationInfo("", 0, 0, 0, 0) }
}

View File

@@ -0,0 +1,5 @@
private import Raw
class LoopStmt extends @loop_statement, LabeledStmt {
StmtBlock getBody() { none() }
}

View File

@@ -0,0 +1,62 @@
private import Raw
class Member extends @member, Ast {
TypeStmt getDeclaringType() { result.getAMember() = this }
string getName() { none() }
predicate isHidden() { none() }
predicate isPrivate() { none() }
predicate isPublic() { none() }
predicate isStatic() { none() }
Attribute getAttribute(int i) { none() }
final Attribute getAnAttribute() { result = this.getAttribute(_) }
TypeConstraint getTypeConstraint() { none() }
override Ast getChild(ChildIndex i) {
exists(int index |
i = MemberAttr(index) and
result = this.getAttribute(index)
)
or
i = MemberTypeConstraint() and
result = this.getTypeConstraint()
}
}
/**
* A method definition. That is, a function defined inside a class definition.
*/
class Method extends Member {
Method() { function_member(this, _, _, _, _, _, _, _, _) }
ScriptBlock getBody() { function_member(this, result, _, _, _, _, _, _, _) }
final override predicate isStatic() { function_member(this, _, _, _, _, _, true, _, _) }
final override string getName() { function_member(this, _, _, _, _, _, _, result, _) }
predicate isConstructor() { function_member(this, _, true, _, _, _, _, _, _) }
override Location getLocation() { function_member_location(this, result) }
override Attribute getAttribute(int i) { function_member_attribute(this, i, result) }
override TypeConstraint getTypeConstraint() { function_member_return_type(this, result) }
FunctionDefinitionStmt getFunctionDefinitionStmt() { result.getBody() = this.getBody() }
}
class MethodScriptBlock extends ScriptBlock {
Method m;
MethodScriptBlock() { m.getBody() = this }
Method getMethod() { result = m }
}

View File

@@ -0,0 +1,33 @@
private import Raw
class MemberExpr extends @member_expression, MemberExprBase {
final override Location getLocation() { member_expression_location(this, result) }
Expr getQualifier() { member_expression(this, result, _, _, _) }
CmdElement getMember() { member_expression(this, _, result, _, _) }
/** Gets the name of the member being looked up, if any. */
string getMemberName() { result = this.getMember().(StringConstExpr).getValue().getValue() }
predicate isNullConditional() { member_expression(this, _, _, true, _) }
override predicate isStatic() { member_expression(this, _, _, _, true) }
final override Ast getChild(ChildIndex i) {
i = MemberExprQual() and result = this.getQualifier()
or
i = MemberExprMember() and
result = this.getMember()
}
}
/** A `MemberExpr` that is being written to. */
class MemberExprWriteAccess extends MemberExpr {
MemberExprWriteAccess() { this = any(AssignStmt assign).getLeftHandSide() }
}
/** A `MemberExpr` that is being read from. */
class MemberExprReadAccess extends MemberExpr {
MemberExprReadAccess() { not this instanceof MemberExprWriteAccess }
}

View File

@@ -0,0 +1,5 @@
private import Raw
class MemberExprBase extends @member_expression_base, Expr {
predicate isStatic() { none() }
}

View File

@@ -0,0 +1,5 @@
private import Raw
class MergingRedirection extends @merging_redirection, Redirection {
override Location getLocation() { merging_redirection_location(this, result) }
}

View File

@@ -0,0 +1,17 @@
private import Raw
class ModuleSpecification extends @module_specification {
string toString() { result = this.getName() }
string getName() { module_specification(this, result, _, _, _, _) }
string getGuid() { module_specification(this, _, result, _, _, _) }
string getMaxVersion() { module_specification(this, _, _, result, _, _) }
string getRequiredVersion() { module_specification(this, _, _, _, result, _) }
string getVersion() { module_specification(this, _, _, _, _, result) }
Location getLocation() { result instanceof EmptyLocation }
}

View File

@@ -0,0 +1,23 @@
private import Raw
class NamedAttributeArgument extends @named_attribute_argument, Ast {
final override SourceLocation getLocation() { named_attribute_argument_location(this, result) }
string getName() { named_attribute_argument(this, result, _) }
predicate hasName(string s) { this.getName() = s }
Expr getValue() { named_attribute_argument(this, _, result) }
final override Ast getChild(ChildIndex i) {
i = NamedAttributeArgVal() and result = this.getValue()
}
}
class ValueFromPipelineAttribute extends NamedAttributeArgument {
ValueFromPipelineAttribute() { this.getName() = "ValueFromPipeline" }
}
class ValueFromPipelineByPropertyName extends NamedAttributeArgument {
ValueFromPipelineByPropertyName() { this.getName() = "ValueFromPipelineByPropertyName" }
}

View File

@@ -0,0 +1,36 @@
private import Raw
class NamedBlock extends @named_block, Ast {
override SourceLocation getLocation() { named_block_location(this, result) }
int getNumStatements() { named_block(this, result, _) }
int getNumTraps() { named_block(this, _, result) }
Stmt getStmt(int i) { named_block_statement(this, i, result) }
Stmt getAStmt() { result = this.getStmt(_) }
TrapStmt getTrap(int i) { named_block_trap(this, i, result) }
TrapStmt getATrap() { result = this.getTrap(_) }
final override Ast getChild(ChildIndex i) {
exists(int index |
i = NamedBlockStmt(index) and
result = this.getStmt(index)
or
i = NamedBlockTrap(index) and
result = this.getTrap(index)
)
}
}
/** A `process` block. */
class ProcessBlock extends NamedBlock {
ScriptBlock scriptBlock;
ProcessBlock() { scriptBlock.getProcessBlock() = this }
ScriptBlock getScriptBlock() { result = scriptBlock }
}

View File

@@ -0,0 +1,36 @@
private import Raw
class ParamBlock extends @param_block, Ast {
override SourceLocation getLocation() { param_block_location(this, result) }
int getNumAttributes() { param_block(this, result, _) }
int getNumParameters() { param_block(this, _, result) }
Attribute getAttribute(int i) { param_block_attribute(this, i, result) }
Attribute getAnAttribute() { result = this.getAttribute(_) }
Parameter getParameter(int i) { param_block_parameter(this, i, result) }
Parameter getAParameter() { result = this.getParameter(_) }
PipelineParameter getPipelineParameter() { result = this.getAParameter() }
PipelineByPropertyNameParameter getAPipelineByPropertyNameParameter() {
result = this.getAParameter()
}
final override Ast getChild(ChildIndex i) {
exists(int index |
i = ParamBlockAttr(index) and
result = this.getAttribute(index)
or
i = ParamBlockParam(index) and
result = this.getParameter(index)
)
}
/** Gets the script block, if any. */
ScriptBlock getScriptBlock() { result.getParamBlock() = this }
}

View File

@@ -0,0 +1,60 @@
private import Raw
class Parameter extends @parameter, Ast {
string getName() {
exists(@variable_expression va |
parameter(this, va, _, _) and
variable_expression(va, result, _, _, _, _, _, _, _, _, _, _)
)
}
override SourceLocation getLocation() { parameter_location(this, result) }
AttributeBase getAttribute(int i) { parameter_attribute(this, i, result) }
AttributeBase getAnAttribute() { result = this.getAttribute(_) }
Expr getDefaultValue() { parameter_default_value(this, result) }
final override Ast getChild(ChildIndex i) {
exists(int index |
i = ParamAttr(index) and
result = this.getAttribute(index)
)
or
i = ParamDefaultVal() and
result = this.getDefaultValue()
}
string getStaticType() { parameter(this, _, result, _) }
}
class PipelineParameter extends Parameter {
PipelineParameter() {
exists(NamedAttributeArgument namedAttribute |
this.getAnAttribute().(Attribute).getANamedArgument() = namedAttribute and
namedAttribute.getName().toLowerCase() = "valuefrompipeline"
|
namedAttribute.getValue().(ConstExpr).getValue().getValue() = "true"
or
not exists(namedAttribute.getValue().(ConstExpr).getValue().getValue())
)
}
ScriptBlock getScriptBlock() { result.getParamBlock().getAParameter() = this }
}
class PipelineByPropertyNameParameter extends Parameter {
PipelineByPropertyNameParameter() {
exists(NamedAttributeArgument namedAttribute |
this.getAnAttribute().(Attribute).getANamedArgument() = namedAttribute and
namedAttribute.getName().toLowerCase() = "valuefrompipelinebypropertyname"
|
namedAttribute.getValue().(ConstExpr).getValue().getValue() = "true"
or
not exists(namedAttribute.getValue().(ConstExpr).getValue().getValue())
)
}
ScriptBlock getScriptBlock() { result.getParamBlock().getAParameter() = this }
}

View File

@@ -0,0 +1,9 @@
private import Raw
class ParenExpr extends @paren_expression, Expr {
PipelineBase getBase() { paren_expression(this, result) }
override SourceLocation getLocation() { paren_expression_location(this, result) }
final override Ast getChild(ChildIndex i) { i = ParenExprExpr() and result = this.getBase() }
}

View File

@@ -0,0 +1,18 @@
private import Raw
class Pipeline extends @pipeline, Chainable {
override SourceLocation getLocation() { pipeline_location(this, result) }
int getNumberOfComponents() { result = count(this.getAComponent()) }
CmdBase getComponent(int i) { pipeline_component(this, i, result) }
CmdBase getAComponent() { result = this.getComponent(_) }
final override Ast getChild(ChildIndex i) {
exists(int index |
i = PipelineComp(index) and
result = this.getComponent(index)
)
}
}

View File

@@ -0,0 +1,3 @@
private import Raw
class PipelineBase extends @pipeline_base, Stmt { }

View File

@@ -0,0 +1,17 @@
private import Raw
class PipelineChain extends @pipeline_chain, Chainable {
final override SourceLocation getLocation() { pipeline_chain_location(this, result) }
predicate isBackground() { pipeline_chain(this, true, _, _, _) }
Chainable getLeft() { pipeline_chain(this, _, _, result, _) }
Pipeline getRight() { pipeline_chain(this, _, _, _, result) }
final override Ast getChild(ChildIndex i) {
i = PipelineChainLeft() and result = this.getLeft()
or
i = PipelineChainRight() and result = this.getRight()
}
}

View File

@@ -0,0 +1,19 @@
private import Raw
class PropertyMember extends @property_member, Member {
override string getName() { property_member(this, _, _, _, _, result, _) }
override SourceLocation getLocation() { property_member_location(this, result) }
override predicate isHidden() { property_member(this, true, _, _, _, _, _) }
override predicate isPrivate() { property_member(this, _, true, _, _, _, _) }
override predicate isPublic() { property_member(this, _, _, true, _, _, _) }
override predicate isStatic() { property_member(this, _, _, _, true, _, _) }
override Attribute getAttribute(int i) { property_member_attribute(this, i, result) }
override TypeConstraint getTypeConstraint() { property_member_property_type(this, result) }
}

View File

@@ -0,0 +1,84 @@
import ChildIndex
import ArrayExpression
import ArrayLiteral
import AssignmentStatement
import Ast
import Attribute
import AttributeBase
import BaseConstantExpression
import BinaryExpression
import BreakStmt
import CatchClause
import Chainable
import Command
import CommandBase
import CommandElement
import CommandExpression
import CommandParameter
import CommentEntity
import Configuration
import ConstantExpression
import ContinueStmt
import ConvertExpr
import DataStmt
import DoUntilStmt
import DoWhileStmt
import DynamicStmt
import ErrorExpr
import ErrorStmt
import ExitStmt
import ExpandableStringExpression
import Expression
import File
import FileRedirection
import ForEachStmt
import ForStmt
import Function
import GotoStmt
import HashTable
import IfStmt
import IndexExpr
import InvokeMemberExpression
import LabeledStmt
import Location
import LoopStmt
import Member
import MemberExpr
import MemberExpressionBase
import MergingRedirection
import ModuleSpecification
import NamedAttributeArgument
import NamedBlock
import ParamBlock
import Parameter
import ParenExpression
import Pipeline
import PipelineBase
import PipelineChain
import PropertyMember
import Redirection
import ReturnStmt
import ScriptBlock
import ScriptBlockExpr
import SourceLocation
import Statement
import StatementBlock
import StringConstantExpression
import StringLiteral
import SubExpression
import SwitchStmt
import TernaryExpression
import ThrowStmt
import TrapStatement
import TryStmt
import Type
import TypeConstraint
import TypeExpression
import UnaryExpression
import UsingExpression
import UsingStmt
import VariableExpression
import WhileStmt
import AttributedExpr
import AttributedExprBase
import Scope

View File

@@ -0,0 +1,10 @@
private import Raw
class Redirection extends @redirection, Ast {
Expr getExpr() { parent(result, this) } // TODO: Is there really no other way to get this?
final override Ast getChild(ChildIndex i) {
i = RedirectionExpr() and
result = this.getExpr()
}
}

View File

@@ -0,0 +1,11 @@
private import Raw
class ReturnStmt extends @return_statement, Stmt {
override SourceLocation getLocation() { return_statement_location(this, result) }
PipelineBase getPipeline() { return_statement_pipeline(this, result) }
predicate hasPipeline() { exists(this.getPipeline()) }
final override Ast getChild(ChildIndex i) { i = ReturnStmtPipeline() and result = this.getPipeline() }
}

View File

@@ -0,0 +1,59 @@
private import Raw
/** Gets the enclosing scope of `n`. */
Scope scopeOf(Ast n) {
exists(Ast m | m = n.getParent() |
m = result
or
not m instanceof Scope and result = scopeOf(m)
)
}
module Parameter {
abstract class Scope extends Ast {
abstract string getName();
}
private class ParameterScope extends Scope instanceof Parameter {
final override string getName() { result = Parameter.super.getName() }
}
}
abstract private class ScopeImpl extends Ast {
abstract Scope getOuterScopeImpl();
abstract Ast getParameterImpl(int index);
}
class Scope instanceof ScopeImpl {
Scope getOuterScope() { result = super.getOuterScopeImpl() }
string toString() { result = super.toString() }
Parameter getParameter(int index) { result = super.getParameterImpl(index) }
Parameter getAParameter() { result = this.getParameter(_) }
Location getLocation() { result = super.getLocation() }
}
/**
* A variable scope. This is either a top-level (file), a module, a class,
* or a callable.
*/
private class ScriptBlockScope extends ScopeImpl instanceof ScriptBlock {
/** Gets the outer scope, if any. */
override Scope getOuterScopeImpl() { result = scopeOf(this) }
override Parameter getParameterImpl(int index) {
exists(ParamBlock pb |
pb.getParameter(index) = result and
pb.getScriptBlock() = this
)
or
exists(FunctionDefinitionStmt func |
func.getParameter(index) = result and
func.getBody() = this
)
}
}

View File

@@ -0,0 +1,74 @@
private import Raw
class ScriptBlock extends @script_block, Ast {
predicate isTopLevel() { not exists(this.getParent()) }
override Location getLocation() { script_block_location(this, result) }
int getNumUsings() { script_block(this, result, _, _, _, _) }
int getNumRequiredModules() { script_block(this, _, result, _, _, _) }
int getNumRequiredAssemblies() { script_block(this, _, _, result, _, _) }
int getNumRequiredPsEditions() { script_block(this, _, _, _, result, _) }
int getNumRequiredPsSnapIns() { script_block(this, _, _, _, _, result) }
Stmt getUsing(int i) { script_block_using(this, i, result) }
Stmt getAUsing() { result = this.getUsing(_) }
ParamBlock getParamBlock() { script_block_param_block(this, result) }
NamedBlock getBeginBlock() { script_block_begin_block(this, result) }
NamedBlock getCleanBlock() { script_block_clean_block(this, result) }
NamedBlock getDynamicParamBlock() { script_block_dynamic_param_block(this, result) }
NamedBlock getEndBlock() { script_block_end_block(this, result) }
NamedBlock getProcessBlock() { script_block_process_block(this, result) }
string getRequiredApplicationId() { script_block_required_application_id(this, result) }
boolean getRequiresElevation() { script_block_requires_elevation(this, result) }
string getRequiredPsVersion() { script_block_required_ps_version(this, result) }
ModuleSpecification getModuleSpecification(int i) {
script_block_required_module(this, i, result)
}
ModuleSpecification getAModuleSpecification() { result = this.getModuleSpecification(_) }
final override Ast getChild(ChildIndex i) {
exists(int index |
i = ScriptBlockUsing(index) and
result = this.getUsing(index)
)
or
i = ScriptBlockParamBlock() and
result = this.getParamBlock()
or
i = ScriptBlockBeginBlock() and
result = this.getBeginBlock()
or
i = ScriptBlockCleanBlock() and
result = this.getCleanBlock()
or
i = ScriptBlockDynParamBlock() and
result = this.getDynamicParamBlock()
or
i = ScriptBlockEndBlock() and
result = this.getEndBlock()
or
i = ScriptBlockProcessBlock() and
result = this.getProcessBlock()
}
}
class TopLevelScriptBlock extends ScriptBlock {
TopLevelScriptBlock() { this.isTopLevel() }
}

View File

@@ -0,0 +1,9 @@
private import Raw
class ScriptBlockExpr extends @script_block_expression, Expr {
override SourceLocation getLocation() { script_block_expression_location(this, result) }
ScriptBlock getBody() { script_block_expression(this, result) }
final override Ast getChild(ChildIndex i) { i = ScriptBlockExprBody() and result = this.getBody() }
}

View File

@@ -0,0 +1,25 @@
private import Raw
/**
* A location in source code, comprising of a source file and a segment of text
* within the file.
*/
class SourceLocation extends Location, @location_default {
override File getFile() { locations_default(this, result, _, _, _, _) }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
exists(File f | locations_default(this, f, startline, startcolumn, endline, endcolumn) |
filepath = f.getAbsolutePath()
)
}
override string toString() {
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
this.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
result = filepath + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
)
}
}

View File

@@ -0,0 +1,3 @@
private import Raw
class Stmt extends @statement, Ast { }

View File

@@ -0,0 +1,27 @@
private import Raw
class StmtBlock extends @statement_block, Ast {
override SourceLocation getLocation() { statement_block_location(this, result) }
int getNumberOfStmts() { statement_block(this, result, _) }
int getNumTraps() { statement_block(this, _, result) }
Stmt getStmt(int index) { statement_block_statement(this, index, result) }
Stmt getAStmt() { result = this.getStmt(_) }
TrapStmt getTrapStmt(int index) { statement_block_trap(this, index, result) }
TrapStmt getATrapStmt() { result = this.getTrapStmt(_) }
final override Ast getChild(ChildIndex i) {
exists(int index |
i = StmtBlockStmt(index) and
result = this.getStmt(index)
or
i = StmtBlockTrapStmt(index) and
result = this.getTrapStmt(index)
)
}
}

View File

@@ -0,0 +1,10 @@
private import Raw
/** A string constant. */
class StringConstExpr extends @string_constant_expression, BaseConstExpr {
override StringLiteral getValue() { string_constant_expression(this, result) }
override string getType() { result = "String" }
override SourceLocation getLocation() { string_constant_expression_location(this, result) }
}

View File

@@ -0,0 +1,16 @@
private import Raw
class StringLiteral extends @string_literal {
int getNumContinuations() { result = strictcount(int i | exists(this.getContinuation(i))) }
string getContinuation(int index) { string_literal_line(this, index, result) }
/** Get the full string literal with all its parts concatenated */
string toString() { result = this.getValue() }
string getValue() {
result = concat(int i | i = [0 .. this.getNumContinuations()] | this.getContinuation(i), "\n")
}
SourceLocation getLocation() { string_literal_location(this, result) }
}

View File

@@ -0,0 +1,12 @@
private import Raw
// TODO: Should we remove this from the dbscheme?
class ExpandableSubExpr extends @sub_expression, Expr {
final override Location getLocation() { sub_expression_location(this, result) }
StmtBlock getExpr() { sub_expression(this, result) }
final override Ast getChild(ChildIndex i) {
i = ExpandableSubExprExpr() and result = this.getExpr()
}
}

View File

@@ -0,0 +1,39 @@
private import Raw
class SwitchStmt extends LabeledStmt, @switch_statement {
final override Location getLocation() { switch_statement_location(this, result) }
PipelineBase getCondition() { switch_statement(this, result, _) }
StmtBlock getDefault() { switch_statement_default(this, result) }
StmtBlock getCase(int i, Expr e) { switch_statement_clauses(this, i, e, result) }
StmtBlock getCase(int i) { result = this.getCase(i, _) }
StmtBlock getACase() { result = this.getCase(_) }
StmtBlock getCaseForExpr(Expr e) { result = this.getCase(_, e) }
Expr getPattern(int i) { exists(this.getCase(i, result)) }
Expr getAPattern() { result = this.getPattern(_) }
int getNumberOfCases() { result = count(this.getACase()) }
final override Ast getChild(ChildIndex i) {
i = SwitchStmtCond() and
result = this.getCondition()
or
i = SwitchStmtDefault() and
result = this.getDefault()
or
exists(int index |
i = SwitchStmtCase(index) and
result = this.getCase(index)
or
i = SwitchStmtPat(index) and
result = this.getPattern(index)
)
}
}

View File

@@ -0,0 +1,33 @@
private import Raw
class ConditionalExpr extends @ternary_expression, Expr {
override SourceLocation getLocation() { ternary_expression_location(this, result) }
Expr getCondition() { ternary_expression(this, result, _, _) }
Expr getIfFalse() { ternary_expression(this, _, result, _) }
Expr getIfTrue() { ternary_expression(this, _, _, result) }
Expr getBranch(boolean value) {
value = true and
result = this.getIfTrue()
or
value = false and
result = this.getIfFalse()
}
Expr getABranch() { result = this.getBranch(_) }
final override Ast getChild(ChildIndex i) {
i = CondExprCond() and
result = this.getCondition()
or
i = CondExprTrue() and
result = this.getIfTrue()
or
i = CondExprFalse() and
result = this.getIfFalse()
}
}

View File

@@ -0,0 +1,11 @@
private import Raw
class ThrowStmt extends @throw_statement, Stmt {
override SourceLocation getLocation() { throw_statement_location(this, result) }
PipelineBase getPipeline() { throw_statement_pipeline(this, result) }
predicate hasPipeline() { exists(this.getPipeline()) }
final override Ast getChild(ChildIndex i) { i = ThrowStmtPipeline() and result = this.getPipeline() }
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
private import Raw
class TrapStmt extends @trap_statement, Stmt {
override SourceLocation getLocation() { trap_statement_location(this, result) }
StmtBlock getBody() { trap_statement(this, result) } // TODO: Fix type in dbscheme
TypeConstraint getTypeConstraint() { trap_statement_type(this, result) }
override Ast getChild(ChildIndex i) {
i = TrapStmtBody() and
result = this.getBody()
or
i = TrapStmtTypeConstraint() and
result = this.getTypeConstraint()
}
}

View File

@@ -0,0 +1,29 @@
private import Raw
class TryStmt extends @try_statement, Stmt {
override SourceLocation getLocation() { try_statement_location(this, result) }
CatchClause getCatchClause(int i) { try_statement_catch_clause(this, i, result) }
CatchClause getACatchClause() { result = this.getCatchClause(_) }
/** ..., if any. */
StmtBlock getFinally() { try_statement_finally(this, result) }
StmtBlock getBody() { try_statement(this, result) }
predicate hasFinally() { exists(this.getFinally()) }
final override Ast getChild(ChildIndex i) {
i = TryStmtBody() and
result = this.getBody()
or
exists(int index |
i = TryStmtCatchClause(index) and
result = this.getCatchClause(index)
)
or
i = TryStmtFinally() and
result = this.getFinally()
}
}

View File

@@ -0,0 +1,32 @@
private import Raw
class TypeStmt extends @type_definition, Stmt {
override SourceLocation getLocation() { type_definition_location(this, result) }
string getName() { type_definition(this, result, _, _, _, _) }
Member getMember(int i) { type_definition_members(this, i, result) }
Member getAMember() { result = this.getMember(_) }
Method getMethod(string name) {
result = this.getAMember() and
result.getName() = name
}
TypeConstraint getBaseType(int i) { type_definition_base_type(this, i, result) }
TypeConstraint getABaseType() { result = this.getBaseType(_) }
TypeStmt getASubtype() { result.getABaseType().getName() = this.getName() }
final override Ast getChild(ChildIndex i) {
exists(int index |
i = TypeStmtMember(index) and
result = this.getMember(index)
or
i = TypeStmtBaseType(index) and
result = this.getBaseType(index)
)
}
}

View File

@@ -0,0 +1,11 @@
private import Raw
class TypeConstraint extends @type_constraint, AttributeBase {
override SourceLocation getLocation() { type_constraint_location(this, result) }
/** Gets the assembly name. */
string getName() { type_constraint(this, result, _) }
/** Gets the full name of this type constraint including namespaces. */
string getFullName() { type_constraint(this, _, result) }
}

View File

@@ -0,0 +1,10 @@
private import Raw
class TypeNameExpr extends @type_expression, Expr {
string getName() { type_expression(this, result, _) }
override SourceLocation getLocation() { type_expression_location(this, result) }
/** Gets the type referred to by this `TypeNameExpr`. */
TypeStmt getType() { result.getName() = this.getName() }
}

View File

@@ -0,0 +1,11 @@
private import Raw
class UnaryExpr extends @unary_expression, Expr {
override SourceLocation getLocation() { unary_expression_location(this, result) }
int getKind() { unary_expression(this, _, result, _) }
Expr getOperand() { unary_expression(this, result, _, _) }
final override Ast getChild(ChildIndex i) { i = UnaryExprOp() and result = this.getOperand() }
}

View File

@@ -0,0 +1,12 @@
private import Raw
class UsingExpr extends @using_expression, Expr {
override SourceLocation getLocation() { using_expression_location(this, result) }
Expr getExpr() { using_expression(this, result) }
override Ast getChild(ChildIndex i) {
i = UsingExprExpr() and
result = this.getExpr()
}
}

View File

@@ -0,0 +1,19 @@
private import Raw
class UsingStmt extends @using_statement, Stmt {
override SourceLocation getLocation() { using_statement_location(this, result) }
string getName() {
exists(StringConstExpr const |
using_statement_name(this, const) and // TODO: Change dbscheme
result = const.getValue().getValue()
)
}
string getAlias() {
exists(StringConstExpr const |
using_statement_alias(this, const) and // TODO: Change dbscheme
result = const.getValue().getValue()
)
}
}

View File

@@ -0,0 +1,48 @@
private import Raw
class VarAccess extends @variable_expression, Expr {
override SourceLocation getLocation() { variable_expression_location(this, result) }
string getUserPath() { variable_expression(this, result, _, _, _, _, _, _, _, _, _, _) }
string getDriveName() { variable_expression(this, _, result, _, _, _, _, _, _, _, _, _) }
boolean isConstant() { variable_expression(this, _, _, result, _, _, _, _, _, _, _, _) }
boolean isGlobal() { variable_expression(this, _, _, _, result, _, _, _, _, _, _, _) }
boolean isLocal() { variable_expression(this, _, _, _, _, result, _, _, _, _, _, _) }
boolean isPrivate() { variable_expression(this, _, _, _, _, _, result, _, _, _, _, _) }
boolean isScript() { variable_expression(this, _, _, _, _, _, _, result, _, _, _, _) }
boolean isUnqualified() { variable_expression(this, _, _, _, _, _, _, _, result, _, _, _) }
boolean isUnscoped() { variable_expression(this, _, _, _, _, _, _, _, _, result, _, _) }
boolean isVariable() { variable_expression(this, _, _, _, _, _, _, _, _, _, result, _) }
boolean isDriveQualified() { variable_expression(this, _, _, _, _, _, _, _, _, _, _, result) }
}
class ThisAccess extends VarAccess {
ThisAccess() { this.getUserPath() = "this" }
}
predicate isEnvVariableAccess(VarAccess va, string env) {
va.getUserPath().toLowerCase() = "env:" + env
}
predicate isAutomaticVariableAccess(VarAccess va, string var) {
va.getUserPath().toLowerCase() =
[
"args", "consolefilename", "enabledexperimentalfeatures", "error", "event", "eventargs",
"eventsubscriber", "executioncontext", "home", "host", "input", "iscoreclr", "islinux",
"ismacos", "iswindows", "lastexitcode", "myinvocation", "nestedpromptlevel", "pid", "profile",
"psboundparameters", "pscmdlet", "pscommandpath", "psculture", "psdebugcontext", "psedition",
"pshome", "psitem", "psscriptroot", "pssenderinfo", "psuiculture", "psversiontable", "pwd",
"sender", "shellid", "stacktrace"
] and
var = va.getUserPath().toLowerCase()
}

View File

@@ -0,0 +1,15 @@
private import Raw
class WhileStmt extends @while_statement, LoopStmt {
override SourceLocation getLocation() { while_statement_location(this, result) }
PipelineBase getCondition() { while_statement_condition(this, result) }
final override StmtBlock getBody() { while_statement(this, result) }
final override Ast getChild(ChildIndex i) {
i = WhileStmtCond() and result = this.getCondition()
or
i = WhileStmtBody() and result = this.getBody()
}
}