mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
JS: Remove synthetic locations
This commit is contained in:
@@ -31,7 +31,7 @@ class AstNode extends @ast_node, NodeInStmtContainer {
|
||||
|
||||
/** Gets the first token belonging to this element. */
|
||||
Token getFirstToken() {
|
||||
exists(DbLocation l1, DbLocation l2, string filepath, int startline, int startcolumn |
|
||||
exists(Location l1, Location l2, string filepath, int startline, int startcolumn |
|
||||
l1 = this.getLocation() and
|
||||
l2 = result.getLocation() and
|
||||
l1.hasLocationInfo(filepath, startline, startcolumn, _, _) and
|
||||
@@ -41,7 +41,7 @@ class AstNode extends @ast_node, NodeInStmtContainer {
|
||||
|
||||
/** Gets the last token belonging to this element. */
|
||||
Token getLastToken() {
|
||||
exists(DbLocation l1, DbLocation l2, string filepath, int endline, int endcolumn |
|
||||
exists(Location l1, Location l2, string filepath, int endline, int endcolumn |
|
||||
l1 = this.getLocation() and
|
||||
l2 = result.getLocation() and
|
||||
l1.hasLocationInfo(filepath, _, _, endline, endcolumn) and
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import javascript
|
||||
private import NodeModuleResolutionImpl
|
||||
private import codeql.util.FileSystem
|
||||
private import internal.Locations
|
||||
|
||||
private module FsInput implements InputSig {
|
||||
abstract class ContainerBase extends @container {
|
||||
@@ -99,7 +98,7 @@ class File extends Container, Impl::File {
|
||||
*
|
||||
* Note that files have special locations starting and ending at line zero, column zero.
|
||||
*/
|
||||
DbLocation getLocation() { result = getLocatableLocation(this) }
|
||||
Location getLocation() { hasLocation(this, result) }
|
||||
|
||||
/** Gets the number of lines in this file. */
|
||||
int getNumberOfLines() { result = sum(int loc | numlines(this, loc, _, _) | loc) }
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*/
|
||||
|
||||
import javascript
|
||||
private import semmle.javascript.internal.Locations
|
||||
|
||||
/**
|
||||
* A JSON-encoded value, which may be a primitive value, an array or an object.
|
||||
@@ -33,7 +32,7 @@ class JsonValue extends @json_value, Locatable {
|
||||
override string toString() { json(this, _, _, _, result) }
|
||||
|
||||
/** Gets the JSON file containing this value. */
|
||||
File getJsonFile() { result = getLocatableLocation(this).getFile() }
|
||||
File getJsonFile() { exists(Location loc | json_locations(this, loc) and result = loc.getFile()) }
|
||||
|
||||
/** If this is an object, gets the value of property `name`. */
|
||||
JsonValue getPropValue(string name) { json_properties(this, name, result) }
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/** Provides classes for working with locations and program elements that have locations. */
|
||||
|
||||
import javascript
|
||||
private import internal.Locations
|
||||
|
||||
/**
|
||||
* A location as given by a file, a start line, a start column,
|
||||
@@ -11,31 +10,31 @@ private import internal.Locations
|
||||
*
|
||||
* For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
class DbLocation extends TDbLocation {
|
||||
final class Location extends @location_default {
|
||||
/** Gets the file for this location. */
|
||||
File getFile() { dbLocationInfo(this, result, _, _, _, _) }
|
||||
File getFile() { locations_default(this, result, _, _, _, _) }
|
||||
|
||||
/** Gets the 1-based line number (inclusive) where this location starts. */
|
||||
int getStartLine() { dbLocationInfo(this, _, result, _, _, _) }
|
||||
int getStartLine() { locations_default(this, _, result, _, _, _) }
|
||||
|
||||
/** Gets the 1-based column number (inclusive) where this location starts. */
|
||||
int getStartColumn() { dbLocationInfo(this, _, _, result, _, _) }
|
||||
int getStartColumn() { locations_default(this, _, _, result, _, _) }
|
||||
|
||||
/** Gets the 1-based line number (inclusive) where this location ends. */
|
||||
int getEndLine() { dbLocationInfo(this, _, _, _, result, _) }
|
||||
int getEndLine() { locations_default(this, _, _, _, result, _) }
|
||||
|
||||
/** Gets the 1-based column number (inclusive) where this location ends. */
|
||||
int getEndColumn() { dbLocationInfo(this, _, _, _, _, result) }
|
||||
int getEndColumn() { locations_default(this, _, _, _, _, result) }
|
||||
|
||||
/** Gets the number of lines covered by this location. */
|
||||
int getNumLines() { result = this.getEndLine() - this.getStartLine() + 1 }
|
||||
|
||||
/** Holds if this location starts before location `that`. */
|
||||
pragma[inline]
|
||||
predicate startsBefore(DbLocation that) {
|
||||
exists(File f, int sl1, int sc1, int sl2, int sc2 |
|
||||
dbLocationInfo(this, f, sl1, sc1, _, _) and
|
||||
dbLocationInfo(that, f, sl2, sc2, _, _)
|
||||
predicate startsBefore(Location that) {
|
||||
exists(string f, int sl1, int sc1, int sl2, int sc2 |
|
||||
this.hasLocationInfo(f, sl1, sc1, _, _) and
|
||||
that.hasLocationInfo(f, sl2, sc2, _, _)
|
||||
|
|
||||
sl1 < sl2
|
||||
or
|
||||
@@ -45,10 +44,10 @@ class DbLocation extends TDbLocation {
|
||||
|
||||
/** Holds if this location ends after location `that`. */
|
||||
pragma[inline]
|
||||
predicate endsAfter(DbLocation that) {
|
||||
exists(File f, int el1, int ec1, int el2, int ec2 |
|
||||
dbLocationInfo(this, f, _, _, el1, ec1) and
|
||||
dbLocationInfo(that, f, _, _, el2, ec2)
|
||||
predicate endsAfter(Location that) {
|
||||
exists(string f, int el1, int ec1, int el2, int ec2 |
|
||||
this.hasLocationInfo(f, _, _, el1, ec1) and
|
||||
that.hasLocationInfo(f, _, _, el2, ec2)
|
||||
|
|
||||
el1 > el2
|
||||
or
|
||||
@@ -60,10 +59,10 @@ class DbLocation extends TDbLocation {
|
||||
* Holds if this location contains location `that`, meaning that it starts
|
||||
* before and ends after it.
|
||||
*/
|
||||
predicate contains(DbLocation that) { this.startsBefore(that) and this.endsAfter(that) }
|
||||
predicate contains(Location that) { this.startsBefore(that) and this.endsAfter(that) }
|
||||
|
||||
/** Holds if this location is empty. */
|
||||
predicate isEmpty() { exists(int l, int c | dbLocationInfo(this, _, l, c, l, c - 1)) }
|
||||
predicate isEmpty() { exists(int l, int c | this.hasLocationInfo(_, l, c, l, c - 1)) }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = this.getFile().getBaseName() + ":" + this.getStartLine().toString() }
|
||||
@@ -79,13 +78,19 @@ class DbLocation extends TDbLocation {
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
exists(File f |
|
||||
dbLocationInfo(this, f, startline, startcolumn, endline, endcolumn) and
|
||||
locations_default(this, f, startline, startcolumn, endline, endcolumn) and
|
||||
filepath = f.getAbsolutePath()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
final class Location = LocationImpl;
|
||||
cached
|
||||
private Location getLocatableLocation(@locatable l) {
|
||||
hasLocation(l, result) or
|
||||
xmllocations(l, result) or
|
||||
json_locations(l, result) or
|
||||
yaml_locations(l, result)
|
||||
}
|
||||
|
||||
/** A program element with a location. */
|
||||
class Locatable extends @locatable {
|
||||
@@ -93,7 +98,7 @@ class Locatable extends @locatable {
|
||||
File getFile() { result = this.getLocation().getFile() }
|
||||
|
||||
/** Gets this element's location. */
|
||||
final DbLocation getLocation() { result = getLocatableLocation(this) }
|
||||
final Location getLocation() { result = getLocatableLocation(this) }
|
||||
|
||||
/**
|
||||
* Gets the line on which this element starts.
|
||||
|
||||
@@ -26,7 +26,7 @@ class FirstLineOf extends Locatable {
|
||||
then endcolumn = xc
|
||||
else
|
||||
endcolumn =
|
||||
max(int c | any(DbLocation l).hasLocationInfo(filepath, startline, _, startline, c))
|
||||
max(int c | any(Location l).hasLocationInfo(filepath, startline, _, startline, c))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -412,17 +412,22 @@ class SsaVariable extends TSsaDefinition {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = this.getDefinition().prettyPrintRef() }
|
||||
|
||||
/** Gets the location of this SSA variable. */
|
||||
Location getLocation() { result = this.getDefinition().getLocation() }
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use `getLocation().hasLocationInfo()` instead.
|
||||
*
|
||||
* 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(
|
||||
deprecated predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.getDefinition().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,23 +483,22 @@ class SsaDefinition extends TSsaDefinition {
|
||||
string toString() { result = this.prettyPrintDef() }
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use `getLocation().hasLocationInfo()` instead.
|
||||
*
|
||||
* 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/).
|
||||
*/
|
||||
abstract predicate hasLocationInfo(
|
||||
deprecated predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
);
|
||||
) {
|
||||
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
|
||||
/** Gets the location of this element. */
|
||||
final Location getLocation() {
|
||||
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
|
||||
this.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
|
||||
result.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
)
|
||||
}
|
||||
Location getLocation() { result = this.getBasicBlock().getLocation() }
|
||||
|
||||
/** Gets the function or toplevel to which this definition belongs. */
|
||||
StmtContainer getContainer() { result = this.getBasicBlock().getContainer() }
|
||||
@@ -522,20 +526,13 @@ class SsaExplicitDefinition extends SsaDefinition, TExplicitDef {
|
||||
override VarDef getAContributingVarDef() { result = this.getDef() }
|
||||
|
||||
override string prettyPrintRef() {
|
||||
exists(int l, int c | this.hasLocationInfo(_, l, c, _, _) | result = "def@" + l + ":" + c)
|
||||
exists(int l, int c | this.getLocation().hasLocationInfo(_, l, c, _, _) |
|
||||
result = "def@" + l + ":" + c
|
||||
)
|
||||
}
|
||||
|
||||
override string prettyPrintDef() { result = this.getDef().toString() }
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
exists(Location loc |
|
||||
pragma[only_bind_into](loc) = pragma[only_bind_into](this.getDef()).getLocation() and
|
||||
loc.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data flow node representing the incoming value assigned at this definition,
|
||||
* if any.
|
||||
@@ -557,21 +554,10 @@ abstract class SsaImplicitDefinition extends SsaDefinition {
|
||||
abstract string getKind();
|
||||
|
||||
override string prettyPrintRef() {
|
||||
exists(int l, int c | this.hasLocationInfo(_, l, c, _, _) |
|
||||
exists(int l, int c | this.getLocation().hasLocationInfo(_, l, c, _, _) |
|
||||
result = this.getKind() + "@" + l + ":" + c
|
||||
)
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
endline = startline and
|
||||
endcolumn = startcolumn and
|
||||
exists(Location loc |
|
||||
pragma[only_bind_into](loc) = pragma[only_bind_into](this.getBasicBlock()).getLocation() and
|
||||
loc.hasLocationInfo(filepath, startline, startcolumn, _, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -617,16 +603,6 @@ class SsaVariableCapture extends SsaImplicitDefinition, TCapture {
|
||||
override string getKind() { result = "capture" }
|
||||
|
||||
override string prettyPrintDef() { result = "capture variable " + this.getSourceVariable() }
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
exists(ReachableBasicBlock bb, int i | this.definesAt(bb, i, _) |
|
||||
bb.getNode(i)
|
||||
.getLocation()
|
||||
.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -747,13 +723,7 @@ class SsaRefinementNode extends SsaPseudoDefinition, TRefinement {
|
||||
this.getSourceVariable() + " = refine[" + this.getGuard() + "](" + this.ppInputs() + ")"
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.getGuard()
|
||||
.getLocation()
|
||||
.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
override Location getLocation() { result = this.getGuard().getLocation() }
|
||||
}
|
||||
|
||||
module Ssa {
|
||||
|
||||
@@ -353,9 +353,9 @@ class LocalVariable extends Variable {
|
||||
* If the variable has one or more declarations, the location of the first declaration is used.
|
||||
* If the variable has no declaration, the entry point of its declaring container is used.
|
||||
*/
|
||||
DbLocation getLocation() {
|
||||
Location getLocation() {
|
||||
result =
|
||||
min(DbLocation loc |
|
||||
min(Location loc |
|
||||
loc = this.getADeclaration().getLocation()
|
||||
|
|
||||
loc order by loc.getStartLine(), loc.getStartColumn()
|
||||
|
||||
@@ -3,13 +3,12 @@
|
||||
*/
|
||||
|
||||
import semmle.files.FileSystem
|
||||
private import semmle.javascript.internal.Locations
|
||||
private import codeql.xml.Xml
|
||||
|
||||
private module Input implements InputSig<File, DbLocation> {
|
||||
private module Input implements InputSig<File, Location> {
|
||||
class XmlLocatableBase = @xmllocatable or @xmlnamespaceable;
|
||||
|
||||
predicate xmllocations_(XmlLocatableBase e, DbLocation loc) { loc = getLocatableLocation(e) }
|
||||
predicate xmllocations_(XmlLocatableBase e, Location loc) { xmllocations(e, loc) }
|
||||
|
||||
class XmlParentBase = @xmlparent;
|
||||
|
||||
@@ -67,4 +66,4 @@ private module Input implements InputSig<File, DbLocation> {
|
||||
}
|
||||
}
|
||||
|
||||
import Make<File, DbLocation, Input>
|
||||
import Make<File, Location, Input>
|
||||
|
||||
@@ -9,8 +9,6 @@ import javascript
|
||||
private import codeql.yaml.Yaml as LibYaml
|
||||
|
||||
private module YamlSig implements LibYaml::InputSig {
|
||||
class Location = DbLocation;
|
||||
|
||||
class LocatableBase extends @yaml_locatable, Locatable { }
|
||||
|
||||
import javascript
|
||||
|
||||
@@ -4,7 +4,7 @@ private import semmle.javascript.dataflow.internal.VariableOrThis
|
||||
private import codeql.dataflow.VariableCapture
|
||||
private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon
|
||||
|
||||
module VariableCaptureConfig implements InputSig<js::DbLocation> {
|
||||
module VariableCaptureConfig implements InputSig<js::Location> {
|
||||
private js::Function getLambdaFromVariable(js::LocalVariable variable) {
|
||||
result.getVariable() = variable
|
||||
or
|
||||
@@ -168,7 +168,7 @@ module VariableCaptureConfig implements InputSig<js::DbLocation> {
|
||||
|
||||
string toString() { none() } // Overridden in subclass
|
||||
|
||||
js::DbLocation getLocation() { none() } // Overridden in subclass
|
||||
js::Location getLocation() { none() } // Overridden in subclass
|
||||
|
||||
predicate hasCfgNode(BasicBlock bb, int i) { none() } // Overridden in subclass
|
||||
|
||||
@@ -186,7 +186,7 @@ module VariableCaptureConfig implements InputSig<js::DbLocation> {
|
||||
override string toString() { result = pattern.toString() }
|
||||
|
||||
/** Gets the location of this write. */
|
||||
override js::DbLocation getLocation() { result = pattern.getLocation() }
|
||||
override js::Location getLocation() { result = pattern.getLocation() }
|
||||
|
||||
override js::DataFlow::Node getSource() {
|
||||
// Note: there is not always an expression corresponding to the RHS of the assignment.
|
||||
@@ -222,7 +222,7 @@ module VariableCaptureConfig implements InputSig<js::DbLocation> {
|
||||
|
||||
override string toString() { result = "[implicit init] " + variable }
|
||||
|
||||
override js::DbLocation getLocation() { result = variable.getLocation() }
|
||||
override js::Location getLocation() { result = variable.getLocation() }
|
||||
|
||||
override CapturedVariable getVariable() { result = variable }
|
||||
|
||||
@@ -242,7 +242,7 @@ module VariableCaptureConfig implements InputSig<js::DbLocation> {
|
||||
predicate entryBlock(BasicBlock bb) { bb instanceof js::EntryBasicBlock }
|
||||
}
|
||||
|
||||
module VariableCaptureOutput = Flow<js::DbLocation, VariableCaptureConfig>;
|
||||
module VariableCaptureOutput = Flow<js::Location, VariableCaptureConfig>;
|
||||
|
||||
js::DataFlow::Node getNodeFromClosureNode(VariableCaptureOutput::ClosureNode node) {
|
||||
result = TValueNode(node.(VariableCaptureOutput::ExprNode).getExpr())
|
||||
|
||||
@@ -25,7 +25,7 @@ class LocalVariableOrThis extends TLocalVariableOrThis {
|
||||
}
|
||||
|
||||
/** Gets the location of a declaration of this variable, or the declaring container if this is `this`. */
|
||||
DbLocation getLocation() {
|
||||
Location getLocation() {
|
||||
result = this.asLocalVariable().getLocation()
|
||||
or
|
||||
result = this.asThisContainer().getLocation()
|
||||
@@ -95,7 +95,7 @@ abstract class ThisUse instanceof ControlFlowNode {
|
||||
string toString() { result = super.toString() }
|
||||
|
||||
/** Gets the location of this use of `this`. */
|
||||
DbLocation getLocation() { result = super.getLocation() }
|
||||
Location getLocation() { result = super.getLocation() }
|
||||
}
|
||||
|
||||
private predicate implicitThisUse(ControlFlowNode node, StmtContainer thisBinder) {
|
||||
|
||||
@@ -9,7 +9,7 @@ private import codeql.ssa.Ssa
|
||||
private import semmle.javascript.internal.BasicBlockInternal as BasicBlockInternal
|
||||
private import semmle.javascript.dataflow.internal.VariableOrThis
|
||||
|
||||
module SsaConfig implements InputSig<js::DbLocation> {
|
||||
module SsaConfig implements InputSig<js::Location> {
|
||||
class ControlFlowNode = js::ControlFlowNode;
|
||||
|
||||
class BasicBlock = js::BasicBlock;
|
||||
@@ -47,7 +47,7 @@ module SsaConfig implements InputSig<js::DbLocation> {
|
||||
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
|
||||
}
|
||||
|
||||
import Make<js::DbLocation, SsaConfig>
|
||||
import Make<js::Location, SsaConfig>
|
||||
|
||||
module SsaDataflowInput implements DataFlowIntegrationInputSig {
|
||||
private import codeql.util.Boolean
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
/** Provides classes for working with locations and program elements that have locations. */
|
||||
|
||||
import javascript
|
||||
|
||||
// Should _not_ be cached, as that would require the data flow stage to be evaluated
|
||||
// in order to evaluate the AST stage. Ideally, we would cache each injector separately,
|
||||
// but that's not possible. Instead, we cache all predicates that need the injectors
|
||||
// to be tuple numbered.
|
||||
newtype TLocation =
|
||||
TDbLocation(@location loc) or
|
||||
TSynthLocation(string filepath, int startline, int startcolumn, int endline, int endcolumn) {
|
||||
any(SsaDefinition def).hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
|
||||
// avoid overlap with existing DB locations
|
||||
not exists(File f |
|
||||
locations_default(_, f, startline, startcolumn, endline, endcolumn) and
|
||||
f.getAbsolutePath() = filepath
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A location as given by a file, a start line, a start column,
|
||||
* an end line, and an end column.
|
||||
*
|
||||
* For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
abstract class LocationImpl extends TLocation {
|
||||
/** Gets the file for this location. */
|
||||
abstract File getFile();
|
||||
|
||||
/** Gets the 1-based line number (inclusive) where this location starts. */
|
||||
abstract int getStartLine();
|
||||
|
||||
/** Gets the 1-based column number (inclusive) where this location starts. */
|
||||
abstract int getStartColumn();
|
||||
|
||||
/** Gets the 1-based line number (inclusive) where this location ends. */
|
||||
abstract int getEndLine();
|
||||
|
||||
/** Gets the 1-based column number (inclusive) where this location ends. */
|
||||
abstract int getEndColumn();
|
||||
|
||||
/** Gets the number of lines covered by this location. */
|
||||
int getNumLines() { result = this.getEndLine() - this.getStartLine() + 1 }
|
||||
|
||||
/** Holds if this location starts before location `that`. */
|
||||
pragma[inline]
|
||||
predicate startsBefore(Location that) {
|
||||
exists(string f, int sl1, int sc1, int sl2, int sc2 |
|
||||
this.hasLocationInfo(f, sl1, sc1, _, _) and
|
||||
that.hasLocationInfo(f, sl2, sc2, _, _)
|
||||
|
|
||||
sl1 < sl2
|
||||
or
|
||||
sl1 = sl2 and sc1 < sc2
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if this location ends after location `that`. */
|
||||
pragma[inline]
|
||||
predicate endsAfter(Location that) {
|
||||
exists(string f, int el1, int ec1, int el2, int ec2 |
|
||||
this.hasLocationInfo(f, _, _, el1, ec1) and
|
||||
that.hasLocationInfo(f, _, _, el2, ec2)
|
||||
|
|
||||
el1 > el2
|
||||
or
|
||||
el1 = el2 and ec1 > ec2
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this location contains location `that`, meaning that it starts
|
||||
* before and ends after it.
|
||||
*/
|
||||
predicate contains(Location that) { this.startsBefore(that) and this.endsAfter(that) }
|
||||
|
||||
/** Holds if this location is empty. */
|
||||
predicate isEmpty() { exists(int l, int c | this.hasLocationInfo(_, l, c, l, c - 1)) }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = this.getFile().getBaseName() + ":" + this.getStartLine().toString() }
|
||||
|
||||
/**
|
||||
* 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/).
|
||||
*/
|
||||
abstract predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
);
|
||||
}
|
||||
|
||||
class DbLocationImpl extends LocationImpl instanceof DbLocation {
|
||||
override File getFile() { result = DbLocation.super.getFile() }
|
||||
|
||||
override int getStartLine() { result = DbLocation.super.getStartLine() }
|
||||
|
||||
override int getStartColumn() { result = DbLocation.super.getStartColumn() }
|
||||
|
||||
override int getEndLine() { result = DbLocation.super.getEndLine() }
|
||||
|
||||
override int getEndColumn() { result = DbLocation.super.getEndColumn() }
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
DbLocation.super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
}
|
||||
|
||||
class SynthLocationImpl extends LocationImpl, TSynthLocation {
|
||||
override File getFile() { synthLocationInfo(this, result.getAbsolutePath(), _, _, _, _) }
|
||||
|
||||
override int getStartLine() { synthLocationInfo(this, _, result, _, _, _) }
|
||||
|
||||
override int getStartColumn() { synthLocationInfo(this, _, _, result, _, _) }
|
||||
|
||||
override int getEndLine() { synthLocationInfo(this, _, _, _, result, _) }
|
||||
|
||||
override int getEndColumn() { synthLocationInfo(this, _, _, _, _, result) }
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
synthLocationInfo(this, filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
}
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
cached
|
||||
DbLocation getLocatableLocation(@locatable l) {
|
||||
exists(@location loc |
|
||||
hasLocation(l, loc) or
|
||||
xmllocations(l, loc) or
|
||||
json_locations(l, loc) or
|
||||
yaml_locations(l, loc)
|
||||
|
|
||||
result = TDbLocation(loc)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate dbLocationInfo(
|
||||
DbLocation l, File f, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
exists(@location loc |
|
||||
l = TDbLocation(loc) and
|
||||
locations_default(loc, f, startline, startcolumn, endline, endcolumn)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import Cached
|
||||
|
||||
cached
|
||||
private module CachedInDataFlowStage {
|
||||
private import semmle.javascript.internal.CachedStages
|
||||
|
||||
cached
|
||||
predicate synthLocationInfo(
|
||||
SynthLocationImpl l, string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
Stages::DataFlowStage::ref() and
|
||||
l = TSynthLocation(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
}
|
||||
|
||||
private import CachedInDataFlowStage
|
||||
Reference in New Issue
Block a user