1- import { LocationStyle } from ' ./bqrs-schema' ;
1+ import { LocationStyle } from " ./bqrs-schema" ;
22
33// See https://help.semmle.com/QL/learn-ql/ql/locations.html for how these are used.
44export interface FivePartLocation {
@@ -31,54 +31,69 @@ export type LocationValue = RawLocationValue | WholeFileLocation;
3131/** A location that may be resolved to a source code element. */
3232export type ResolvableLocationValue = FivePartLocation | WholeFileLocation ;
3333
34-
3534/**
3635 * The CodeQL filesystem libraries use this pattern in `getURL()` predicates
3736 * to describe the location of an entire filesystem resource.
3837 * Such locations appear as `StringLocation`s instead of `FivePartLocation`s.
39- *
38+ *
4039 * Folder resources also get similar URLs, but with the `folder` scheme.
4140 * They are deliberately ignored here, since there is no suitable location to show the user.
4241 */
43- const WHOLE_FILE_LOCATION_REGEX = / f i l e : \/ \/ ( .+ ) : 0 : 0 : 0 : 0 / ;
44-
42+ const FILE_LOCATION_REGEX = / f i l e : \/ \/ ( .+ ) : ( [ 0 - 9 ] + ) : ( [ 0 - 9 ] + ) : ( [ 0 - 9 ] + ) : ( [ 0 - 9 ] + ) / ;
4543/**
4644 * Gets a resolvable source file location for the specified `LocationValue`, if possible.
4745 * @param loc The location to test.
4846 */
49- export function tryGetResolvableLocation ( loc : LocationValue | undefined ) : ResolvableLocationValue | undefined {
47+ export function tryGetResolvableLocation (
48+ loc : LocationValue | undefined
49+ ) : ResolvableLocationValue | undefined {
5050 if ( loc === undefined ) {
5151 return undefined ;
52- }
53- else if ( ( loc . t === LocationStyle . FivePart ) && loc . file ) {
52+ } else if ( loc . t === LocationStyle . FivePart && loc . file ) {
5453 return loc ;
55- }
56- else if ( ( loc . t === LocationStyle . WholeFile ) && loc . file ) {
54+ } else if ( loc . t === LocationStyle . WholeFile && loc . file ) {
5755 return loc ;
58- }
59- else if ( ( loc . t === LocationStyle . String ) && loc . loc ) {
60- return tryGetWholeFileLocation ( loc ) ;
61- }
62- else {
56+ } else if ( loc . t === LocationStyle . String && loc . loc ) {
57+ return tryGetLocationFromString ( loc ) ;
58+ } else {
6359 return undefined ;
6460 }
6561}
6662
67- export function tryGetWholeFileLocation ( loc : StringLocation ) : WholeFileLocation | undefined {
68- const matches = WHOLE_FILE_LOCATION_REGEX . exec ( loc . loc ) ;
63+ export function tryGetLocationFromString (
64+ loc : StringLocation
65+ ) : ResolvableLocationValue | undefined {
66+ const matches = FILE_LOCATION_REGEX . exec ( loc . loc ) ;
6967 if ( matches && matches . length > 1 && matches [ 1 ] ) {
70- // Whole-file location.
71- // We could represent this as a FivePartLocation with all numeric fields set to zero,
72- // but that would be a deliberate misuse as those fields are intended to be 1-based.
73- return {
74- t : LocationStyle . WholeFile ,
75- file : matches [ 1 ]
76- } ;
68+ if ( isWholeFileMatch ( matches ) ) {
69+ return {
70+ t : LocationStyle . WholeFile ,
71+ file : matches [ 1 ] ,
72+ } ;
73+ } else {
74+ return {
75+ t : LocationStyle . FivePart ,
76+ file : matches [ 1 ] ,
77+ lineStart : Number ( matches [ 2 ] ) ,
78+ colStart : Number ( matches [ 3 ] ) ,
79+ lineEnd : Number ( matches [ 4 ] ) ,
80+ colEnd : Number ( matches [ 5 ] ) ,
81+ }
82+ }
7783 } else {
7884 return undefined ;
7985 }
8086}
8187
88+ function isWholeFileMatch ( matches : RegExpExecArray ) : boolean {
89+ return (
90+ matches [ 2 ] === "0" &&
91+ matches [ 3 ] === "0" &&
92+ matches [ 4 ] === "0" &&
93+ matches [ 5 ] === "0"
94+ ) ;
95+ }
96+
8297export interface ElementBase {
8398 id : PrimitiveColumnValue ;
8499 label ?: string ;
@@ -93,8 +108,7 @@ export interface ElementWithLocation extends ElementBase {
93108 location : LocationValue ;
94109}
95110
96- export interface Element extends Required < ElementBase > {
97- }
111+ export interface Element extends Required < ElementBase > { }
98112
99113export type PrimitiveColumnValue = string | boolean | number | Date ;
100114export type ColumnValue = PrimitiveColumnValue | ElementBase ;
0 commit comments