Merge pull request #496 from jcreedcmu/jcreed/untangle

Reduce dependencies on internal modules
This commit is contained in:
jcreedcmu
2020-07-14 13:03:03 -04:00
committed by GitHub
15 changed files with 195 additions and 36 deletions

View File

@@ -20,6 +20,9 @@ export const config: webpack.Configuration = {
{
test: /\.(ts|tsx)$/,
loader: 'ts-loader',
options: {
configFile: 'src/view/tsconfig.json',
}
},
{
test: /\.less$/,

View File

@@ -600,8 +600,6 @@
"node-fetch": "~2.6.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"semmle-bqrs": "^0.0.1",
"semmle-io-node": "^0.0.1",
"@github/codeql-vscode-utils": "^0.0.4",
"tmp": "^0.1.0",
"tree-kill": "~1.2.2",

View File

@@ -1,5 +1,5 @@
import { DecodedBqrsChunk, ResultSetSchema, ColumnKind, Column, ColumnValue } from './bqrs-cli-types';
import { LocationValue, ResultSetSchema as AdaptedSchema, ColumnSchema, ColumnType, LocationStyle } from 'semmle-bqrs';
import { LocationValue, ResultSetSchema as AdaptedSchema, ColumnSchema, ColumnType, LocationStyle } from './bqrs-types';
import { ResultSet } from './interface-types';
// FIXME: This is a temporary bit of impedance matching to convert

View File

@@ -0,0 +1,102 @@
/**
* TODO: Types in this file are deprecated, and uses of them should be
* migrated to the analogous types in bqrs-cli-types.
*/
export enum LocationStyle {
None = 0,
String,
FivePart,
/** Does not occur in BQRS files. Used only to distinguish whole-file locations in client code. */
WholeFile
}
/**
* A primitive type (any type other than an element).
*/
export type PrimitiveTypeKind = 's' | 'b' | 'i' | 'f' | 'd' | 'u';
/**
* A kind of type that a column may have.
*/
export type ColumnTypeKind = PrimitiveTypeKind | 'e';
/**
* A column type that is a primitive type.
*/
export interface PrimitiveColumnType {
type: PrimitiveTypeKind;
}
/**
* A column type that is an element type.
*/
export interface ElementColumnType {
type: 'e';
primitiveType: PrimitiveTypeKind;
locationStyle: LocationStyle;
hasLabel: boolean;
}
/**
* The type of a column.
*/
export type ColumnType = PrimitiveColumnType | ElementColumnType;
/**
* The schema describing a single column in a `ResultSet`.
*/
export interface ColumnSchema {
readonly name: string;
readonly type: ColumnType;
}
/**
* The schema of a single `ResultSet` in a BQRS file.
*/
export interface ResultSetSchema {
readonly version: number;
readonly name: string;
readonly tupleCount: number;
readonly columns: readonly ColumnSchema[];
}
/**
* The schema describing the contents of a BQRS file.
*/
export interface ResultSetsSchema {
readonly version: number;
readonly stringPoolSize: number;
readonly resultSets: readonly ResultSetSchema[];
}
// See https://help.semmle.com/QL/learn-ql/ql/locations.html for how these are used.
export interface FivePartLocation {
t: LocationStyle.FivePart;
file: string;
lineStart: number;
colStart: number;
lineEnd: number;
colEnd: number;
}
export interface StringLocation {
t: LocationStyle.String;
loc: string;
}
/**
* A location representing an entire filesystem resource.
* This is usually derived from a `StringLocation` with the entire filesystem URL.
*/
export interface WholeFileLocation {
t: LocationStyle.WholeFile;
file: string;
}
export type RawLocationValue = FivePartLocation | StringLocation;
export type LocationValue = RawLocationValue | WholeFileLocation;
/** A location that may be resolved to a source code element. */
export type ResolvableLocationValue = FivePartLocation | WholeFileLocation;

View File

@@ -0,0 +1,64 @@
import { StringLocation, LocationValue, LocationStyle, ResolvableLocationValue } from './bqrs-types';
/**
* The CodeQL filesystem libraries use this pattern in `getURL()` predicates
* to describe the location of an entire filesystem resource.
* Such locations appear as `StringLocation`s instead of `FivePartLocation`s.
*
* Folder resources also get similar URLs, but with the `folder` scheme.
* They are deliberately ignored here, since there is no suitable location to show the user.
*/
const FILE_LOCATION_REGEX = /file:\/\/(.+):([0-9]+):([0-9]+):([0-9]+):([0-9]+)/;
/**
* Gets a resolvable source file location for the specified `LocationValue`, if possible.
* @param loc The location to test.
*/
export function tryGetResolvableLocation(
loc: LocationValue | undefined
): ResolvableLocationValue | undefined {
if (loc === undefined) {
return undefined;
} else if (loc.t === LocationStyle.FivePart && loc.file) {
return loc;
} else if (loc.t === LocationStyle.WholeFile && loc.file) {
return loc;
} else if (loc.t === LocationStyle.String && loc.loc) {
return tryGetLocationFromString(loc);
} else {
return undefined;
}
}
export function tryGetLocationFromString(
loc: StringLocation
): ResolvableLocationValue | undefined {
const matches = FILE_LOCATION_REGEX.exec(loc.loc);
if (matches && matches.length > 1 && matches[1]) {
if (isWholeFileMatch(matches)) {
return {
t: LocationStyle.WholeFile,
file: matches[1],
};
} else {
return {
t: LocationStyle.FivePart,
file: matches[1],
lineStart: Number(matches[2]),
colStart: Number(matches[3]),
lineEnd: Number(matches[4]),
colEnd: Number(matches[5]),
};
}
} else {
return undefined;
}
}
function isWholeFileMatch(matches: RegExpExecArray): boolean {
return (
matches[2] === '0' &&
matches[3] === '0' &&
matches[4] === '0' &&
matches[5] === '0'
);
}

View File

@@ -10,15 +10,14 @@
],
"jsx": "react",
"sourceMap": true,
"rootDir": "../..",
"rootDir": "..",
"strict": true,
"noUnusedLocals": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"experimentalDecorators": true,
"typeRoots" : ["./typings"]
"experimentalDecorators": true
},
"exclude": [
"node_modules"
]
}
}

View File

@@ -3,7 +3,7 @@ import {
ResolvableLocationValue,
ColumnSchema,
ResultSetSchema,
} from 'semmle-bqrs';
} from './bqrs-types';
import { ResultRow, ParsedResultSets, RawResultSet } from './adapt';
/**

View File

@@ -16,10 +16,12 @@ import {
FivePartLocation,
LocationStyle,
LocationValue,
tryGetResolvableLocation,
WholeFileLocation,
ResolvableLocationValue,
} from 'semmle-bqrs';
} from './bqrs-types';
import {
tryGetResolvableLocation,
} from './bqrs-utils';
import { DatabaseItem, DatabaseManager } from './databases';
import { ViewSourceFileMsg } from './interface-types';
import { Logger } from './logging';

View File

@@ -1,6 +1,6 @@
import * as Sarif from 'sarif';
import * as path from 'path';
import { LocationStyle, ResolvableLocationValue } from 'semmle-bqrs';
import { LocationStyle, ResolvableLocationValue } from './bqrs-types';
export interface SarifLink {
dest: number;

View File

@@ -3,7 +3,7 @@ import * as React from 'react';
import { vscode } from './vscode-api';
import { RawResultsSortState, SortDirection } from '../interface-types';
import { nextSortDirection } from './result-table-utils';
import { ColumnSchema } from 'semmle-bqrs';
import { ColumnSchema } from '../bqrs-types';
interface Props {
readonly columns: readonly ColumnSchema[];

View File

@@ -2,7 +2,7 @@ import * as path from 'path';
import * as React from 'react';
import * as Sarif from 'sarif';
import * as Keys from '../result-keys';
import { LocationStyle } from 'semmle-bqrs';
import { LocationStyle } from '../bqrs-types';
import * as octicons from './octicons';
import { className, renderLocation, ResultTableProps, zebraStripe, selectableZebraStripe, jumpToLocation, nextSortDirection } from './result-table-utils';
import { onNavigation, NavigationEvent } from './results';

View File

@@ -1,5 +1,6 @@
import * as React from 'react';
import { LocationValue, ResolvableLocationValue, tryGetResolvableLocation } from 'semmle-bqrs';
import { LocationValue, ResolvableLocationValue } from '../bqrs-types';
import { tryGetResolvableLocation } from '../bqrs-utils';
import { RawResultsSortState, QueryMetadata, SortDirection } from '../interface-types';
import { assertNever } from '../helpers-pure';
import { ResultSet } from '../interface-types';

View File

@@ -9,7 +9,7 @@ import {
tryResolveLocation,
} from '../../interface-utils';
import { getDefaultResultSetName } from '../../interface-types';
import { LocationStyle } from 'semmle-bqrs';
import { LocationStyle } from '../../bqrs-types';
import { DatabaseItem } from '../../databases';
describe('interface-utils', () => {

View File

@@ -1,6 +1,7 @@
import { expect } from 'chai';
import 'mocha';
import { LocationStyle, StringLocation, tryGetResolvableLocation } from 'semmle-bqrs';
import { LocationStyle, StringLocation } from '../../src/bqrs-types';
import { tryGetResolvableLocation } from '../../src/bqrs-utils';
describe('processing string locations', function () {
it('should detect Windows whole-file locations', function () {

View File

@@ -2,8 +2,6 @@ import { expect } from 'chai';
import * as fs from 'fs-extra';
import 'mocha';
import * as path from 'path';
import * as bqrs from 'semmle-bqrs';
import { FileReader } from 'semmle-io-node';
import * as tmp from 'tmp';
import * as url from 'url';
import { CancellationTokenSource } from 'vscode-jsonrpc';
@@ -11,6 +9,7 @@ import * as messages from '../../src/messages';
import * as qsClient from '../../src/queryserver-client';
import * as cli from '../../src/cli';
import { ProgressReporter, Logger } from '../../src/logging';
import { ColumnValue } from '../../src/bqrs-cli-types';
declare module 'url' {
@@ -50,7 +49,7 @@ class Checkpoint<T> {
}
type ResultSets = {
[name: string]: bqrs.ColumnValue[][];
[name: string]: ColumnValue[][];
}
type QueryTestCase = {
@@ -204,24 +203,14 @@ describe('using the query server', function() {
const actualResultSets: ResultSets = {};
it(`should be able to parse results of query ${queryName}`, async function() {
let fileReader: FileReader | undefined;
try {
await evaluationSucceeded.done();
fileReader = await FileReader.open(RESULTS_PATH);
const resultSetsReader = await bqrs.open(fileReader);
for (const reader of resultSetsReader.resultSets) {
const actualRows: bqrs.ColumnValue[][] = [];
for await (const row of reader.readTuples()) {
actualRows.push(row);
}
actualResultSets[reader.schema.name] = actualRows;
}
parsedResults.resolve();
} finally {
if (fileReader) {
fileReader.dispose();
}
await evaluationSucceeded.done();
const info = await cliServer.bqrsInfo(RESULTS_PATH);
for (const resultSet of info['result-sets']) {
const decoded = await cliServer.bqrsDecode(RESULTS_PATH, resultSet.name);
actualResultSets[resultSet.name] = decoded.tuples;
}
parsedResults.resolve();
});
it(`should have correct results for query ${queryName}`, async function() {