Merge pull request #3200 from github/koesie10/remove-namespace-imports
Remove unnecessary namespace imports
This commit is contained in:
@@ -66,7 +66,6 @@ const baseConfig = {
|
||||
"github/no-then": "off",
|
||||
"react/jsx-key": ["error", { checkFragmentShorthand: true }],
|
||||
"import/no-cycle": "off",
|
||||
"import/no-namespace": "off",
|
||||
// Never allow extensions in import paths, except for JSON files where they are required.
|
||||
"import/extensions": ["error", "never", { json: "always" }],
|
||||
},
|
||||
@@ -147,6 +146,8 @@ module.exports = {
|
||||
},
|
||||
rules: {
|
||||
...baseConfig.rules,
|
||||
// We want to allow mocking of functions in modules, so we need to allow namespace imports.
|
||||
"import/no-namespace": "off",
|
||||
"@typescript-eslint/ban-types": [
|
||||
"error",
|
||||
{
|
||||
@@ -181,5 +182,17 @@ module.exports = {
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: [".storybook/**/*.tsx"],
|
||||
parserOptions: {
|
||||
project: resolve(__dirname, ".storybook/tsconfig.json"),
|
||||
},
|
||||
rules: {
|
||||
...baseConfig.rules,
|
||||
// Storybook doesn't use the automatic JSX runtime in the addon yet, so we need to allow
|
||||
// `React` to be imported.
|
||||
"import/no-namespace": ["error", { ignore: ["react"] }],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
} from "fs-extra";
|
||||
import { resolve, join } from "path";
|
||||
import { isDevBuild } from "./dev";
|
||||
import type * as packageJsonType from "../package.json";
|
||||
import type packageJsonType from "../package.json";
|
||||
|
||||
export interface DeployedPackage {
|
||||
distPath: string;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { dest, src } from "gulp";
|
||||
import { load } from "js-yaml";
|
||||
import { obj } from "through2";
|
||||
import PluginError from "plugin-error";
|
||||
import * as Vinyl from "vinyl";
|
||||
import Vinyl from "vinyl";
|
||||
|
||||
/**
|
||||
* Replaces all rule references with the match pattern of the referenced rule.
|
||||
|
||||
@@ -3,7 +3,7 @@ import esbuild from "gulp-esbuild";
|
||||
import { createProject } from "gulp-typescript";
|
||||
import { goodReporter } from "./typescript";
|
||||
|
||||
import * as chromiumVersion from "./chromium-version.json";
|
||||
import chromiumVersion from "./chromium-version.json";
|
||||
|
||||
const tsProject = createProject("src/view/tsconfig.json");
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as semver from "semver";
|
||||
import { parse, SemVer } from "semver";
|
||||
import { runCodeQlCliCommand } from "./cli";
|
||||
import { Logger } from "../common/logging";
|
||||
import { getErrorMessage } from "../common/helpers-pure";
|
||||
@@ -9,7 +9,7 @@ import { getErrorMessage } from "../common/helpers-pure";
|
||||
export async function getCodeQlCliVersion(
|
||||
codeQlPath: string,
|
||||
logger: Logger,
|
||||
): Promise<semver.SemVer | undefined> {
|
||||
): Promise<SemVer | undefined> {
|
||||
try {
|
||||
const output: string = await runCodeQlCliCommand(
|
||||
codeQlPath,
|
||||
@@ -18,7 +18,7 @@ export async function getCodeQlCliVersion(
|
||||
"Checking CodeQL version",
|
||||
logger,
|
||||
);
|
||||
return semver.parse(output.trim()) || undefined;
|
||||
return parse(output.trim()) || undefined;
|
||||
} catch (e) {
|
||||
// Failed to run the version command. This might happen if the cli version is _really_ old, or it is corrupted.
|
||||
// Either way, we can't determine compatibility.
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import { EOL } from "os";
|
||||
import { spawn } from "child-process-promise";
|
||||
import * as child_process from "child_process";
|
||||
import {
|
||||
ChildProcessWithoutNullStreams,
|
||||
execFile,
|
||||
spawn as spawnChildProcess,
|
||||
} from "child_process";
|
||||
import { readFile } from "fs-extra";
|
||||
import { delimiter, dirname, join } from "path";
|
||||
import * as sarif from "sarif";
|
||||
import { Log } from "sarif";
|
||||
import { SemVer } from "semver";
|
||||
import { Readable } from "stream";
|
||||
import tk from "tree-kill";
|
||||
@@ -51,16 +55,6 @@ const CSV_FORMAT = "csv";
|
||||
*/
|
||||
const LOGGING_FLAGS = ["-v", "--log-to-stderr"];
|
||||
|
||||
/**
|
||||
* The expected output of `codeql resolve library-path`.
|
||||
*/
|
||||
export interface QuerySetup {
|
||||
libraryPath: string[];
|
||||
dbscheme: string;
|
||||
relativeName?: string;
|
||||
compilationCache?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* The expected output of `codeql resolve queries --format bylanguage`.
|
||||
*/
|
||||
@@ -88,7 +82,7 @@ export interface DbInfo {
|
||||
/**
|
||||
* The expected output of `codeql resolve upgrades`.
|
||||
*/
|
||||
export interface UpgradesInfo {
|
||||
interface UpgradesInfo {
|
||||
scripts: string[];
|
||||
finalDbscheme: string;
|
||||
matchesTarget?: boolean;
|
||||
@@ -102,33 +96,33 @@ export type QlpacksInfo = { [name: string]: string[] };
|
||||
/**
|
||||
* The expected output of `codeql resolve languages`.
|
||||
*/
|
||||
export type LanguagesInfo = { [name: string]: string[] };
|
||||
type LanguagesInfo = { [name: string]: string[] };
|
||||
|
||||
/** Information about an ML model, as resolved by `codeql resolve ml-models`. */
|
||||
export type MlModelInfo = {
|
||||
type MlModelInfo = {
|
||||
checksum: string;
|
||||
path: string;
|
||||
};
|
||||
|
||||
/** The expected output of `codeql resolve ml-models`. */
|
||||
export type MlModelsInfo = { models: MlModelInfo[] };
|
||||
type MlModelsInfo = { models: MlModelInfo[] };
|
||||
|
||||
/** Information about a data extension predicate, as resolved by `codeql resolve extensions`. */
|
||||
export type DataExtensionResult = {
|
||||
type DataExtensionResult = {
|
||||
predicate: string;
|
||||
file: string;
|
||||
index: number;
|
||||
};
|
||||
|
||||
/** The expected output of `codeql resolve extensions`. */
|
||||
export type ResolveExtensionsResult = {
|
||||
type ResolveExtensionsResult = {
|
||||
models: MlModelInfo[];
|
||||
data: {
|
||||
[path: string]: DataExtensionResult[];
|
||||
};
|
||||
};
|
||||
|
||||
export type GenerateExtensiblePredicateMetadataResult = {
|
||||
type GenerateExtensiblePredicateMetadataResult = {
|
||||
// There are other properties in this object, but they are
|
||||
// not relevant for its use in the extension, so we omit them.
|
||||
extensible_predicates: Array<{
|
||||
@@ -140,7 +134,7 @@ export type GenerateExtensiblePredicateMetadataResult = {
|
||||
/**
|
||||
* The expected output of `codeql resolve qlref`.
|
||||
*/
|
||||
export type QlrefInfo = { resolvedPath: string };
|
||||
type QlrefInfo = { resolvedPath: string };
|
||||
|
||||
// `codeql bqrs interpret` requires both of these to be present or
|
||||
// both absent.
|
||||
@@ -152,17 +146,17 @@ export interface SourceInfo {
|
||||
/**
|
||||
* The expected output of `codeql resolve queries`.
|
||||
*/
|
||||
export type ResolvedQueries = string[];
|
||||
type ResolvedQueries = string[];
|
||||
|
||||
/**
|
||||
* The expected output of `codeql resolve tests`.
|
||||
*/
|
||||
export type ResolvedTests = string[];
|
||||
type ResolvedTests = string[];
|
||||
|
||||
/**
|
||||
* A compilation message for a test message (either an error or a warning)
|
||||
*/
|
||||
export interface CompilationMessage {
|
||||
interface CompilationMessage {
|
||||
/**
|
||||
* The text of the message
|
||||
*/
|
||||
@@ -205,7 +199,7 @@ interface BqrsDecodeOptions {
|
||||
entities?: string[];
|
||||
}
|
||||
|
||||
export type OnLineCallback = (
|
||||
type OnLineCallback = (
|
||||
line: string,
|
||||
) => Promise<string | undefined> | string | undefined;
|
||||
|
||||
@@ -219,7 +213,7 @@ type VersionChangedListener = (newVersion: SemVer | undefined) => void;
|
||||
*/
|
||||
export class CodeQLCliServer implements Disposable {
|
||||
/** The process for the cli server, or undefined if one doesn't exist yet */
|
||||
process?: child_process.ChildProcessWithoutNullStreams;
|
||||
process?: ChildProcessWithoutNullStreams;
|
||||
/** Queue of future commands*/
|
||||
commandQueue: Array<() => void>;
|
||||
/** Whether a command is running */
|
||||
@@ -335,7 +329,7 @@ export class CodeQLCliServer implements Disposable {
|
||||
/**
|
||||
* Launch the cli server
|
||||
*/
|
||||
private async launchProcess(): Promise<child_process.ChildProcessWithoutNullStreams> {
|
||||
private async launchProcess(): Promise<ChildProcessWithoutNullStreams> {
|
||||
const codeQlPath = await this.getCodeQlPath();
|
||||
const args = [];
|
||||
if (shouldDebugCliServer()) {
|
||||
@@ -1101,7 +1095,7 @@ export class CodeQLCliServer implements Disposable {
|
||||
interpretedResultsPath: string,
|
||||
sourceInfo?: SourceInfo,
|
||||
args?: string[],
|
||||
): Promise<sarif.Log> {
|
||||
): Promise<Log> {
|
||||
const additionalArgs = [
|
||||
// TODO: This flag means that we don't group interpreted results
|
||||
// by primary location. We may want to revisit whether we call
|
||||
@@ -1592,7 +1586,7 @@ export function spawnServer(
|
||||
stderrListener: (data: any) => void,
|
||||
stdoutListener?: (data: any) => void,
|
||||
progressReporter?: ProgressReporter,
|
||||
): child_process.ChildProcessWithoutNullStreams {
|
||||
): ChildProcessWithoutNullStreams {
|
||||
// Enable verbose logging.
|
||||
const args = command.concat(commandArgs).concat(LOGGING_FLAGS);
|
||||
|
||||
@@ -1603,7 +1597,7 @@ export function spawnServer(
|
||||
progressReporter.report({ message: `Starting ${name}` });
|
||||
}
|
||||
void logger.log(`Starting ${name} using CodeQL CLI: ${base} ${argsString}`);
|
||||
const child = child_process.spawn(base, args);
|
||||
const child = spawnChildProcess(base, args);
|
||||
if (!child || !child.pid) {
|
||||
throw new Error(
|
||||
`Failed to start ${name} using command ${base} ${argsString}.`,
|
||||
@@ -1670,7 +1664,7 @@ export async function runCodeQlCliCommand(
|
||||
void logger.log(
|
||||
`${description} using CodeQL CLI: ${codeQlPath} ${argsString}...`,
|
||||
);
|
||||
const result = await promisify(child_process.execFile)(codeQlPath, args);
|
||||
const result = await promisify(execFile)(codeQlPath, args);
|
||||
void logger.log(result.stderr);
|
||||
void logger.log("CLI command succeeded.");
|
||||
return result.stdout;
|
||||
@@ -1710,7 +1704,7 @@ export function shouldDebugQueryServer() {
|
||||
return isEnvTrue("QUERY_SERVER_JAVA_DEBUG");
|
||||
}
|
||||
|
||||
export function shouldDebugCliServer() {
|
||||
function shouldDebugCliServer() {
|
||||
return isEnvTrue("CLI_SERVER_JAVA_DEBUG");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { pathExists, mkdtemp, createWriteStream, remove } from "fs-extra";
|
||||
import { createWriteStream, mkdtemp, pathExists, remove } from "fs-extra";
|
||||
import { tmpdir } from "os";
|
||||
import { delimiter, dirname, join } from "path";
|
||||
import * as semver from "semver";
|
||||
import { ExtensionContext, Event } from "vscode";
|
||||
import { Range, satisfies, SemVer } from "semver";
|
||||
import { Event, ExtensionContext } from "vscode";
|
||||
import { DistributionConfig } from "../config";
|
||||
import { extLogger } from "../common/logging/vscode";
|
||||
import { getCodeQlCliVersion } from "./cli-version";
|
||||
@@ -50,8 +50,7 @@ const NIGHTLY_DISTRIBUTION_REPOSITORY_NWO = "dsp-testing/codeql-cli-nightlies";
|
||||
*
|
||||
* This applies to both extension-managed and CLI distributions.
|
||||
*/
|
||||
export const DEFAULT_DISTRIBUTION_VERSION_RANGE: semver.Range =
|
||||
new semver.Range("2.x");
|
||||
export const DEFAULT_DISTRIBUTION_VERSION_RANGE: Range = new Range("2.x");
|
||||
|
||||
export interface DistributionProvider {
|
||||
getCodeQlPathWithoutVersionCheck(): Promise<string | undefined>;
|
||||
@@ -62,7 +61,7 @@ export interface DistributionProvider {
|
||||
export class DistributionManager implements DistributionProvider {
|
||||
constructor(
|
||||
public readonly config: DistributionConfig,
|
||||
private readonly versionRange: semver.Range,
|
||||
private readonly versionRange: Range,
|
||||
extensionContext: ExtensionContext,
|
||||
) {
|
||||
this._onDidChangeDistribution = config.onDidChangeConfiguration;
|
||||
@@ -121,7 +120,7 @@ export class DistributionManager implements DistributionProvider {
|
||||
distribution.kind !== DistributionKind.ExtensionManaged ||
|
||||
this.config.includePrerelease;
|
||||
|
||||
if (!semver.satisfies(version, this.versionRange, { includePrerelease })) {
|
||||
if (!satisfies(version, this.versionRange, { includePrerelease })) {
|
||||
return {
|
||||
distribution,
|
||||
kind: FindDistributionResultKind.IncompatibleDistribution,
|
||||
@@ -278,7 +277,7 @@ export class DistributionManager implements DistributionProvider {
|
||||
class ExtensionSpecificDistributionManager {
|
||||
constructor(
|
||||
private readonly config: DistributionConfig,
|
||||
private readonly versionRange: semver.Range,
|
||||
private readonly versionRange: Range,
|
||||
private readonly extensionContext: ExtensionContext,
|
||||
) {
|
||||
/**/
|
||||
@@ -601,7 +600,7 @@ interface DistributionResult {
|
||||
|
||||
interface CompatibleDistributionResult extends DistributionResult {
|
||||
kind: FindDistributionResultKind.CompatibleDistribution;
|
||||
version: semver.SemVer;
|
||||
version: SemVer;
|
||||
}
|
||||
|
||||
interface UnknownCompatibilityDistributionResult extends DistributionResult {
|
||||
@@ -610,7 +609,7 @@ interface UnknownCompatibilityDistributionResult extends DistributionResult {
|
||||
|
||||
interface IncompatibleDistributionResult extends DistributionResult {
|
||||
kind: FindDistributionResultKind.IncompatibleDistribution;
|
||||
version: semver.SemVer;
|
||||
version: SemVer;
|
||||
}
|
||||
|
||||
interface NoDistributionResult {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as fetch from "node-fetch";
|
||||
import * as semver from "semver";
|
||||
import { default as fetch, Response } from "node-fetch";
|
||||
import { compare, parse, Range, satisfies } from "semver";
|
||||
import { URL } from "url";
|
||||
import { Release, ReleaseAsset } from "./release";
|
||||
import { GithubRateLimitedError, GithubApiError } from "./github-api-error";
|
||||
import { GithubApiError, GithubRateLimitedError } from "./github-api-error";
|
||||
|
||||
/**
|
||||
* Communicates with the GitHub API to determine the latest compatible release and download assets.
|
||||
@@ -26,7 +26,7 @@ export class ReleasesApiConsumer {
|
||||
}
|
||||
|
||||
public async getLatestRelease(
|
||||
versionRange: semver.Range | undefined,
|
||||
versionRange: Range | undefined,
|
||||
orderBySemver = true,
|
||||
includePrerelease = false,
|
||||
additionalCompatibilityCheck?: (release: GithubRelease) => boolean,
|
||||
@@ -41,10 +41,10 @@ export class ReleasesApiConsumer {
|
||||
}
|
||||
|
||||
if (versionRange !== undefined) {
|
||||
const version = semver.parse(release.tag_name);
|
||||
const version = parse(release.tag_name);
|
||||
if (
|
||||
version === null ||
|
||||
!semver.satisfies(version, versionRange, { includePrerelease })
|
||||
!satisfies(version, versionRange, { includePrerelease })
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@@ -57,7 +57,7 @@ export class ReleasesApiConsumer {
|
||||
// Tag names must all be parsable to semvers due to the previous filtering step.
|
||||
const latestRelease = compatibleReleases.sort((a, b) => {
|
||||
const versionComparison = orderBySemver
|
||||
? semver.compare(semver.parse(b.tag_name)!, semver.parse(a.tag_name)!)
|
||||
? compare(parse(b.tag_name)!, parse(a.tag_name)!)
|
||||
: b.id - a.id;
|
||||
if (versionComparison !== 0) {
|
||||
return versionComparison;
|
||||
@@ -88,7 +88,7 @@ export class ReleasesApiConsumer {
|
||||
|
||||
public async streamBinaryContentOfAsset(
|
||||
asset: ReleaseAsset,
|
||||
): Promise<fetch.Response> {
|
||||
): Promise<Response> {
|
||||
const apiPath = `/repos/${this.repositoryNwo}/releases/assets/${asset.id}`;
|
||||
|
||||
return await this.makeApiCall(apiPath, {
|
||||
@@ -99,7 +99,7 @@ export class ReleasesApiConsumer {
|
||||
protected async makeApiCall(
|
||||
apiPath: string,
|
||||
additionalHeaders: { [key: string]: string } = {},
|
||||
): Promise<fetch.Response> {
|
||||
): Promise<Response> {
|
||||
const response = await this.makeRawRequest(
|
||||
ReleasesApiConsumer.apiBase + apiPath,
|
||||
Object.assign({}, this.defaultHeaders, additionalHeaders),
|
||||
@@ -128,8 +128,8 @@ export class ReleasesApiConsumer {
|
||||
requestUrl: string,
|
||||
headers: { [key: string]: string },
|
||||
redirectCount = 0,
|
||||
): Promise<fetch.Response> {
|
||||
const response = await fetch.default(requestUrl, {
|
||||
): Promise<Response> {
|
||||
const response = await fetch(requestUrl, {
|
||||
headers,
|
||||
redirect: "manual",
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as Octokit from "@octokit/rest";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
|
||||
/**
|
||||
* An interface providing methods for obtaining access tokens
|
||||
@@ -12,7 +12,7 @@ export interface Credentials {
|
||||
*
|
||||
* @returns An instance of Octokit.
|
||||
*/
|
||||
getOctokit(): Promise<Octokit.Octokit>;
|
||||
getOctokit(): Promise<Octokit>;
|
||||
|
||||
/**
|
||||
* Returns an OAuth access token.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as sarif from "sarif";
|
||||
import { Log, Result } from "sarif";
|
||||
import {
|
||||
VariantAnalysis,
|
||||
VariantAnalysisScannedRepositoryResult,
|
||||
@@ -76,7 +76,7 @@ export type SarifInterpretationData = {
|
||||
* they appear in the sarif file.
|
||||
*/
|
||||
sortState?: InterpretedResultsSortState;
|
||||
} & sarif.Log;
|
||||
} & Log;
|
||||
|
||||
export type GraphInterpretationData = {
|
||||
t: "GraphInterpretationData";
|
||||
@@ -393,8 +393,8 @@ export type RawQueryCompareResult = {
|
||||
export type InterpretedQueryCompareResult = {
|
||||
kind: "interpreted";
|
||||
sourceLocationPrefix: string;
|
||||
from: sarif.Result[];
|
||||
to: sarif.Result[];
|
||||
from: Result[];
|
||||
to: Result[];
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as Octokit from "@octokit/rest";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import { retry } from "@octokit/plugin-retry";
|
||||
import fetch from "node-fetch";
|
||||
|
||||
export const AppOctokit = Octokit.Octokit.defaults({
|
||||
export const AppOctokit = Octokit.defaults({
|
||||
request: {
|
||||
fetch,
|
||||
},
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import * as Sarif from "sarif";
|
||||
import { Log, Tool } from "sarif";
|
||||
import { createReadStream } from "fs-extra";
|
||||
import { connectTo } from "stream-json/Assembler";
|
||||
import { getErrorMessage } from "./helpers-pure";
|
||||
import { withParser } from "stream-json/filters/Pick";
|
||||
|
||||
const DUMMY_TOOL: Sarif.Tool = { driver: { name: "" } };
|
||||
const DUMMY_TOOL: Tool = { driver: { name: "" } };
|
||||
|
||||
export async function sarifParser(
|
||||
interpretedResultsPath: string,
|
||||
): Promise<Sarif.Log> {
|
||||
): Promise<Log> {
|
||||
try {
|
||||
// Parse the SARIF file into token streams, filtering out only the results array.
|
||||
const pipeline = createReadStream(interpretedResultsPath).pipe(
|
||||
@@ -38,7 +38,7 @@ export async function sarifParser(
|
||||
});
|
||||
|
||||
asm.on("done", (asm) => {
|
||||
const log: Sarif.Log = {
|
||||
const log: Log = {
|
||||
version: "2.1.0",
|
||||
runs: [
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as Sarif from "sarif";
|
||||
import { Location, Region } from "sarif";
|
||||
import type { HighlightedRegion } from "../variant-analysis/shared/analysis-result";
|
||||
import { UrlValueResolvable } from "./raw-result-types";
|
||||
import { isEmptyPath } from "./bqrs-utils";
|
||||
@@ -103,7 +103,7 @@ export function getPathRelativeToSourceLocationPrefix(
|
||||
* @param sourceLocationPrefix a file path (usually a full path) to the database containing the source location.
|
||||
*/
|
||||
export function parseSarifLocation(
|
||||
loc: Sarif.Location,
|
||||
loc: Location,
|
||||
sourceLocationPrefix: string,
|
||||
): ParsedSarifLocation {
|
||||
const physicalLocation = loc.physicalLocation;
|
||||
@@ -153,7 +153,7 @@ export function parseSarifLocation(
|
||||
}
|
||||
}
|
||||
|
||||
export function parseSarifRegion(region: Sarif.Region): {
|
||||
export function parseSarifRegion(region: Region): {
|
||||
startLine: number;
|
||||
endLine: number;
|
||||
startColumn: number;
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import * as vscode from "vscode";
|
||||
import { Uri, WebviewViewProvider } from "vscode";
|
||||
import { WebviewKind, WebviewMessage, getHtmlForWebview } from "./webview-html";
|
||||
import {
|
||||
CancellationToken,
|
||||
Uri,
|
||||
WebviewView,
|
||||
WebviewViewProvider,
|
||||
WebviewViewResolveContext,
|
||||
} from "vscode";
|
||||
import { getHtmlForWebview, WebviewKind, WebviewMessage } from "./webview-html";
|
||||
import { Disposable } from "../disposable-object";
|
||||
import { App } from "../app";
|
||||
import { DeepReadonly } from "../readonly";
|
||||
@@ -10,7 +15,7 @@ export abstract class AbstractWebviewViewProvider<
|
||||
FromMessage extends WebviewMessage,
|
||||
> implements WebviewViewProvider
|
||||
{
|
||||
protected webviewView: vscode.WebviewView | undefined = undefined;
|
||||
protected webviewView: WebviewView | undefined = undefined;
|
||||
private disposables: Disposable[] = [];
|
||||
|
||||
constructor(
|
||||
@@ -23,9 +28,9 @@ export abstract class AbstractWebviewViewProvider<
|
||||
* first loaded or when the user hides and then shows a view again.
|
||||
*/
|
||||
public resolveWebviewView(
|
||||
webviewView: vscode.WebviewView,
|
||||
_context: vscode.WebviewViewResolveContext,
|
||||
_token: vscode.CancellationToken,
|
||||
webviewView: WebviewView,
|
||||
_context: WebviewViewResolveContext,
|
||||
_token: CancellationToken,
|
||||
) {
|
||||
webviewView.webview.options = {
|
||||
enableScripts: true,
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
import { pathExists } from "fs-extra";
|
||||
import { Entry as ZipEntry, ZipFile } from "yauzl";
|
||||
import * as vscode from "vscode";
|
||||
import {
|
||||
Disposable,
|
||||
Event,
|
||||
EventEmitter,
|
||||
ExtensionContext,
|
||||
FileChangeEvent,
|
||||
FileStat,
|
||||
FileSystemError,
|
||||
FileSystemProvider,
|
||||
FileType,
|
||||
Uri,
|
||||
workspace,
|
||||
} from "vscode";
|
||||
import { extLogger } from "../logging/vscode";
|
||||
import {
|
||||
excludeDirectories,
|
||||
@@ -12,10 +24,11 @@ import {
|
||||
// All path operations in this file must be on paths *within* the zip
|
||||
// archive.
|
||||
import { posix } from "path";
|
||||
|
||||
const path = posix;
|
||||
|
||||
class File implements vscode.FileStat {
|
||||
type: vscode.FileType;
|
||||
class File implements FileStat {
|
||||
type: FileType;
|
||||
ctime: number;
|
||||
mtime: number;
|
||||
size: number;
|
||||
@@ -24,7 +37,7 @@ class File implements vscode.FileStat {
|
||||
public name: string,
|
||||
public data: Uint8Array,
|
||||
) {
|
||||
this.type = vscode.FileType.File;
|
||||
this.type = FileType.File;
|
||||
this.ctime = Date.now();
|
||||
this.mtime = Date.now();
|
||||
this.size = data.length;
|
||||
@@ -32,15 +45,15 @@ class File implements vscode.FileStat {
|
||||
}
|
||||
}
|
||||
|
||||
class Directory implements vscode.FileStat {
|
||||
type: vscode.FileType;
|
||||
class Directory implements FileStat {
|
||||
type: FileType;
|
||||
ctime: number;
|
||||
mtime: number;
|
||||
size: number;
|
||||
entries: Map<string, Entry> = new Map();
|
||||
|
||||
constructor(public name: string) {
|
||||
this.type = vscode.FileType.Directory;
|
||||
this.type = FileType.Directory;
|
||||
this.ctime = Date.now();
|
||||
this.mtime = Date.now();
|
||||
this.size = 0;
|
||||
@@ -58,7 +71,7 @@ type Entry = File | Directory;
|
||||
* dirMap['/foo'] = {'bar': vscode.FileType.Directory}
|
||||
* dirMap['/foo/bar'] = {'baz': vscode.FileType.File}
|
||||
*/
|
||||
type DirectoryHierarchyMap = Map<string, Map<string, vscode.FileType>>;
|
||||
type DirectoryHierarchyMap = Map<string, Map<string, FileType>>;
|
||||
|
||||
export type ZipFileReference = {
|
||||
sourceArchiveZipPath: string;
|
||||
@@ -66,7 +79,7 @@ export type ZipFileReference = {
|
||||
};
|
||||
|
||||
/** Encodes a reference to a source file within a zipped source archive into a single URI. */
|
||||
export function encodeSourceArchiveUri(ref: ZipFileReference): vscode.Uri {
|
||||
export function encodeSourceArchiveUri(ref: ZipFileReference): Uri {
|
||||
const { sourceArchiveZipPath, pathWithinSourceArchive } = ref;
|
||||
|
||||
// These two paths are put into a single URI with a custom scheme.
|
||||
@@ -94,7 +107,7 @@ export function encodeSourceArchiveUri(ref: ZipFileReference): vscode.Uri {
|
||||
const sourceArchiveZipPathEndIndex =
|
||||
sourceArchiveZipPathStartIndex + sourceArchiveZipPath.length;
|
||||
const authority = `${sourceArchiveZipPathStartIndex}-${sourceArchiveZipPathEndIndex}`;
|
||||
return vscode.Uri.parse(`${zipArchiveScheme}:/`, true).with({
|
||||
return Uri.parse(`${zipArchiveScheme}:/`, true).with({
|
||||
path: encodedPath,
|
||||
authority,
|
||||
});
|
||||
@@ -116,7 +129,7 @@ export function encodeArchiveBasePath(sourceArchiveZipPath: string) {
|
||||
const sourceArchiveUriAuthorityPattern = /^(\d+)-(\d+)$/;
|
||||
|
||||
class InvalidSourceArchiveUriError extends Error {
|
||||
constructor(uri: vscode.Uri) {
|
||||
constructor(uri: Uri) {
|
||||
super(
|
||||
`Can't decode uri ${uri}: authority should be of the form startIndex-endIndex (where both indices are integers).`,
|
||||
);
|
||||
@@ -124,7 +137,7 @@ class InvalidSourceArchiveUriError extends Error {
|
||||
}
|
||||
|
||||
/** Decodes an encoded source archive URI into its corresponding paths. Inverse of `encodeSourceArchiveUri`. */
|
||||
export function decodeSourceArchiveUri(uri: vscode.Uri): ZipFileReference {
|
||||
export function decodeSourceArchiveUri(uri: Uri): ZipFileReference {
|
||||
if (!uri.authority) {
|
||||
// Uri is malformed, but this is recoverable
|
||||
void extLogger.log(
|
||||
@@ -164,7 +177,7 @@ function ensureFile(map: DirectoryHierarchyMap, file: string) {
|
||||
throw new Error(error);
|
||||
}
|
||||
ensureDir(map, dirname);
|
||||
map.get(dirname)!.set(path.basename(file), vscode.FileType.File);
|
||||
map.get(dirname)!.set(path.basename(file), FileType.File);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -177,7 +190,7 @@ function ensureDir(map: DirectoryHierarchyMap, dir: string) {
|
||||
if (dir !== parent) {
|
||||
// not the root directory
|
||||
ensureDir(map, parent);
|
||||
map.get(parent)!.set(path.basename(dir), vscode.FileType.Directory);
|
||||
map.get(parent)!.set(path.basename(dir), FileType.Directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,7 +203,7 @@ type Archive = {
|
||||
|
||||
async function parse_zip(zipPath: string): Promise<Archive> {
|
||||
if (!(await pathExists(zipPath))) {
|
||||
throw vscode.FileSystemError.FileNotFound(zipPath);
|
||||
throw FileSystemError.FileNotFound(zipPath);
|
||||
}
|
||||
const zipFile = await openZip(zipPath, {
|
||||
lazyEntries: true,
|
||||
@@ -212,8 +225,8 @@ async function parse_zip(zipPath: string): Promise<Archive> {
|
||||
return archive;
|
||||
}
|
||||
|
||||
export class ArchiveFileSystemProvider implements vscode.FileSystemProvider {
|
||||
private readOnlyError = vscode.FileSystemError.NoPermissions(
|
||||
export class ArchiveFileSystemProvider implements FileSystemProvider {
|
||||
private readOnlyError = FileSystemError.NoPermissions(
|
||||
"write operation attempted, but source archive filesystem is readonly",
|
||||
);
|
||||
private archives: Map<string, Promise<Archive>> = new Map();
|
||||
@@ -229,63 +242,57 @@ export class ArchiveFileSystemProvider implements vscode.FileSystemProvider {
|
||||
|
||||
// metadata
|
||||
|
||||
async stat(uri: vscode.Uri): Promise<vscode.FileStat> {
|
||||
async stat(uri: Uri): Promise<FileStat> {
|
||||
return await this._lookup(uri);
|
||||
}
|
||||
|
||||
async readDirectory(
|
||||
uri: vscode.Uri,
|
||||
): Promise<Array<[string, vscode.FileType]>> {
|
||||
async readDirectory(uri: Uri): Promise<Array<[string, FileType]>> {
|
||||
const ref = decodeSourceArchiveUri(uri);
|
||||
const archive = await this.getArchive(ref.sourceArchiveZipPath);
|
||||
const contents = archive.dirMap.get(ref.pathWithinSourceArchive);
|
||||
const result =
|
||||
contents === undefined ? undefined : Array.from(contents.entries());
|
||||
if (result === undefined) {
|
||||
throw vscode.FileSystemError.FileNotFound(uri);
|
||||
throw FileSystemError.FileNotFound(uri);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// file contents
|
||||
|
||||
async readFile(uri: vscode.Uri): Promise<Uint8Array> {
|
||||
async readFile(uri: Uri): Promise<Uint8Array> {
|
||||
const data = (await this._lookupAsFile(uri)).data;
|
||||
if (data) {
|
||||
return data;
|
||||
}
|
||||
throw vscode.FileSystemError.FileNotFound();
|
||||
throw FileSystemError.FileNotFound();
|
||||
}
|
||||
|
||||
// write operations, all disabled
|
||||
|
||||
writeFile(
|
||||
_uri: vscode.Uri,
|
||||
_uri: Uri,
|
||||
_content: Uint8Array,
|
||||
_options: { create: boolean; overwrite: boolean },
|
||||
): void {
|
||||
throw this.readOnlyError;
|
||||
}
|
||||
|
||||
rename(
|
||||
_oldUri: vscode.Uri,
|
||||
_newUri: vscode.Uri,
|
||||
_options: { overwrite: boolean },
|
||||
): void {
|
||||
rename(_oldUri: Uri, _newUri: Uri, _options: { overwrite: boolean }): void {
|
||||
throw this.readOnlyError;
|
||||
}
|
||||
|
||||
delete(_uri: vscode.Uri): void {
|
||||
delete(_uri: Uri): void {
|
||||
throw this.readOnlyError;
|
||||
}
|
||||
|
||||
createDirectory(_uri: vscode.Uri): void {
|
||||
createDirectory(_uri: Uri): void {
|
||||
throw this.readOnlyError;
|
||||
}
|
||||
|
||||
// content lookup
|
||||
|
||||
private async _lookup(uri: vscode.Uri): Promise<Entry> {
|
||||
private async _lookup(uri: Uri): Promise<Entry> {
|
||||
const ref = decodeSourceArchiveUri(uri);
|
||||
const archive = await this.getArchive(ref.sourceArchiveZipPath);
|
||||
|
||||
@@ -307,31 +314,30 @@ export class ArchiveFileSystemProvider implements vscode.FileSystemProvider {
|
||||
if (archive.dirMap.has(reqPath)) {
|
||||
return new Directory(reqPath);
|
||||
}
|
||||
throw vscode.FileSystemError.FileNotFound(
|
||||
throw FileSystemError.FileNotFound(
|
||||
`uri '${uri.toString()}', interpreted as '${reqPath}' in archive '${
|
||||
ref.sourceArchiveZipPath
|
||||
}'`,
|
||||
);
|
||||
}
|
||||
|
||||
private async _lookupAsFile(uri: vscode.Uri): Promise<File> {
|
||||
private async _lookupAsFile(uri: Uri): Promise<File> {
|
||||
const entry = await this._lookup(uri);
|
||||
if (entry instanceof File) {
|
||||
return entry;
|
||||
}
|
||||
throw vscode.FileSystemError.FileIsADirectory(uri);
|
||||
throw FileSystemError.FileIsADirectory(uri);
|
||||
}
|
||||
|
||||
// file events
|
||||
|
||||
private _emitter = new vscode.EventEmitter<vscode.FileChangeEvent[]>();
|
||||
private _emitter = new EventEmitter<FileChangeEvent[]>();
|
||||
|
||||
readonly onDidChangeFile: vscode.Event<vscode.FileChangeEvent[]> =
|
||||
this._emitter.event;
|
||||
readonly onDidChangeFile: Event<FileChangeEvent[]> = this._emitter.event;
|
||||
|
||||
watch(_resource: vscode.Uri): vscode.Disposable {
|
||||
watch(_resource: Uri): Disposable {
|
||||
// ignore, fires for all changes...
|
||||
return new vscode.Disposable(() => {
|
||||
return new Disposable(() => {
|
||||
/**/
|
||||
});
|
||||
}
|
||||
@@ -347,9 +353,9 @@ export class ArchiveFileSystemProvider implements vscode.FileSystemProvider {
|
||||
*/
|
||||
export const zipArchiveScheme = "codeql-zip-archive";
|
||||
|
||||
export function activate(ctx: vscode.ExtensionContext) {
|
||||
export function activate(ctx: ExtensionContext) {
|
||||
ctx.subscriptions.push(
|
||||
vscode.workspace.registerFileSystemProvider(
|
||||
workspace.registerFileSystemProvider(
|
||||
zipArchiveScheme,
|
||||
new ArchiveFileSystemProvider(),
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as vscode from "vscode";
|
||||
import * as Octokit from "@octokit/rest";
|
||||
import { authentication } from "vscode";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import { Credentials } from "../authentication";
|
||||
import { AppOctokit } from "../octokit";
|
||||
|
||||
@@ -18,14 +18,14 @@ export class VSCodeCredentials implements Credentials {
|
||||
/**
|
||||
* A specific octokit to return, otherwise a new authenticated octokit will be created when needed.
|
||||
*/
|
||||
private octokit: Octokit.Octokit | undefined;
|
||||
private octokit: Octokit | undefined;
|
||||
|
||||
/**
|
||||
* Creates or returns an instance of Octokit.
|
||||
*
|
||||
* @returns An instance of Octokit.
|
||||
*/
|
||||
async getOctokit(): Promise<Octokit.Octokit> {
|
||||
async getOctokit(): Promise<Octokit> {
|
||||
if (this.octokit) {
|
||||
return this.octokit;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ export class VSCodeCredentials implements Credentials {
|
||||
}
|
||||
|
||||
async getAccessToken(): Promise<string> {
|
||||
const session = await vscode.authentication.getSession(
|
||||
const session = await authentication.getSession(
|
||||
GITHUB_AUTH_PROVIDER_ID,
|
||||
SCOPES,
|
||||
{ createIfNone: true },
|
||||
@@ -48,7 +48,7 @@ export class VSCodeCredentials implements Credentials {
|
||||
}
|
||||
|
||||
async getExistingAccessToken(): Promise<string | undefined> {
|
||||
const session = await vscode.authentication.getSession(
|
||||
const session = await authentication.getSession(
|
||||
GITHUB_AUTH_PROVIDER_ID,
|
||||
SCOPES,
|
||||
{ createIfNone: false },
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
isIntegrationTestMode,
|
||||
isCanary,
|
||||
} from "../../config";
|
||||
import * as appInsights from "applicationinsights";
|
||||
import { TelemetryClient } from "applicationinsights";
|
||||
import { extLogger } from "../logging/vscode";
|
||||
import { UserCancellationException } from "./progress";
|
||||
import { showBinaryChoiceWithUrlDialog } from "./dialog";
|
||||
@@ -129,8 +129,7 @@ export class ExtensionTelemetryListener
|
||||
);
|
||||
this.push(this.reporter);
|
||||
|
||||
const client = (this.reporter as any)
|
||||
.appInsightsClient as appInsights.TelemetryClient;
|
||||
const client = (this.reporter as any).appInsightsClient as TelemetryClient;
|
||||
if (client) {
|
||||
// add a telemetry processor to delete unwanted properties
|
||||
client.addTelemetryProcessor((envelope: any) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as vscode from "vscode";
|
||||
import { ExtensionContext, ExtensionMode } from "vscode";
|
||||
import { VSCodeCredentials } from "./authentication";
|
||||
import { Disposable } from "../disposable-object";
|
||||
import { App, AppMode, EnvironmentContext } from "../app";
|
||||
@@ -18,9 +18,7 @@ export class ExtensionApp implements App {
|
||||
public readonly commands: AppCommandManager;
|
||||
public readonly queryServerCommands: QueryServerCommandManager;
|
||||
|
||||
public constructor(
|
||||
public readonly extensionContext: vscode.ExtensionContext,
|
||||
) {
|
||||
public constructor(public readonly extensionContext: ExtensionContext) {
|
||||
this.credentials = new VSCodeCredentials();
|
||||
this.commands = createVSCodeCommandManager();
|
||||
this.queryServerCommands = createVSCodeCommandManager(queryServerLogger);
|
||||
@@ -49,9 +47,9 @@ export class ExtensionApp implements App {
|
||||
|
||||
public get mode(): AppMode {
|
||||
switch (this.extensionContext.extensionMode) {
|
||||
case vscode.ExtensionMode.Development:
|
||||
case ExtensionMode.Development:
|
||||
return AppMode.Development;
|
||||
case vscode.ExtensionMode.Test:
|
||||
case ExtensionMode.Test:
|
||||
return AppMode.Test;
|
||||
default:
|
||||
return AppMode.Production;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Uri } from "vscode";
|
||||
import * as sarif from "sarif";
|
||||
import { Log } from "sarif";
|
||||
import { pathExists } from "fs-extra";
|
||||
import { sarifParser } from "../common/sarif-parser";
|
||||
import { CompletedLocalQueryInfo } from "../query-results";
|
||||
@@ -11,7 +11,7 @@ import { sarifDiff } from "./sarif-diff";
|
||||
|
||||
async function getInterpretedResults(
|
||||
interpretedResultsPath: string,
|
||||
): Promise<sarif.Log | undefined> {
|
||||
): Promise<Log | undefined> {
|
||||
if (!(await pathExists(interpretedResultsPath))) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as sarif from "sarif";
|
||||
import { Result } from "sarif";
|
||||
|
||||
/**
|
||||
* Compare the alerts of two queries. Use deep equality to determine if
|
||||
@@ -16,10 +16,7 @@ import * as sarif from "sarif";
|
||||
* 1. If either query is empty
|
||||
* 2. If the queries are 100% disjoint
|
||||
*/
|
||||
export function sarifDiff(
|
||||
fromResults: sarif.Result[],
|
||||
toResults: sarif.Result[],
|
||||
) {
|
||||
export function sarifDiff(fromResults: Result[], toResults: Result[]) {
|
||||
if (!fromResults.length) {
|
||||
throw new Error("CodeQL Compare: Source query has no results.");
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
DB_CONFIG_VERSION,
|
||||
SelectedDbItemKind,
|
||||
} from "./db-config";
|
||||
import * as chokidar from "chokidar";
|
||||
import { FSWatcher, watch } from "chokidar";
|
||||
import {
|
||||
DisposableObject,
|
||||
DisposeHandler,
|
||||
@@ -37,7 +37,7 @@ export class DbConfigStore extends DisposableObject {
|
||||
|
||||
private config: DbConfig | undefined;
|
||||
private configErrors: DbConfigValidationError[];
|
||||
private configWatcher: chokidar.FSWatcher | undefined;
|
||||
private configWatcher: FSWatcher | undefined;
|
||||
|
||||
public constructor(
|
||||
private readonly app: App,
|
||||
@@ -367,20 +367,18 @@ export class DbConfigStore extends DisposableObject {
|
||||
}
|
||||
|
||||
private watchConfig(): void {
|
||||
this.configWatcher = chokidar
|
||||
.watch(this.configPath, {
|
||||
// In some cases, change events are emitted while the file is still
|
||||
// being written. The awaitWriteFinish option tells the watcher to
|
||||
// poll the file size, holding its add and change events until the size
|
||||
// does not change for a configurable amount of time. We set that time
|
||||
// to 1 second, but it may need to be adjusted if there are issues.
|
||||
awaitWriteFinish: {
|
||||
stabilityThreshold: 1000,
|
||||
},
|
||||
})
|
||||
.on("change", () => {
|
||||
this.readConfigSync();
|
||||
});
|
||||
this.configWatcher = watch(this.configPath, {
|
||||
// In some cases, change events are emitted while the file is still
|
||||
// being written. The awaitWriteFinish option tells the watcher to
|
||||
// poll the file size, holding its add and change events until the size
|
||||
// does not change for a configurable amount of time. We set that time
|
||||
// to 1 second, but it may need to be adjusted if there are issues.
|
||||
awaitWriteFinish: {
|
||||
stabilityThreshold: 1000,
|
||||
},
|
||||
}).on("change", () => {
|
||||
this.readConfigSync();
|
||||
});
|
||||
}
|
||||
|
||||
private createEmptyConfig(): DbConfig {
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
readdir,
|
||||
} from "fs-extra";
|
||||
import { basename, join } from "path";
|
||||
import * as Octokit from "@octokit/rest";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
|
||||
import { DatabaseManager, DatabaseItem } from "./local-databases";
|
||||
import { tmpDir } from "../tmp-dir";
|
||||
@@ -230,7 +230,7 @@ export async function downloadGitHubDatabaseFromUrl(
|
||||
commitOid: string | null,
|
||||
owner: string,
|
||||
name: string,
|
||||
octokit: Octokit.Octokit,
|
||||
octokit: Octokit,
|
||||
progress: ProgressCallback,
|
||||
databaseManager: DatabaseManager,
|
||||
storagePath: string,
|
||||
@@ -568,7 +568,7 @@ export async function findDirWithFile(
|
||||
|
||||
export async function convertGithubNwoToDatabaseUrl(
|
||||
nwo: string,
|
||||
octokit: Octokit.Octokit,
|
||||
octokit: Octokit,
|
||||
progress: ProgressCallback,
|
||||
language?: string,
|
||||
): Promise<
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import vscode from "vscode";
|
||||
import { Uri } from "vscode";
|
||||
|
||||
/**
|
||||
* The layout of the database.
|
||||
@@ -18,13 +18,13 @@ export interface DatabaseContents {
|
||||
*/
|
||||
name: string;
|
||||
/** The URI of the QL dataset within the database. */
|
||||
datasetUri: vscode.Uri;
|
||||
datasetUri: Uri;
|
||||
/** The URI of the source archive within the database, if one exists. */
|
||||
sourceArchiveUri?: vscode.Uri;
|
||||
sourceArchiveUri?: Uri;
|
||||
/** The URI of the CodeQL database scheme within the database, if exactly one exists. */
|
||||
dbSchemeUri?: vscode.Uri;
|
||||
dbSchemeUri?: Uri;
|
||||
}
|
||||
|
||||
export interface DatabaseContentsWithDbScheme extends DatabaseContents {
|
||||
dbSchemeUri: vscode.Uri; // Always present
|
||||
dbSchemeUri: Uri; // Always present
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Exported for testing
|
||||
import * as cli from "../../codeql-cli/cli";
|
||||
import vscode from "vscode";
|
||||
import { CodeQLCliServer, DbInfo } from "../../codeql-cli/cli";
|
||||
import { Uri, workspace } from "vscode";
|
||||
import { FullDatabaseOptions } from "./database-options";
|
||||
import { basename, dirname, extname, join } from "path";
|
||||
import {
|
||||
@@ -21,10 +21,10 @@ export class DatabaseItemImpl implements DatabaseItem {
|
||||
public error: Error | undefined = undefined;
|
||||
public contents: DatabaseContents | undefined;
|
||||
/** A cache of database info */
|
||||
private _dbinfo: cli.DbInfo | undefined;
|
||||
private _dbinfo: DbInfo | undefined;
|
||||
|
||||
public constructor(
|
||||
public readonly databaseUri: vscode.Uri,
|
||||
public readonly databaseUri: Uri,
|
||||
contents: DatabaseContents | undefined,
|
||||
private options: FullDatabaseOptions,
|
||||
) {
|
||||
@@ -45,7 +45,7 @@ export class DatabaseItemImpl implements DatabaseItem {
|
||||
this.options.displayName = newName;
|
||||
}
|
||||
|
||||
public get sourceArchive(): vscode.Uri | undefined {
|
||||
public get sourceArchive(): Uri | undefined {
|
||||
if (this.ignoreSourceArchive || this.contents === undefined) {
|
||||
return undefined;
|
||||
} else {
|
||||
@@ -66,9 +66,9 @@ export class DatabaseItemImpl implements DatabaseItem {
|
||||
return this.options.origin;
|
||||
}
|
||||
|
||||
public resolveSourceFile(uriStr: string | undefined): vscode.Uri {
|
||||
public resolveSourceFile(uriStr: string | undefined): Uri {
|
||||
const sourceArchive = this.sourceArchive;
|
||||
const uri = uriStr ? vscode.Uri.parse(uriStr, true) : undefined;
|
||||
const uri = uriStr ? Uri.parse(uriStr, true) : undefined;
|
||||
if (uri && uri.scheme !== "file") {
|
||||
throw new Error(
|
||||
`Invalid uri scheme in ${uriStr}. Only 'file' is allowed.`,
|
||||
@@ -131,7 +131,7 @@ export class DatabaseItemImpl implements DatabaseItem {
|
||||
/**
|
||||
* Returns information about a database.
|
||||
*/
|
||||
private async getDbInfo(server: cli.CodeQLCliServer): Promise<cli.DbInfo> {
|
||||
private async getDbInfo(server: CodeQLCliServer): Promise<DbInfo> {
|
||||
if (this._dbinfo === undefined) {
|
||||
this._dbinfo = await server.resolveDatabase(this.databaseUri.fsPath);
|
||||
}
|
||||
@@ -143,7 +143,7 @@ export class DatabaseItemImpl implements DatabaseItem {
|
||||
* has a `.dbinfo` file, which is the source of the prefix.
|
||||
*/
|
||||
public async getSourceLocationPrefix(
|
||||
server: cli.CodeQLCliServer,
|
||||
server: CodeQLCliServer,
|
||||
): Promise<string> {
|
||||
const dbInfo = await this.getDbInfo(server);
|
||||
return dbInfo.sourceLocationPrefix;
|
||||
@@ -152,7 +152,7 @@ export class DatabaseItemImpl implements DatabaseItem {
|
||||
/**
|
||||
* Returns path to dataset folder of database.
|
||||
*/
|
||||
public async getDatasetFolder(server: cli.CodeQLCliServer): Promise<string> {
|
||||
public async getDatasetFolder(server: CodeQLCliServer): Promise<string> {
|
||||
const dbInfo = await this.getDbInfo(server);
|
||||
return dbInfo.datasetFolder;
|
||||
}
|
||||
@@ -164,7 +164,7 @@ export class DatabaseItemImpl implements DatabaseItem {
|
||||
/**
|
||||
* Returns the root uri of the virtual filesystem for this database's source archive.
|
||||
*/
|
||||
public getSourceArchiveExplorerUri(): vscode.Uri {
|
||||
public getSourceArchiveExplorerUri(): Uri {
|
||||
const sourceArchive = this.sourceArchive;
|
||||
if (sourceArchive === undefined || !sourceArchive.fsPath.endsWith(".zip")) {
|
||||
throw new Error(this.verifyZippedSources());
|
||||
@@ -176,7 +176,7 @@ export class DatabaseItemImpl implements DatabaseItem {
|
||||
* Returns true if the database's source archive is in the workspace.
|
||||
*/
|
||||
public hasSourceArchiveInExplorer(): boolean {
|
||||
return (vscode.workspace.workspaceFolders || []).some((folder) =>
|
||||
return (workspace.workspaceFolders || []).some((folder) =>
|
||||
this.belongsToSourceArchiveExplorerUri(folder.uri),
|
||||
);
|
||||
}
|
||||
@@ -196,7 +196,7 @@ export class DatabaseItemImpl implements DatabaseItem {
|
||||
/**
|
||||
* Holds if `uri` belongs to this database's source archive.
|
||||
*/
|
||||
public belongsToSourceArchiveExplorerUri(uri: vscode.Uri): boolean {
|
||||
public belongsToSourceArchiveExplorerUri(uri: Uri): boolean {
|
||||
if (this.sourceArchive === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import vscode from "vscode";
|
||||
import * as cli from "../../codeql-cli/cli";
|
||||
import { Uri } from "vscode";
|
||||
import { CodeQLCliServer } from "../../codeql-cli/cli";
|
||||
import { DatabaseContents } from "./database-contents";
|
||||
import { DatabaseOptions } from "./database-options";
|
||||
import { DatabaseOrigin } from "./database-origin";
|
||||
@@ -7,14 +7,14 @@ import { DatabaseOrigin } from "./database-origin";
|
||||
/** An item in the list of available databases */
|
||||
export interface DatabaseItem {
|
||||
/** The URI of the database */
|
||||
readonly databaseUri: vscode.Uri;
|
||||
readonly databaseUri: Uri;
|
||||
/** The name of the database to be displayed in the UI */
|
||||
name: string;
|
||||
|
||||
/** The primary language of the database or empty string if unknown */
|
||||
readonly language: string;
|
||||
/** The URI of the database's source archive, or `undefined` if no source archive is to be used. */
|
||||
readonly sourceArchive: vscode.Uri | undefined;
|
||||
readonly sourceArchive: Uri | undefined;
|
||||
/**
|
||||
* The contents of the database.
|
||||
* Will be `undefined` if the database is invalid. Can be updated by calling `refresh()`.
|
||||
@@ -39,7 +39,7 @@ export interface DatabaseItem {
|
||||
*
|
||||
* @param file Filename within the source archive. May be `undefined` to return a dummy file path.
|
||||
*/
|
||||
resolveSourceFile(file: string | undefined): vscode.Uri;
|
||||
resolveSourceFile(file: string | undefined): Uri;
|
||||
|
||||
/**
|
||||
* Holds if the database item has a `.dbinfo` or `codeql-database.yml` file.
|
||||
@@ -49,18 +49,18 @@ export interface DatabaseItem {
|
||||
/**
|
||||
* Returns `sourceLocationPrefix` of exported database.
|
||||
*/
|
||||
getSourceLocationPrefix(server: cli.CodeQLCliServer): Promise<string>;
|
||||
getSourceLocationPrefix(server: CodeQLCliServer): Promise<string>;
|
||||
|
||||
/**
|
||||
* Returns dataset folder of exported database.
|
||||
*/
|
||||
getDatasetFolder(server: cli.CodeQLCliServer): Promise<string>;
|
||||
getDatasetFolder(server: CodeQLCliServer): Promise<string>;
|
||||
|
||||
/**
|
||||
* Returns the root uri of the virtual filesystem for this database's source archive,
|
||||
* as displayed in the filesystem explorer.
|
||||
*/
|
||||
getSourceArchiveExplorerUri(): vscode.Uri;
|
||||
getSourceArchiveExplorerUri(): Uri;
|
||||
|
||||
/**
|
||||
* Returns true if the database's source archive is in the workspace.
|
||||
@@ -70,7 +70,7 @@ export interface DatabaseItem {
|
||||
/**
|
||||
* Holds if `uri` belongs to this database's source archive.
|
||||
*/
|
||||
belongsToSourceArchiveExplorerUri(uri: vscode.Uri): boolean;
|
||||
belongsToSourceArchiveExplorerUri(uri: Uri): boolean;
|
||||
|
||||
/**
|
||||
* Whether the database may be affected by test execution for the given path.
|
||||
|
||||
@@ -4,7 +4,7 @@ import { extLogger } from "../../common/logging/vscode";
|
||||
import { DisposableObject } from "../../common/disposable-object";
|
||||
import { App } from "../../common/app";
|
||||
import { QueryRunner } from "../../query-server";
|
||||
import * as cli from "../../codeql-cli/cli";
|
||||
import { CodeQLCliServer } from "../../codeql-cli/cli";
|
||||
import { ProgressCallback, withProgress } from "../../common/vscode/progress";
|
||||
import {
|
||||
addDatabaseSourceToWorkspace,
|
||||
@@ -105,7 +105,7 @@ export class DatabaseManager extends DisposableObject {
|
||||
private readonly ctx: ExtensionContext,
|
||||
private readonly app: App,
|
||||
private readonly qs: QueryRunner,
|
||||
private readonly cli: cli.CodeQLCliServer,
|
||||
private readonly cli: CodeQLCliServer,
|
||||
private readonly languageContext: LanguageContextStore,
|
||||
public logger: Logger,
|
||||
) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import vscode from "vscode";
|
||||
import { Uri } from "vscode";
|
||||
import { pathExists } from "fs-extra";
|
||||
import { basename, join, resolve } from "path";
|
||||
import {
|
||||
@@ -16,7 +16,7 @@ import { extLogger } from "../../common/logging/vscode";
|
||||
|
||||
export class DatabaseResolver {
|
||||
public static async resolveDatabaseContents(
|
||||
uri: vscode.Uri,
|
||||
uri: Uri,
|
||||
): Promise<DatabaseContentsWithDbScheme> {
|
||||
if (uri.scheme !== "file") {
|
||||
throw new Error(
|
||||
@@ -51,7 +51,7 @@ export class DatabaseResolver {
|
||||
`Database '${databasePath}' contains multiple CodeQL dbschemes under '${dbPath}'.`,
|
||||
);
|
||||
} else {
|
||||
const dbSchemeUri = vscode.Uri.file(resolve(dbPath, dbSchemeFiles[0]));
|
||||
const dbSchemeUri = Uri.file(resolve(dbPath, dbSchemeFiles[0]));
|
||||
return {
|
||||
...contents,
|
||||
dbSchemeUri,
|
||||
@@ -83,7 +83,7 @@ export class DatabaseResolver {
|
||||
*/
|
||||
class InvalidDatabaseError extends Error {}
|
||||
|
||||
async function findDataset(parentDirectory: string): Promise<vscode.Uri> {
|
||||
async function findDataset(parentDirectory: string): Promise<Uri> {
|
||||
/*
|
||||
* Look directly in the root
|
||||
*/
|
||||
@@ -113,7 +113,7 @@ async function findDataset(parentDirectory: string): Promise<vscode.Uri> {
|
||||
);
|
||||
}
|
||||
|
||||
return vscode.Uri.file(dbAbsolutePath);
|
||||
return Uri.file(dbAbsolutePath);
|
||||
}
|
||||
|
||||
/** Gets the relative paths of all `.dbscheme` files in the given directory. */
|
||||
@@ -124,7 +124,7 @@ async function getDbSchemeFiles(dbDirectory: string): Promise<string[]> {
|
||||
// exported for testing
|
||||
export async function findSourceArchive(
|
||||
databasePath: string,
|
||||
): Promise<vscode.Uri | undefined> {
|
||||
): Promise<Uri | undefined> {
|
||||
const relativePaths = ["src", "output/src_archive"];
|
||||
|
||||
for (const relativePath of relativePaths) {
|
||||
@@ -135,7 +135,7 @@ export async function findSourceArchive(
|
||||
if (await pathExists(zipPath)) {
|
||||
return encodeArchiveBasePath(zipPath);
|
||||
} else if (await pathExists(basePath)) {
|
||||
return vscode.Uri.file(basePath);
|
||||
return Uri.file(basePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import * as vscode from "vscode";
|
||||
import {
|
||||
ThemeColor,
|
||||
ThemeIcon,
|
||||
TreeItem,
|
||||
TreeItemCollapsibleState,
|
||||
Uri,
|
||||
} from "vscode";
|
||||
import {
|
||||
DbItem,
|
||||
isSelectableDbItem,
|
||||
@@ -16,16 +22,16 @@ export const SELECTED_DB_ITEM_RESOURCE_URI = "codeql://databases?selected=true";
|
||||
* Represents an item in the database tree view. This item could be
|
||||
* representing an actual database item or a warning.
|
||||
*/
|
||||
export class DbTreeViewItem extends vscode.TreeItem {
|
||||
export class DbTreeViewItem extends TreeItem {
|
||||
constructor(
|
||||
// iconPath and tooltip must have those names because
|
||||
// they are part of the vscode.TreeItem interface
|
||||
|
||||
public readonly dbItem: DbItem | undefined,
|
||||
public readonly iconPath: vscode.ThemeIcon | undefined,
|
||||
public readonly iconPath: ThemeIcon | undefined,
|
||||
public readonly label: string,
|
||||
public readonly tooltip: string | undefined,
|
||||
public readonly collapsibleState: vscode.TreeItemCollapsibleState,
|
||||
public readonly collapsibleState: TreeItemCollapsibleState,
|
||||
public readonly children: DbTreeViewItem[],
|
||||
) {
|
||||
super(label, collapsibleState);
|
||||
@@ -40,7 +46,7 @@ export class DbTreeViewItem extends vscode.TreeItem {
|
||||
|
||||
public setAsSelected(): void {
|
||||
// Define the resource id to drive the UI to render this item as selected.
|
||||
this.resourceUri = vscode.Uri.parse(SELECTED_DB_ITEM_RESOURCE_URI);
|
||||
this.resourceUri = Uri.parse(SELECTED_DB_ITEM_RESOURCE_URI);
|
||||
}
|
||||
|
||||
public setAsUnselected(): void {
|
||||
@@ -59,13 +65,10 @@ export function createDbTreeViewItemError(
|
||||
): DbTreeViewItem {
|
||||
return new DbTreeViewItem(
|
||||
undefined,
|
||||
new vscode.ThemeIcon(
|
||||
"error",
|
||||
new vscode.ThemeColor("problemsErrorIcon.foreground"),
|
||||
),
|
||||
new ThemeIcon("error", new ThemeColor("problemsErrorIcon.foreground")),
|
||||
label,
|
||||
tooltip,
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
TreeItemCollapsibleState.None,
|
||||
[],
|
||||
);
|
||||
}
|
||||
@@ -93,10 +96,10 @@ export function createDbTreeViewItemSystemDefinedList(
|
||||
): DbTreeViewItem {
|
||||
return new DbTreeViewItem(
|
||||
dbItem,
|
||||
new vscode.ThemeIcon("github"),
|
||||
new ThemeIcon("github"),
|
||||
label,
|
||||
tooltip,
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
TreeItemCollapsibleState.None,
|
||||
[],
|
||||
);
|
||||
}
|
||||
@@ -122,10 +125,10 @@ export function createDbTreeViewItemOwner(
|
||||
): DbTreeViewItem {
|
||||
return new DbTreeViewItem(
|
||||
dbItem,
|
||||
new vscode.ThemeIcon("organization"),
|
||||
new ThemeIcon("organization"),
|
||||
ownerName,
|
||||
undefined,
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
TreeItemCollapsibleState.None,
|
||||
[],
|
||||
);
|
||||
}
|
||||
@@ -136,18 +139,16 @@ export function createDbTreeViewItemRepo(
|
||||
): DbTreeViewItem {
|
||||
return new DbTreeViewItem(
|
||||
dbItem,
|
||||
new vscode.ThemeIcon("cloud"),
|
||||
new ThemeIcon("cloud"),
|
||||
repoName,
|
||||
undefined,
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
TreeItemCollapsibleState.None,
|
||||
[],
|
||||
);
|
||||
}
|
||||
|
||||
function getCollapsibleState(
|
||||
expanded: boolean,
|
||||
): vscode.TreeItemCollapsibleState {
|
||||
function getCollapsibleState(expanded: boolean): TreeItemCollapsibleState {
|
||||
return expanded
|
||||
? vscode.TreeItemCollapsibleState.Expanded
|
||||
: vscode.TreeItemCollapsibleState.Collapsed;
|
||||
? TreeItemCollapsibleState.Expanded
|
||||
: TreeItemCollapsibleState.Collapsed;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
import { getOnDiskWorkspaceFolders } from "../common/vscode/workspace-folders";
|
||||
import { LocalQueries } from "../local-queries";
|
||||
import { getQuickEvalContext, validateQueryPath } from "../run-queries-shared";
|
||||
import * as CodeQLProtocol from "./debug-protocol";
|
||||
import { LaunchConfig } from "./debug-protocol";
|
||||
import { getErrorMessage } from "../common/helpers-pure";
|
||||
import { showAndLogErrorMessage } from "../common/logging";
|
||||
import { extLogger } from "../common/logging/vscode";
|
||||
@@ -36,8 +36,7 @@ export type QLDebugConfiguration = DebugConfiguration & QLDebugArgs;
|
||||
* A CodeQL debug configuration after all variables and defaults have been resolved. This is what
|
||||
* is passed to the debug adapter via the `launch` request.
|
||||
*/
|
||||
export type QLResolvedDebugConfiguration = DebugConfiguration &
|
||||
CodeQLProtocol.LaunchConfig;
|
||||
export type QLResolvedDebugConfiguration = DebugConfiguration & LaunchConfig;
|
||||
|
||||
/** If the specified value is a single element, then turn it into an array containing that element. */
|
||||
function makeArray<T extends Exclude<any, any[]>>(value: T | T[]): T[] {
|
||||
|
||||
@@ -16,6 +16,7 @@ import { BaseLogger, LogOptions } from "../common/logging";
|
||||
import { queryServerLogger } from "../common/logging/vscode";
|
||||
import { QueryResultType } from "../query-server/messages";
|
||||
import { CoreQueryResults, CoreQueryRun, QueryRunner } from "../query-server";
|
||||
// eslint-disable-next-line import/no-namespace -- There are two different debug protocols, so we should make a distinction.
|
||||
import * as CodeQLProtocol from "./debug-protocol";
|
||||
import { QuickEvalContext } from "../run-queries-shared";
|
||||
import { getErrorMessage } from "../common/helpers-pure";
|
||||
|
||||
@@ -18,7 +18,12 @@ import {
|
||||
validateQueryUri,
|
||||
} from "../run-queries-shared";
|
||||
import { QLResolvedDebugConfiguration } from "./debug-configuration";
|
||||
import * as CodeQLProtocol from "./debug-protocol";
|
||||
import {
|
||||
AnyProtocolMessage,
|
||||
EvaluationCompletedEvent,
|
||||
EvaluationStartedEvent,
|
||||
QuickEvalRequest,
|
||||
} from "./debug-protocol";
|
||||
import { App } from "../common/app";
|
||||
import { LocalQueryRun, LocalQueries } from "../local-queries";
|
||||
|
||||
@@ -46,7 +51,7 @@ class QLDebugAdapterTracker
|
||||
this.configuration = <QLResolvedDebugConfiguration>session.configuration;
|
||||
}
|
||||
|
||||
public onDidSendMessage(message: CodeQLProtocol.AnyProtocolMessage): void {
|
||||
public onDidSendMessage(message: AnyProtocolMessage): void {
|
||||
if (message.type === "event") {
|
||||
switch (message.event) {
|
||||
case "codeql-evaluation-started":
|
||||
@@ -77,7 +82,7 @@ class QLDebugAdapterTracker
|
||||
// Since we're not going through VS Code's launch path, we need to save dirty files ourselves.
|
||||
await saveBeforeStart();
|
||||
|
||||
const args: CodeQLProtocol.QuickEvalRequest["arguments"] = {
|
||||
const args: QuickEvalRequest["arguments"] = {
|
||||
quickEvalContext: await getQuickEvalContext(undefined, false),
|
||||
};
|
||||
await this.session.customRequest("codeql-quickeval", args);
|
||||
@@ -102,7 +107,7 @@ class QLDebugAdapterTracker
|
||||
|
||||
/** Updates the UI to track the currently executing query. */
|
||||
private async onEvaluationStarted(
|
||||
body: CodeQLProtocol.EvaluationStartedEvent["body"],
|
||||
body: EvaluationStartedEvent["body"],
|
||||
): Promise<void> {
|
||||
const dbUri = Uri.file(this.configuration.database);
|
||||
const dbItem = await this.dbm.createOrOpenDatabaseItem(dbUri, {
|
||||
@@ -128,7 +133,7 @@ class QLDebugAdapterTracker
|
||||
|
||||
/** Update the UI after a query has finished evaluating. */
|
||||
private async onEvaluationCompleted(
|
||||
body: CodeQLProtocol.EvaluationCompletedEvent["body"],
|
||||
body: EvaluationCompletedEvent["body"],
|
||||
): Promise<void> {
|
||||
if (this.localQueryRun !== undefined) {
|
||||
const results: CoreQueryResults = body;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as vscode from "vscode";
|
||||
import { Location, Range } from "vscode";
|
||||
|
||||
import {
|
||||
BqrsUrlValue,
|
||||
BqrsLineColumnLocation,
|
||||
BqrsUrlValue,
|
||||
} from "../../common/bqrs-cli-types";
|
||||
import { isEmptyPath } from "../../common/bqrs-utils";
|
||||
import { DatabaseItem } from "../../databases/local-databases";
|
||||
@@ -10,7 +10,7 @@ import { DatabaseItem } from "../../databases/local-databases";
|
||||
export function fileRangeFromURI(
|
||||
uri: BqrsUrlValue | undefined,
|
||||
db: DatabaseItem,
|
||||
): vscode.Location | undefined {
|
||||
): Location | undefined {
|
||||
if (!uri || typeof uri === "string") {
|
||||
return undefined;
|
||||
} else if ("startOffset" in uri) {
|
||||
@@ -20,7 +20,7 @@ export function fileRangeFromURI(
|
||||
if (isEmptyPath(loc.uri)) {
|
||||
return undefined;
|
||||
}
|
||||
const range = new vscode.Range(
|
||||
const range = new Range(
|
||||
Math.max(0, (loc.startLine || 0) - 1),
|
||||
Math.max(0, (loc.startColumn || 0) - 1),
|
||||
Math.max(0, (loc.endLine || 0) - 1),
|
||||
@@ -28,7 +28,7 @@ export function fileRangeFromURI(
|
||||
);
|
||||
try {
|
||||
if (uri.uri.startsWith("file:")) {
|
||||
return new vscode.Location(db.resolveSourceFile(uri.uri), range);
|
||||
return new Location(db.resolveSourceFile(uri.uri), range);
|
||||
}
|
||||
return undefined;
|
||||
} catch (e) {
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import * as Sarif from "sarif";
|
||||
import * as vscode from "vscode";
|
||||
import { Location, Result, Run } from "sarif";
|
||||
import {
|
||||
Diagnostic,
|
||||
DiagnosticRelatedInformation,
|
||||
DiagnosticSeverity,
|
||||
languages,
|
||||
Uri,
|
||||
window as Window,
|
||||
window,
|
||||
env,
|
||||
WebviewPanel,
|
||||
TextEditorSelectionChangeKind,
|
||||
TextEditorSelectionChangeEvent,
|
||||
ViewColumn,
|
||||
workspace,
|
||||
} from "vscode";
|
||||
import * as cli from "../codeql-cli/cli";
|
||||
import { CodeQLCliServer } from "../codeql-cli/cli";
|
||||
import { CodeQLCliServer, SourceInfo } from "../codeql-cli/cli";
|
||||
import {
|
||||
DatabaseEventKind,
|
||||
DatabaseItem,
|
||||
@@ -93,7 +95,7 @@ function sortMultiplier(sortDirection: SortDirection): number {
|
||||
}
|
||||
|
||||
function sortInterpretedResults(
|
||||
results: Sarif.Result[],
|
||||
results: Result[],
|
||||
sortState: InterpretedResultsSortState | undefined,
|
||||
): void {
|
||||
if (sortState !== undefined) {
|
||||
@@ -188,7 +190,7 @@ export class ResultsView extends AbstractWebview<
|
||||
// We can't use this.push for these two event listeners because they need to be disposed of when the view is
|
||||
// disposed, not when the panel is disposed. The results view is a singleton, so we shouldn't be calling this.push.
|
||||
this.disposableEventListeners.push(
|
||||
vscode.window.onDidChangeTextEditorSelection(
|
||||
window.onDidChangeTextEditorSelection(
|
||||
this.handleSelectionChange.bind(this),
|
||||
),
|
||||
);
|
||||
@@ -241,7 +243,7 @@ export class ResultsView extends AbstractWebview<
|
||||
if (!this.panel?.visible) {
|
||||
return;
|
||||
}
|
||||
// Reveal the panel now as the subsequent call to 'Window.showTextEditor' in 'showLocation' may destroy the webview otherwise.
|
||||
// Reveal the panel now as the subsequent call to 'window.showTextEditor' in 'showLocation' may destroy the webview otherwise.
|
||||
this.panel.reveal();
|
||||
await this.postMessage({ t: "navigate", direction });
|
||||
}
|
||||
@@ -363,12 +365,12 @@ export class ResultsView extends AbstractWebview<
|
||||
*
|
||||
* The goal is to avoid opening new columns when there already are two columns open.
|
||||
*/
|
||||
private chooseColumnForWebview(): vscode.ViewColumn {
|
||||
private chooseColumnForWebview(): ViewColumn {
|
||||
// This is not a great way to determine the number of view columns, but I
|
||||
// can't find a vscode API that does it any better.
|
||||
// Here, iterate through all the visible editors and determine the max view column.
|
||||
// This won't work if the largest view column is empty.
|
||||
const colCount = Window.visibleTextEditors.reduce(
|
||||
const colCount = window.visibleTextEditors.reduce(
|
||||
(maxVal, editor) =>
|
||||
Math.max(
|
||||
maxVal,
|
||||
@@ -377,15 +379,15 @@ export class ResultsView extends AbstractWebview<
|
||||
0,
|
||||
);
|
||||
if (colCount <= 1) {
|
||||
return vscode.ViewColumn.Beside;
|
||||
return ViewColumn.Beside;
|
||||
}
|
||||
const activeViewColumnNum = Number.parseInt(
|
||||
Window.activeTextEditor?.viewColumn?.toFixed() || "0",
|
||||
window.activeTextEditor?.viewColumn?.toFixed() || "0",
|
||||
10,
|
||||
);
|
||||
return activeViewColumnNum === colCount
|
||||
? vscode.ViewColumn.One
|
||||
: vscode.ViewColumn.Beside;
|
||||
? ViewColumn.One
|
||||
: ViewColumn.Beside;
|
||||
}
|
||||
|
||||
private async changeInterpretedSortState(
|
||||
@@ -481,7 +483,7 @@ export class ResultsView extends AbstractWebview<
|
||||
// user's workflow by immediately revealing the panel.
|
||||
const showButton = "View Results";
|
||||
const queryName = this.labelProvider.getShortLabel(fullQuery);
|
||||
const resultPromise = vscode.window.showInformationMessage(
|
||||
const resultPromise = window.showInformationMessage(
|
||||
`Finished running query ${
|
||||
queryName.length > 0 ? ` "${queryName}"` : ""
|
||||
}.`,
|
||||
@@ -609,8 +611,8 @@ export class ResultsView extends AbstractWebview<
|
||||
}
|
||||
|
||||
public async openFile(filePath: string) {
|
||||
const textDocument = await vscode.workspace.openTextDocument(filePath);
|
||||
await vscode.window.showTextDocument(textDocument, vscode.ViewColumn.One);
|
||||
const textDocument = await workspace.openTextDocument(filePath);
|
||||
await window.showTextDocument(textDocument, ViewColumn.One);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -699,7 +701,7 @@ export class ResultsView extends AbstractWebview<
|
||||
private async _getInterpretedResults(
|
||||
metadata: QueryMetadata | undefined,
|
||||
resultsPaths: ResultsPaths,
|
||||
sourceInfo: cli.SourceInfo | undefined,
|
||||
sourceInfo: SourceInfo | undefined,
|
||||
sourceLocationPrefix: string,
|
||||
sortState: InterpretedResultsSortState | undefined,
|
||||
): Promise<Interpretation | undefined> {
|
||||
@@ -753,7 +755,7 @@ export class ResultsView extends AbstractWebview<
|
||||
}
|
||||
|
||||
private getPageOfInterpretedResults(pageNumber: number): Interpretation {
|
||||
function getPageOfRun(run: Sarif.Run): Sarif.Run {
|
||||
function getPageOfRun(run: Run): Run {
|
||||
return {
|
||||
...run,
|
||||
results: run.results?.slice(
|
||||
@@ -926,7 +928,7 @@ export class ResultsView extends AbstractWebview<
|
||||
}
|
||||
const parsedMessage = parseSarifPlainTextMessage(message);
|
||||
const relatedInformation: DiagnosticRelatedInformation[] = [];
|
||||
const relatedLocationsById: { [k: number]: Sarif.Location } = {};
|
||||
const relatedLocationsById: { [k: number]: Location } = {};
|
||||
|
||||
for (const loc of result.relatedLocations || []) {
|
||||
relatedLocationsById[loc.id!] = loc;
|
||||
@@ -984,13 +986,11 @@ export class ResultsView extends AbstractWebview<
|
||||
};
|
||||
}
|
||||
|
||||
private handleSelectionChange(
|
||||
event: vscode.TextEditorSelectionChangeEvent,
|
||||
): void {
|
||||
if (event.kind === vscode.TextEditorSelectionChangeKind.Command) {
|
||||
private handleSelectionChange(event: TextEditorSelectionChangeEvent): void {
|
||||
if (event.kind === TextEditorSelectionChangeKind.Command) {
|
||||
return; // Ignore selection events we caused ourselves.
|
||||
}
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
const editor = window.activeTextEditor;
|
||||
if (editor !== undefined) {
|
||||
editor.setDecorations(shownLocationDecoration, []);
|
||||
editor.setDecorations(shownLocationLineDecoration, []);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { CodeQLCliServer, SourceInfo } from "../codeql-cli/cli";
|
||||
import { CoreCompletedQuery, QueryRunner } from "../query-server";
|
||||
import { DatabaseItem } from "../databases/local-databases";
|
||||
import { ProgressCallback } from "../common/vscode/progress";
|
||||
import * as Sarif from "sarif";
|
||||
import { Log } from "sarif";
|
||||
import { Mode } from "./shared/mode";
|
||||
import { getOnDiskWorkspaceFolders } from "../common/vscode/workspace-folders";
|
||||
import { interpretResultsSarif } from "../query-results";
|
||||
@@ -30,7 +30,7 @@ type AutoModelQueriesOptions = {
|
||||
};
|
||||
|
||||
export type AutoModelQueriesResult = {
|
||||
candidates: Sarif.Log;
|
||||
candidates: Log;
|
||||
};
|
||||
|
||||
export async function runAutoModelQueries({
|
||||
@@ -212,7 +212,7 @@ async function interpretAutomodelResults(
|
||||
completedQuery: CoreCompletedQuery,
|
||||
metadata: QueryMetadata,
|
||||
sourceInfo: SourceInfo | undefined,
|
||||
): Promise<Sarif.Log> {
|
||||
): Promise<Log> {
|
||||
const interpretedResultsPath = join(
|
||||
completedQuery.outputDir.querySaveDir,
|
||||
"results.sarif",
|
||||
|
||||
@@ -2,7 +2,7 @@ import { AutomodelMode, ModelRequest } from "./auto-model-api";
|
||||
import { Mode } from "./shared/mode";
|
||||
import { AutoModelQueriesResult } from "./auto-model-codeml-queries";
|
||||
import { assertNever } from "../common/helpers-pure";
|
||||
import * as Sarif from "sarif";
|
||||
import { Log } from "sarif";
|
||||
import { gzipEncode } from "../common/zlib";
|
||||
import { Method, MethodSignature } from "./method";
|
||||
import { ModeledMethod } from "./modeled-method";
|
||||
@@ -57,7 +57,7 @@ export function getCandidates(
|
||||
* @param log SARIF log to encode
|
||||
* @returns base64-encoded GZIP-compressed SARIF log
|
||||
*/
|
||||
export async function encodeSarif(log: Sarif.Log): Promise<string> {
|
||||
export async function encodeSarif(log: Log): Promise<string> {
|
||||
const json = JSON.stringify(log);
|
||||
const buffer = Buffer.from(json, "utf-8");
|
||||
const compressed = await gzipEncode(buffer);
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
import { autoPickExtensionsDirectory } from "./extensions-workspace-folder";
|
||||
|
||||
import { ExtensionPackMetadata } from "./extension-pack-metadata";
|
||||
import * as extensionPackMetadataSchemaJson from "./extension-pack-metadata.schema.json";
|
||||
import extensionPackMetadataSchemaJson from "./extension-pack-metadata.schema.json";
|
||||
|
||||
const ajv = new Ajv({ allErrors: true });
|
||||
const extensionPackValidate = ajv.compile(extensionPackMetadataSchemaJson);
|
||||
|
||||
@@ -14,13 +14,13 @@ import {
|
||||
ModelsAsDataLanguagePredicate,
|
||||
ModelsAsDataLanguagePredicates,
|
||||
} from "./languages";
|
||||
|
||||
import * as modelExtensionFileSchema from "./model-extension-file.schema.json";
|
||||
import { Mode } from "./shared/mode";
|
||||
import { assertNever } from "../common/helpers-pure";
|
||||
import { ModelExtensionFile } from "./model-extension-file";
|
||||
import { QueryLanguage } from "../common/query-language";
|
||||
|
||||
import modelExtensionFileSchema from "./model-extension-file.schema.json";
|
||||
|
||||
const ajv = new Ajv({ allErrors: true, allowUnionTypes: true });
|
||||
const modelExtensionFileSchemaValidate = ajv.compile(modelExtensionFileSchema);
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import Ajv from "ajv";
|
||||
import * as qlpackFileSchemaJson from "./qlpack-file.schema.json";
|
||||
import { QlPackFile } from "./qlpack-file";
|
||||
import { load } from "js-yaml";
|
||||
import { readFile } from "fs-extra";
|
||||
|
||||
import qlpackFileSchemaJson from "./qlpack-file.schema.json";
|
||||
|
||||
const ajv = new Ajv({ allErrors: true });
|
||||
const qlpackFileValidate = ajv.compile(qlpackFileSchemaJson);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as vscode from "vscode";
|
||||
import { TreeItem, TreeItemCollapsibleState, Uri } from "vscode";
|
||||
|
||||
export class QueryTreeViewItem extends vscode.TreeItem {
|
||||
export class QueryTreeViewItem extends TreeItem {
|
||||
constructor(
|
||||
name: string,
|
||||
public readonly path: string,
|
||||
@@ -17,7 +17,7 @@ export function createQueryTreeFolderItem(
|
||||
): QueryTreeViewItem {
|
||||
const item = new QueryTreeViewItem(name, path, children);
|
||||
item.tooltip = path;
|
||||
item.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed;
|
||||
item.collapsibleState = TreeItemCollapsibleState.Collapsed;
|
||||
item.contextValue = "queryFolder";
|
||||
return item;
|
||||
}
|
||||
@@ -30,12 +30,12 @@ export function createQueryTreeFileItem(
|
||||
const item = new QueryTreeViewItem(name, path, []);
|
||||
item.tooltip = path;
|
||||
item.description = language;
|
||||
item.collapsibleState = vscode.TreeItemCollapsibleState.None;
|
||||
item.collapsibleState = TreeItemCollapsibleState.None;
|
||||
item.contextValue = "queryFile";
|
||||
item.command = {
|
||||
title: "Open",
|
||||
command: "vscode.open",
|
||||
arguments: [vscode.Uri.file(path)],
|
||||
arguments: [Uri.file(path)],
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { CancellationTokenSource, env } from "vscode";
|
||||
|
||||
import * as messages from "./query-server/messages-shared";
|
||||
import * as cli from "./codeql-cli/cli";
|
||||
import { Position } from "./query-server/messages-shared";
|
||||
import { CodeQLCliServer, SourceInfo } from "./codeql-cli/cli";
|
||||
import { pathExists } from "fs-extra";
|
||||
import { basename } from "path";
|
||||
import {
|
||||
@@ -41,7 +41,7 @@ export interface InitialQueryInfo {
|
||||
readonly isQuickQuery: boolean;
|
||||
readonly isQuickEval: boolean;
|
||||
readonly isQuickEvalCount?: boolean; // Missing is false for backwards compatibility
|
||||
readonly quickEvalPosition?: messages.Position;
|
||||
readonly quickEvalPosition?: Position;
|
||||
readonly queryPath: string;
|
||||
readonly databaseInfo: DatabaseInfo;
|
||||
readonly start: Date;
|
||||
@@ -86,7 +86,7 @@ export class CompletedQueryInfo implements QueryWithResults {
|
||||
}
|
||||
|
||||
async updateSortState(
|
||||
server: cli.CodeQLCliServer,
|
||||
server: CodeQLCliServer,
|
||||
resultSetName: string,
|
||||
sortState?: RawResultsSortState,
|
||||
): Promise<void> {
|
||||
@@ -121,10 +121,10 @@ export class CompletedQueryInfo implements QueryWithResults {
|
||||
* Call cli command to interpret SARIF results.
|
||||
*/
|
||||
export async function interpretResultsSarif(
|
||||
cli: cli.CodeQLCliServer,
|
||||
cli: CodeQLCliServer,
|
||||
metadata: QueryMetadata | undefined,
|
||||
resultsPaths: ResultsPaths,
|
||||
sourceInfo?: cli.SourceInfo,
|
||||
sourceInfo?: SourceInfo,
|
||||
args?: string[],
|
||||
): Promise<SarifInterpretationData> {
|
||||
const { resultsPath, interpretedResultsPath } = resultsPaths;
|
||||
@@ -147,10 +147,10 @@ export async function interpretResultsSarif(
|
||||
* Call cli command to interpret graph results.
|
||||
*/
|
||||
export async function interpretGraphResults(
|
||||
cliServer: cli.CodeQLCliServer,
|
||||
cliServer: CodeQLCliServer,
|
||||
metadata: QueryMetadata | undefined,
|
||||
resultsPaths: ResultsPaths,
|
||||
sourceInfo?: cli.SourceInfo,
|
||||
sourceInfo?: SourceInfo,
|
||||
): Promise<GraphInterpretationData> {
|
||||
const { resultsPath, interpretedResultsPath } = resultsPaths;
|
||||
if (await pathExists(interpretedResultsPath)) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import { RequestType } from "vscode-jsonrpc";
|
||||
// eslint-disable-next-line import/no-namespace -- these names are intentionally the same
|
||||
import * as shared from "./messages-shared";
|
||||
|
||||
/**
|
||||
@@ -44,7 +45,7 @@ export interface TrimCacheParams {
|
||||
/**
|
||||
* The result of trimming or clearing the cache.
|
||||
*/
|
||||
export interface ClearCacheResult {
|
||||
interface ClearCacheResult {
|
||||
/**
|
||||
* A user friendly message saying what was or would be
|
||||
* deleted.
|
||||
@@ -91,19 +92,19 @@ export namespace QueryResultType {
|
||||
export const DBSCHEME_NO_UPGRADE = 6;
|
||||
}
|
||||
|
||||
export interface RegisterDatabasesParams {
|
||||
interface RegisterDatabasesParams {
|
||||
databases: string[];
|
||||
}
|
||||
|
||||
export interface DeregisterDatabasesParams {
|
||||
interface DeregisterDatabasesParams {
|
||||
databases: string[];
|
||||
}
|
||||
|
||||
export type RegisterDatabasesResult = {
|
||||
type RegisterDatabasesResult = {
|
||||
registeredDatabases: string[];
|
||||
};
|
||||
|
||||
export type DeregisterDatabasesResult = {
|
||||
type DeregisterDatabasesResult = {
|
||||
registeredDatabases: string[];
|
||||
};
|
||||
|
||||
@@ -129,22 +130,22 @@ export interface RunQueryParams {
|
||||
extensionPacks?: string[];
|
||||
}
|
||||
|
||||
export interface RunQueryResult {
|
||||
interface RunQueryResult {
|
||||
resultType: QueryResultType;
|
||||
message?: string;
|
||||
expectedDbschemeName?: string;
|
||||
evaluationTime: number;
|
||||
}
|
||||
|
||||
export interface UpgradeParams {
|
||||
interface UpgradeParams {
|
||||
db: string;
|
||||
additionalPacks: string[];
|
||||
}
|
||||
|
||||
export type UpgradeResult = Record<string, unknown>;
|
||||
type UpgradeResult = Record<string, unknown>;
|
||||
|
||||
export type ClearPackCacheParams = Record<string, unknown>;
|
||||
export type ClearPackCacheResult = Record<string, unknown>;
|
||||
type ClearPackCacheParams = Record<string, unknown>;
|
||||
type ClearPackCacheResult = Record<string, unknown>;
|
||||
|
||||
/**
|
||||
* A position within a QL file.
|
||||
@@ -155,9 +156,7 @@ export type Position = shared.Position;
|
||||
* The way of compiling the query, as a normal query
|
||||
* or a subset of it. Note that precisely one of the two options should be set.
|
||||
*/
|
||||
export type CompilationTarget = shared.CompilationTarget;
|
||||
|
||||
export type QuickEvalOptions = shared.QuickEvalOptions;
|
||||
type CompilationTarget = shared.CompilationTarget;
|
||||
|
||||
export type WithProgressId<T> = shared.WithProgressId<T>;
|
||||
export type ProgressMessage = shared.ProgressMessage;
|
||||
|
||||
@@ -3,7 +3,11 @@ import { ensureFile } from "fs-extra";
|
||||
import { DisposableObject, DisposeHandler } from "../common/disposable-object";
|
||||
import { CancellationToken } from "vscode";
|
||||
import { createMessageConnection, RequestType } from "vscode-jsonrpc/node";
|
||||
import * as cli from "../codeql-cli/cli";
|
||||
import {
|
||||
CodeQLCliServer,
|
||||
shouldDebugQueryServer,
|
||||
spawnServer,
|
||||
} from "../codeql-cli/cli";
|
||||
import { QueryServerConfig } from "../config";
|
||||
import { BaseLogger, Logger, showAndLogErrorMessage } from "../common/logging";
|
||||
import { extLogger, ProgressReporter } from "../common/logging/vscode";
|
||||
@@ -62,7 +66,7 @@ export class QueryServerClient extends DisposableObject {
|
||||
constructor(
|
||||
app: App,
|
||||
readonly config: QueryServerConfig,
|
||||
readonly cliServer: cli.CodeQLCliServer,
|
||||
readonly cliServer: CodeQLCliServer,
|
||||
readonly opts: ServerOpts,
|
||||
withProgressReporting: WithProgressReporting,
|
||||
) {
|
||||
@@ -198,13 +202,13 @@ export class QueryServerClient extends DisposableObject {
|
||||
args.push("--debug", "--tuple-counting");
|
||||
}
|
||||
|
||||
if (cli.shouldDebugQueryServer()) {
|
||||
if (shouldDebugQueryServer()) {
|
||||
args.push(
|
||||
"-J=-agentlib:jdwp=transport=dt_socket,address=localhost:9010,server=y,suspend=y,quiet=y",
|
||||
);
|
||||
}
|
||||
|
||||
const child = cli.spawnServer(
|
||||
const child = spawnServer(
|
||||
this.config.codeQlPath,
|
||||
"CodeQL query server",
|
||||
["execute", "query-server2"],
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { CancellationToken } from "vscode";
|
||||
import { ProgressCallback } from "../common/vscode/progress";
|
||||
import * as messages from "./messages";
|
||||
import { runQuery, RunQueryParams } from "./messages";
|
||||
import { QueryOutputDir } from "../run-queries-shared";
|
||||
import * as qsClient from "./query-server-client";
|
||||
import { QueryServerClient } from "./query-server-client";
|
||||
import { CoreQueryResults, CoreQueryTarget } from "./query-runner";
|
||||
import { BaseLogger } from "../common/logging";
|
||||
|
||||
@@ -21,7 +21,7 @@ import { BaseLogger } from "../common/logging";
|
||||
*/
|
||||
|
||||
export async function compileAndRunQueryAgainstDatabaseCore(
|
||||
qs: qsClient.QueryServerClient,
|
||||
qs: QueryServerClient,
|
||||
dbPath: string,
|
||||
query: CoreQueryTarget,
|
||||
generateEvalLog: boolean,
|
||||
@@ -45,7 +45,7 @@ export async function compileAndRunQueryAgainstDatabaseCore(
|
||||
: { query: {} };
|
||||
|
||||
const evalLogPath = generateEvalLog ? outputDir.evalLogPath : undefined;
|
||||
const queryToRun: messages.RunQueryParams = {
|
||||
const queryToRun: RunQueryParams = {
|
||||
db: dbPath,
|
||||
additionalPacks,
|
||||
externalInputs: {},
|
||||
@@ -65,12 +65,7 @@ export async function compileAndRunQueryAgainstDatabaseCore(
|
||||
// in parallel, each query's log messages are interleaved. Fixing this
|
||||
// properly will require a change in the query server.
|
||||
qs.activeQueryLogger = logger;
|
||||
const result = await qs.sendRequest(
|
||||
messages.runQuery,
|
||||
queryToRun,
|
||||
token,
|
||||
progress,
|
||||
);
|
||||
const result = await qs.sendRequest(runQuery, queryToRun, token, progress);
|
||||
|
||||
return {
|
||||
resultType: result.resultType,
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { Logger } from "../common/logging";
|
||||
import * as cp from "child_process";
|
||||
import { ChildProcess } from "child_process";
|
||||
import { Disposable } from "vscode";
|
||||
import { MessageConnection } from "vscode-jsonrpc";
|
||||
|
||||
/** A running query server process and its associated message connection. */
|
||||
export class ServerProcess implements Disposable {
|
||||
child: cp.ChildProcess;
|
||||
child: ChildProcess;
|
||||
connection: MessageConnection;
|
||||
logger: Logger;
|
||||
|
||||
constructor(
|
||||
child: cp.ChildProcess,
|
||||
child: ChildProcess,
|
||||
connection: MessageConnection,
|
||||
private name: string,
|
||||
logger: Logger,
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
import { extname } from "path";
|
||||
import * as vscode from "vscode";
|
||||
import {
|
||||
CancellationTokenSource,
|
||||
Event,
|
||||
EventEmitter,
|
||||
WorkspaceFolder,
|
||||
} from "vscode";
|
||||
import {
|
||||
TestAdapter,
|
||||
TestLoadStartedEvent,
|
||||
TestLoadFinishedEvent,
|
||||
TestRunStartedEvent,
|
||||
TestRunFinishedEvent,
|
||||
TestSuiteEvent,
|
||||
TestEvent,
|
||||
TestSuiteInfo,
|
||||
TestInfo,
|
||||
TestHub,
|
||||
TestInfo,
|
||||
TestLoadFinishedEvent,
|
||||
TestLoadStartedEvent,
|
||||
TestRunFinishedEvent,
|
||||
TestRunStartedEvent,
|
||||
TestSuiteEvent,
|
||||
TestSuiteInfo,
|
||||
} from "vscode-test-adapter-api";
|
||||
import { TestAdapterRegistrar } from "vscode-test-adapter-util";
|
||||
import { QLTestDiscovery } from "./qltest-discovery";
|
||||
import { Event, EventEmitter, CancellationTokenSource } from "vscode";
|
||||
import { DisposableObject } from "../common/disposable-object";
|
||||
import { CodeQLCliServer, TestCompleted } from "../codeql-cli/cli";
|
||||
import { testLogger } from "../common/logging/vscode";
|
||||
@@ -95,10 +99,10 @@ export class QLTestAdapter extends DisposableObject implements TestAdapter {
|
||||
>(),
|
||||
);
|
||||
private readonly _autorun = this.push(new EventEmitter<void>());
|
||||
private runningTask?: vscode.CancellationTokenSource = undefined;
|
||||
private runningTask?: CancellationTokenSource = undefined;
|
||||
|
||||
constructor(
|
||||
public readonly workspaceFolder: vscode.WorkspaceFolder,
|
||||
public readonly workspaceFolder: WorkspaceFolder,
|
||||
private readonly testRunner: TestRunner,
|
||||
cliServer: CodeQLCliServer,
|
||||
) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as messages from "./query-server/messages-shared";
|
||||
import { Position } from "./query-server/messages-shared";
|
||||
import { DatabaseInfo, QueryMetadata } from "./common/interface-types";
|
||||
import { join, parse, dirname, basename } from "path";
|
||||
import { Range, TextEditor, Uri, window, workspace } from "vscode";
|
||||
@@ -132,7 +132,7 @@ export class QueryEvaluationInfo extends QueryOutputDir {
|
||||
querySaveDir: string,
|
||||
public readonly dbItemPath: string,
|
||||
public readonly databaseHasMetadataFile: boolean,
|
||||
public readonly quickEvalPosition?: messages.Position,
|
||||
public readonly quickEvalPosition?: Position,
|
||||
public readonly metadata?: QueryMetadata,
|
||||
) {
|
||||
super(querySaveDir);
|
||||
@@ -414,7 +414,7 @@ export function validateQueryPath(
|
||||
}
|
||||
|
||||
export interface QuickEvalContext {
|
||||
quickEvalPosition: messages.Position;
|
||||
quickEvalPosition: Position;
|
||||
quickEvalText: string;
|
||||
quickEvalCount: boolean;
|
||||
}
|
||||
@@ -466,7 +466,7 @@ export interface SelectedQuery {
|
||||
async function getSelectedPosition(
|
||||
editor: TextEditor,
|
||||
range?: Range,
|
||||
): Promise<messages.Position> {
|
||||
): Promise<Position> {
|
||||
const selectedRange = range || editor.selection;
|
||||
const pos = selectedRange.start;
|
||||
const posEnd = selectedRange.end;
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Codicon as CodiconComponent } from "../../../view/common";
|
||||
|
||||
// To regenerate the icons, use the following command from the `extensions/ql-vscode` directory:
|
||||
// jq -R '[inputs | [splits(", *")] as $row | $row[0]]' < node_modules/@vscode/codicons/dist/codicon.csv > src/stories/common/icon/vscode-icons.json
|
||||
// eslint-disable-next-line import/no-namespace -- This is an array in a JSON file, so we can't use named imports
|
||||
import * as icons from "./vscode-icons.json";
|
||||
|
||||
export default {
|
||||
|
||||
@@ -11,7 +11,8 @@ import {
|
||||
} from "../../variant-analysis/shared/analysis-result";
|
||||
import { createMockRepositoryWithMetadata } from "../../../test/factories/variant-analysis/shared/repository";
|
||||
|
||||
import * as analysesResults from "../data/analysesResultsMessage.json";
|
||||
import { analysesResults } from "../data/analysesResultsMessage.json";
|
||||
// eslint-disable-next-line import/no-namespace -- We need the full JSON object, so we can't use named imports
|
||||
import * as rawResults from "../data/rawResults.json";
|
||||
import { RepoRow, RepoRowProps } from "../../view/variant-analysis/RepoRow";
|
||||
|
||||
@@ -120,7 +121,7 @@ InterpretedResults.args = {
|
||||
...Pending.args,
|
||||
status: VariantAnalysisRepoStatus.Succeeded,
|
||||
resultCount: 198,
|
||||
interpretedResults: analysesResults.analysesResults.find(
|
||||
interpretedResults: analysesResults.find(
|
||||
(v) => v.nwo === "facebook/create-react-app",
|
||||
)?.interpretedResults as AnalysisAlert[],
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ import { createMockVariantAnalysis } from "../../../test/factories/variant-analy
|
||||
import { createMockRepositoryWithMetadata } from "../../../test/factories/variant-analysis/shared/repository";
|
||||
import { createMockScannedRepo } from "../../../test/factories/variant-analysis/shared/scanned-repositories";
|
||||
|
||||
import * as analysesResults from "../data/analysesResultsMessage.json";
|
||||
import { analysesResults } from "../data/analysesResultsMessage.json";
|
||||
|
||||
export default {
|
||||
title: "Variant Analysis/Analyzed Repos",
|
||||
@@ -35,7 +35,7 @@ const Template: StoryFn<typeof VariantAnalysisAnalyzedRepos> = (args) => (
|
||||
const interpretedResultsForRepo = (
|
||||
nwo: string,
|
||||
): AnalysisAlert[] | undefined => {
|
||||
return analysesResults.analysesResults.find((v) => v.nwo === nwo)
|
||||
return analysesResults.find((v) => v.nwo === nwo)
|
||||
?.interpretedResults as AnalysisAlert[];
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { dir, tmpName } from "tmp-promise";
|
||||
import { tmpDir } from "../tmp-dir";
|
||||
import { getOnDiskWorkspaceFolders } from "../common/vscode/workspace-folders";
|
||||
import { Credentials } from "../common/authentication";
|
||||
import * as cli from "../codeql-cli/cli";
|
||||
import { CodeQLCliServer } from "../codeql-cli/cli";
|
||||
import { extLogger } from "../common/logging/vscode";
|
||||
import {
|
||||
getActionBranch,
|
||||
@@ -57,7 +57,7 @@ interface GeneratedQueryPack {
|
||||
* @returns the entire qlpack as a base64 string.
|
||||
*/
|
||||
async function generateQueryPack(
|
||||
cliServer: cli.CodeQLCliServer,
|
||||
cliServer: CodeQLCliServer,
|
||||
queryFile: string,
|
||||
queryPackDir: string,
|
||||
): Promise<GeneratedQueryPack> {
|
||||
@@ -169,7 +169,7 @@ async function createNewQueryPack(
|
||||
}
|
||||
|
||||
async function copyExistingQueryPack(
|
||||
cliServer: cli.CodeQLCliServer,
|
||||
cliServer: CodeQLCliServer,
|
||||
originalPackRoot: string,
|
||||
queryFile: string,
|
||||
queryPackDir: string,
|
||||
@@ -273,7 +273,7 @@ interface PreparedRemoteQuery {
|
||||
}
|
||||
|
||||
export async function prepareRemoteQueryRun(
|
||||
cliServer: cli.CodeQLCliServer,
|
||||
cliServer: CodeQLCliServer,
|
||||
credentials: Credentials,
|
||||
uri: Uri | undefined,
|
||||
progress: ProgressCallback,
|
||||
@@ -391,7 +391,7 @@ async function fixPackFile(
|
||||
}
|
||||
|
||||
async function injectExtensionPacks(
|
||||
cliServer: cli.CodeQLCliServer,
|
||||
cliServer: CodeQLCliServer,
|
||||
queryPackDir: string,
|
||||
workspaceFolders: string[],
|
||||
) {
|
||||
|
||||
@@ -1,21 +1,28 @@
|
||||
import * as sarif from "sarif";
|
||||
import {
|
||||
SarifLink,
|
||||
Log,
|
||||
PhysicalLocation,
|
||||
Region,
|
||||
ReportingDescriptor,
|
||||
Result,
|
||||
Run,
|
||||
} from "sarif";
|
||||
import {
|
||||
parseHighlightedLine,
|
||||
parseSarifPlainTextMessage,
|
||||
parseSarifRegion,
|
||||
SarifLink,
|
||||
} from "../common/sarif-utils";
|
||||
|
||||
import {
|
||||
AnalysisAlert,
|
||||
CodeFlow,
|
||||
AnalysisMessage,
|
||||
AnalysisMessageLocationTokenLocation,
|
||||
AnalysisMessageToken,
|
||||
ResultSeverity,
|
||||
ThreadFlow,
|
||||
CodeFlow,
|
||||
CodeSnippet,
|
||||
HighlightedRegion,
|
||||
AnalysisMessageLocationTokenLocation,
|
||||
ResultSeverity,
|
||||
ThreadFlow,
|
||||
} from "./shared/analysis-result";
|
||||
|
||||
// A line of more than 8k characters is probably generated.
|
||||
@@ -26,7 +33,7 @@ const CODE_SNIPPET_HIGHLIGHTED_REGION_MINIMUM_RATIO = 0.01;
|
||||
const defaultSeverity = "Warning";
|
||||
|
||||
export function extractAnalysisAlerts(
|
||||
sarifLog: sarif.Log,
|
||||
sarifLog: Log,
|
||||
fileLinkPrefix: string,
|
||||
): {
|
||||
alerts: AnalysisAlert[];
|
||||
@@ -50,8 +57,8 @@ export function extractAnalysisAlerts(
|
||||
}
|
||||
|
||||
function extractResultAlerts(
|
||||
run: sarif.Run,
|
||||
result: sarif.Result,
|
||||
run: Run,
|
||||
result: Result,
|
||||
fileLinkPrefix: string,
|
||||
): AnalysisAlert[] {
|
||||
const alerts: AnalysisAlert[] = [];
|
||||
@@ -93,7 +100,7 @@ function extractResultAlerts(
|
||||
}
|
||||
|
||||
function getShortDescription(
|
||||
rule: sarif.ReportingDescriptor | undefined,
|
||||
rule: ReportingDescriptor | undefined,
|
||||
message: AnalysisMessage,
|
||||
): string {
|
||||
if (rule?.shortDescription?.text) {
|
||||
@@ -104,9 +111,9 @@ function getShortDescription(
|
||||
}
|
||||
|
||||
export function tryGetSeverity(
|
||||
sarifRun: sarif.Run,
|
||||
result: sarif.Result,
|
||||
rule: sarif.ReportingDescriptor | undefined,
|
||||
sarifRun: Run,
|
||||
result: Result,
|
||||
rule: ReportingDescriptor | undefined,
|
||||
): ResultSeverity | undefined {
|
||||
if (!sarifRun || !result || !rule) {
|
||||
return undefined;
|
||||
@@ -130,9 +137,9 @@ export function tryGetSeverity(
|
||||
}
|
||||
|
||||
export function tryGetRule(
|
||||
sarifRun: sarif.Run,
|
||||
result: sarif.Result,
|
||||
): sarif.ReportingDescriptor | undefined {
|
||||
sarifRun: Run,
|
||||
result: Result,
|
||||
): ReportingDescriptor | undefined {
|
||||
if (!sarifRun || !result) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -171,7 +178,7 @@ export function tryGetRule(
|
||||
}
|
||||
|
||||
export function tryGetFilePath(
|
||||
physicalLocation: sarif.PhysicalLocation,
|
||||
physicalLocation: PhysicalLocation,
|
||||
): string | undefined {
|
||||
const filePath = physicalLocation.artifactLocation?.uri;
|
||||
// We expect the location uri value to be a relative file path, with no scheme.
|
||||
@@ -188,8 +195,8 @@ export function tryGetFilePath(
|
||||
}
|
||||
|
||||
function getCodeSnippet(
|
||||
contextRegion?: sarif.Region,
|
||||
region?: sarif.Region,
|
||||
contextRegion?: Region,
|
||||
region?: Region,
|
||||
): CodeSnippet | undefined {
|
||||
const actualRegion = contextRegion ?? region;
|
||||
|
||||
@@ -234,7 +241,7 @@ function getCodeSnippet(
|
||||
};
|
||||
}
|
||||
|
||||
function getHighlightedRegion(region: sarif.Region): HighlightedRegion {
|
||||
function getHighlightedRegion(region: Region): HighlightedRegion {
|
||||
const { startLine, startColumn, endLine, endColumn } =
|
||||
parseSarifRegion(region);
|
||||
|
||||
@@ -249,10 +256,7 @@ function getHighlightedRegion(region: sarif.Region): HighlightedRegion {
|
||||
};
|
||||
}
|
||||
|
||||
function getCodeFlows(
|
||||
result: sarif.Result,
|
||||
fileLinkPrefix: string,
|
||||
): CodeFlow[] {
|
||||
function getCodeFlows(result: Result, fileLinkPrefix: string): CodeFlow[] {
|
||||
const codeFlows = [];
|
||||
|
||||
if (result.codeFlows) {
|
||||
@@ -292,10 +296,7 @@ function getCodeFlows(
|
||||
return codeFlows;
|
||||
}
|
||||
|
||||
function getMessage(
|
||||
result: sarif.Result,
|
||||
fileLinkPrefix: string,
|
||||
): AnalysisMessage {
|
||||
function getMessage(result: Result, fileLinkPrefix: string): AnalysisMessage {
|
||||
const tokens: AnalysisMessageToken[] = [];
|
||||
|
||||
const messageText = result.message!.text!;
|
||||
@@ -323,7 +324,7 @@ function getMessage(
|
||||
|
||||
function getRelatedLocation(
|
||||
messagePart: SarifLink,
|
||||
result: sarif.Result,
|
||||
result: Result,
|
||||
fileLinkPrefix: string,
|
||||
): AnalysisMessageLocationTokenLocation | undefined {
|
||||
const relatedLocation = result.relatedLocations!.find(
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as sarif from "sarif";
|
||||
import { Result } from "sarif";
|
||||
import { AlertTable } from "../results/AlertTable";
|
||||
|
||||
type Props = {
|
||||
results: sarif.Result[];
|
||||
results: Result[];
|
||||
databaseUri: string;
|
||||
sourceLocationPrefix: string;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import * as Sarif from "sarif";
|
||||
import * as Keys from "./result-keys";
|
||||
import { Location, Result } from "sarif";
|
||||
import {
|
||||
getPath,
|
||||
getPathNode,
|
||||
getResult,
|
||||
keyToString,
|
||||
PathNode,
|
||||
Result as ResultKeysResult,
|
||||
ResultKey,
|
||||
} from "./result-keys";
|
||||
import { className, jumpToLocation } from "./result-table-utils";
|
||||
import { onNavigation } from "./ResultsApp";
|
||||
import { NavigateMsg, NavigationDirection } from "../../common/interface-types";
|
||||
import { parseSarifLocation, isNoLocation } from "../../common/sarif-utils";
|
||||
import { isNoLocation, parseSarifLocation } from "../../common/sarif-utils";
|
||||
import { sendTelemetry } from "../common/telemetry";
|
||||
import { AlertTableTruncatedMessage } from "./AlertTableTruncatedMessage";
|
||||
import { AlertTableResultRow } from "./AlertTableResultRow";
|
||||
@@ -11,7 +19,7 @@ import { ReactNode, useCallback, useEffect, useRef, useState } from "react";
|
||||
import { useScrollIntoView } from "./useScrollIntoView";
|
||||
|
||||
type Props = {
|
||||
results: Sarif.Result[];
|
||||
results: Result[];
|
||||
databaseUri: string;
|
||||
sourceLocationPrefix: string;
|
||||
numTruncatedResults?: number;
|
||||
@@ -29,7 +37,7 @@ export function AlertTable({
|
||||
noResults,
|
||||
}: Props) {
|
||||
const [expanded, setExpanded] = useState<Set<string>>(new Set<string>());
|
||||
const [selectedItem, setSelectedItem] = useState<Keys.ResultKey | undefined>(
|
||||
const [selectedItem, setSelectedItem] = useState<ResultKey | undefined>(
|
||||
undefined,
|
||||
);
|
||||
|
||||
@@ -41,8 +49,8 @@ export function AlertTable({
|
||||
* first item, open all the rest as well. This mimics vscode's file
|
||||
* explorer tree view behavior.
|
||||
*/
|
||||
const toggle = useCallback((e: React.MouseEvent, keys: Keys.ResultKey[]) => {
|
||||
const keyStrings = keys.map(Keys.keyToString);
|
||||
const toggle = useCallback((e: React.MouseEvent, keys: ResultKey[]) => {
|
||||
const keyStrings = keys.map(keyToString);
|
||||
setExpanded((previousExpanded) => {
|
||||
const expanded = new Set(previousExpanded);
|
||||
if (previousExpanded.has(keyStrings[0])) {
|
||||
@@ -62,9 +70,9 @@ export function AlertTable({
|
||||
}, []);
|
||||
|
||||
const getNewSelection = (
|
||||
key: Keys.ResultKey | undefined,
|
||||
key: ResultKey | undefined,
|
||||
direction: NavigationDirection,
|
||||
): Keys.ResultKey => {
|
||||
): ResultKey => {
|
||||
if (key === undefined) {
|
||||
return { resultIndex: 0 };
|
||||
}
|
||||
@@ -109,19 +117,19 @@ export function AlertTable({
|
||||
const key = getNewSelection(selectedItem, event.direction);
|
||||
|
||||
// Check if the selected node actually exists (bounds check) and get its location if relevant
|
||||
let jumpLocation: Sarif.Location | undefined;
|
||||
let jumpLocation: Location | undefined;
|
||||
if (key.pathNodeIndex !== undefined) {
|
||||
jumpLocation = Keys.getPathNode(results, key);
|
||||
jumpLocation = getPathNode(results, key);
|
||||
if (jumpLocation === undefined) {
|
||||
return; // Result does not exist
|
||||
}
|
||||
} else if (key.pathIndex !== undefined) {
|
||||
if (Keys.getPath(results, key) === undefined) {
|
||||
if (getPath(results, key) === undefined) {
|
||||
return; // Path does not exist
|
||||
}
|
||||
jumpLocation = undefined; // When selecting a 'path', don't jump anywhere.
|
||||
} else {
|
||||
jumpLocation = Keys.getResult(results, key)?.locations?.[0];
|
||||
jumpLocation = getResult(results, key)?.locations?.[0];
|
||||
if (jumpLocation === undefined) {
|
||||
return; // Path step does not exist.
|
||||
}
|
||||
@@ -139,10 +147,10 @@ export function AlertTable({
|
||||
const newExpanded = new Set(expanded);
|
||||
if (event.direction === NavigationDirection.right) {
|
||||
// When stepping right, expand to ensure the selected node is visible
|
||||
newExpanded.add(Keys.keyToString({ resultIndex: key.resultIndex }));
|
||||
newExpanded.add(keyToString({ resultIndex: key.resultIndex }));
|
||||
if (key.pathIndex !== undefined) {
|
||||
newExpanded.add(
|
||||
Keys.keyToString({
|
||||
keyToString({
|
||||
resultIndex: key.resultIndex,
|
||||
pathIndex: key.pathIndex,
|
||||
}),
|
||||
@@ -150,11 +158,11 @@ export function AlertTable({
|
||||
}
|
||||
} else if (event.direction === NavigationDirection.left) {
|
||||
// When stepping left, collapse immediately
|
||||
newExpanded.delete(Keys.keyToString(key));
|
||||
newExpanded.delete(keyToString(key));
|
||||
} else {
|
||||
// When stepping up or down, collapse the previous node
|
||||
if (selectedItem !== undefined) {
|
||||
newExpanded.delete(Keys.keyToString(selectedItem));
|
||||
newExpanded.delete(keyToString(selectedItem));
|
||||
}
|
||||
}
|
||||
setExpanded(newExpanded);
|
||||
@@ -171,7 +179,7 @@ export function AlertTable({
|
||||
}, [handleNavigationEvent]);
|
||||
|
||||
const updateSelectionCallback = useCallback(
|
||||
(resultKey: Keys.PathNode | Keys.Result | undefined) => {
|
||||
(resultKey: PathNode | ResultKeysResult | undefined) => {
|
||||
setSelectedItem(resultKey);
|
||||
sendTelemetry("local-results-alert-table-path-selected");
|
||||
},
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
import * as Sarif from "sarif";
|
||||
import * as Keys from "./result-keys";
|
||||
import { ThreadFlowLocation } from "sarif";
|
||||
import {
|
||||
equalsNotUndefined,
|
||||
PathNode,
|
||||
Result as ResultKeysResult,
|
||||
ResultKey,
|
||||
} from "./result-keys";
|
||||
import { SarifLocation } from "./locations/SarifLocation";
|
||||
import { selectableZebraStripe } from "./result-table-utils";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { VerticalRule } from "../common/VerticalRule";
|
||||
|
||||
interface Props {
|
||||
step: Sarif.ThreadFlowLocation;
|
||||
step: ThreadFlowLocation;
|
||||
pathNodeIndex: number;
|
||||
pathIndex: number;
|
||||
resultIndex: number;
|
||||
selectedItem: undefined | Keys.ResultKey;
|
||||
selectedItem: undefined | ResultKey;
|
||||
selectedItemRef: React.RefObject<any>;
|
||||
databaseUri: string;
|
||||
sourceLocationPrefix: string;
|
||||
updateSelectionCallback: (
|
||||
resultKey: Keys.PathNode | Keys.Result | undefined,
|
||||
resultKey: PathNode | ResultKeysResult | undefined,
|
||||
) => void;
|
||||
}
|
||||
|
||||
@@ -32,7 +37,7 @@ export function AlertTablePathNodeRow(props: Props) {
|
||||
updateSelectionCallback,
|
||||
} = props;
|
||||
|
||||
const pathNodeKey: Keys.PathNode = useMemo(
|
||||
const pathNodeKey: PathNode = useMemo(
|
||||
() => ({
|
||||
resultIndex,
|
||||
pathIndex,
|
||||
@@ -45,7 +50,7 @@ export function AlertTablePathNodeRow(props: Props) {
|
||||
[pathNodeKey, updateSelectionCallback],
|
||||
);
|
||||
|
||||
const isSelected = Keys.equalsNotUndefined(selectedItem, pathNodeKey);
|
||||
const isSelected = equalsNotUndefined(selectedItem, pathNodeKey);
|
||||
const stepIndex = pathNodeIndex + 1; // Convert to 1-based
|
||||
const zebraIndex = resultIndex + stepIndex;
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import * as Sarif from "sarif";
|
||||
import * as Keys from "./result-keys";
|
||||
import { ThreadFlow } from "sarif";
|
||||
import {
|
||||
equalsNotUndefined,
|
||||
PathNode,
|
||||
Result as ResultKeysResult,
|
||||
ResultKey,
|
||||
} from "./result-keys";
|
||||
import { selectableZebraStripe } from "./result-table-utils";
|
||||
import { AlertTablePathNodeRow } from "./AlertTablePathNodeRow";
|
||||
import { AlertTableDropdownIndicatorCell } from "./AlertTableDropdownIndicatorCell";
|
||||
@@ -7,18 +12,18 @@ import { useCallback, useMemo } from "react";
|
||||
import { VerticalRule } from "../common/VerticalRule";
|
||||
|
||||
interface Props {
|
||||
path: Sarif.ThreadFlow;
|
||||
path: ThreadFlow;
|
||||
pathIndex: number;
|
||||
resultIndex: number;
|
||||
currentPathExpanded: boolean;
|
||||
selectedItem: undefined | Keys.ResultKey;
|
||||
selectedItem: undefined | ResultKey;
|
||||
selectedItemRef: React.RefObject<any>;
|
||||
databaseUri: string;
|
||||
sourceLocationPrefix: string;
|
||||
updateSelectionCallback: (
|
||||
resultKey: Keys.PathNode | Keys.Result | undefined,
|
||||
resultKey: PathNode | ResultKeysResult | undefined,
|
||||
) => void;
|
||||
toggleExpanded: (e: React.MouseEvent, keys: Keys.ResultKey[]) => void;
|
||||
toggleExpanded: (e: React.MouseEvent, keys: ResultKey[]) => void;
|
||||
}
|
||||
|
||||
export function AlertTablePathRow(props: Props) {
|
||||
@@ -41,10 +46,7 @@ export function AlertTablePathRow(props: Props) {
|
||||
[pathKey, toggleExpanded],
|
||||
);
|
||||
|
||||
const isPathSpecificallySelected = Keys.equalsNotUndefined(
|
||||
pathKey,
|
||||
selectedItem,
|
||||
);
|
||||
const isPathSpecificallySelected = equalsNotUndefined(pathKey, selectedItem);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import * as Sarif from "sarif";
|
||||
import * as Keys from "./result-keys";
|
||||
import { Result } from "sarif";
|
||||
import {
|
||||
getAllPaths,
|
||||
keyToString,
|
||||
PathNode,
|
||||
Result as ResultKeysResult,
|
||||
ResultKey,
|
||||
} from "./result-keys";
|
||||
import { info, listUnordered } from "./octicons";
|
||||
import { selectableZebraStripe } from "./result-table-utils";
|
||||
import { AlertTableDropdownIndicatorCell } from "./AlertTableDropdownIndicatorCell";
|
||||
@@ -9,17 +15,17 @@ import { SarifMessageWithLocations } from "./locations/SarifMessageWithLocations
|
||||
import { AlertTablePathRow } from "./AlertTablePathRow";
|
||||
|
||||
interface Props {
|
||||
result: Sarif.Result;
|
||||
result: Result;
|
||||
resultIndex: number;
|
||||
expanded: Set<string>;
|
||||
selectedItem: undefined | Keys.ResultKey;
|
||||
selectedItem: undefined | ResultKey;
|
||||
selectedItemRef: React.RefObject<any>;
|
||||
databaseUri: string;
|
||||
sourceLocationPrefix: string;
|
||||
updateSelectionCallback: (
|
||||
resultKey: Keys.PathNode | Keys.Result | undefined,
|
||||
resultKey: PathNode | ResultKeysResult | undefined,
|
||||
) => void;
|
||||
toggleExpanded: (e: React.MouseEvent, keys: Keys.ResultKey[]) => void;
|
||||
toggleExpanded: (e: React.MouseEvent, keys: ResultKey[]) => void;
|
||||
}
|
||||
|
||||
export function AlertTableResultRow(props: Props) {
|
||||
@@ -35,7 +41,7 @@ export function AlertTableResultRow(props: Props) {
|
||||
toggleExpanded,
|
||||
} = props;
|
||||
|
||||
const resultKey: Keys.Result = useMemo(
|
||||
const resultKey: ResultKeysResult = useMemo(
|
||||
() => ({ resultIndex }),
|
||||
[resultIndex],
|
||||
);
|
||||
@@ -47,7 +53,7 @@ export function AlertTableResultRow(props: Props) {
|
||||
const handleDropdownClick = useCallback(
|
||||
(e: React.MouseEvent) => {
|
||||
const indices =
|
||||
Keys.getAllPaths(result).length === 1
|
||||
getAllPaths(result).length === 1
|
||||
? [resultKey, { ...resultKey, pathIndex: 0 }]
|
||||
: /* if there's exactly one path, auto-expand
|
||||
* the path when expanding the result */
|
||||
@@ -75,7 +81,7 @@ export function AlertTableResultRow(props: Props) {
|
||||
/>
|
||||
);
|
||||
|
||||
const currentResultExpanded = expanded.has(Keys.keyToString(resultKey));
|
||||
const currentResultExpanded = expanded.has(keyToString(resultKey));
|
||||
return (
|
||||
<>
|
||||
<tr
|
||||
@@ -110,14 +116,14 @@ export function AlertTableResultRow(props: Props) {
|
||||
</tr>
|
||||
{currentResultExpanded &&
|
||||
result.codeFlows &&
|
||||
Keys.getAllPaths(result).map((path, pathIndex) => (
|
||||
getAllPaths(result).map((path, pathIndex) => (
|
||||
<AlertTablePathRow
|
||||
key={`${resultIndex}-${pathIndex}`}
|
||||
{...props}
|
||||
path={path}
|
||||
pathIndex={pathIndex}
|
||||
currentPathExpanded={expanded.has(
|
||||
Keys.keyToString({ resultIndex, pathIndex }),
|
||||
keyToString({ resultIndex, pathIndex }),
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -5,12 +5,12 @@ import {
|
||||
IntoResultsViewMsg,
|
||||
SortDirection,
|
||||
} from "../../../common/interface-types";
|
||||
import * as fs from "fs-extra";
|
||||
import { readJSONSync } from "fs-extra";
|
||||
import { resolve } from "path";
|
||||
import { postMessage } from "../../common/post-message";
|
||||
import { ColumnKind } from "../../../common/raw-result-types";
|
||||
|
||||
const exampleSarif = fs.readJSONSync(
|
||||
const exampleSarif = readJSONSync(
|
||||
resolve(__dirname, "../../../../test/data/sarif/validSarif.sarif"),
|
||||
);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as Sarif from "sarif";
|
||||
import { Location as SarifLogLocation } from "sarif";
|
||||
import { parseSarifLocation } from "../../../common/sarif-utils";
|
||||
import { basename } from "../../../common/path";
|
||||
import { useMemo } from "react";
|
||||
@@ -6,7 +6,7 @@ import { Location } from "./Location";
|
||||
|
||||
interface Props {
|
||||
text?: string;
|
||||
loc?: Sarif.Location;
|
||||
loc?: SarifLogLocation;
|
||||
sourceLocationPrefix: string;
|
||||
databaseUri: string;
|
||||
onClick: () => void;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import * as Sarif from "sarif";
|
||||
import { Location as SarifLogLocation } from "sarif";
|
||||
import { parseSarifPlainTextMessage } from "../../../common/sarif-utils";
|
||||
import { SarifLocation } from "./SarifLocation";
|
||||
|
||||
interface Props {
|
||||
msg: string;
|
||||
relatedLocations: Sarif.Location[];
|
||||
relatedLocations: SarifLogLocation[];
|
||||
sourceLocationPrefix: string;
|
||||
databaseUri: string;
|
||||
onClick: () => void;
|
||||
@@ -20,7 +20,7 @@ export function SarifMessageWithLocations({
|
||||
databaseUri,
|
||||
onClick,
|
||||
}: Props) {
|
||||
const relatedLocationsById: Map<number, Sarif.Location> = new Map();
|
||||
const relatedLocationsById: Map<number, SarifLogLocation> = new Map();
|
||||
for (const loc of relatedLocations) {
|
||||
if (loc.id !== undefined) {
|
||||
relatedLocationsById.set(loc.id, loc);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as sarif from "sarif";
|
||||
import { Location, Result as SarifResult, ThreadFlow } from "sarif";
|
||||
|
||||
/**
|
||||
* Identifies a result, a path, or one of the nodes on a path.
|
||||
@@ -21,7 +21,7 @@ export interface Result extends ResultKeyBase {
|
||||
/**
|
||||
* Identifies one of the paths associated with a result.
|
||||
*/
|
||||
export interface Path extends ResultKeyBase {
|
||||
interface Path extends ResultKeyBase {
|
||||
pathIndex: number;
|
||||
pathNodeIndex?: undefined;
|
||||
}
|
||||
@@ -40,9 +40,9 @@ export type ResultKey = Result | Path | PathNode;
|
||||
* Looks up a specific result in a result set.
|
||||
*/
|
||||
export function getResult(
|
||||
results: sarif.Result[],
|
||||
results: SarifResult[],
|
||||
key: Result | Path | PathNode,
|
||||
): sarif.Result | undefined {
|
||||
): SarifResult | undefined {
|
||||
return results[key.resultIndex];
|
||||
}
|
||||
|
||||
@@ -50,9 +50,9 @@ export function getResult(
|
||||
* Looks up a specific path in a result set.
|
||||
*/
|
||||
export function getPath(
|
||||
results: sarif.Result[],
|
||||
results: SarifResult[],
|
||||
key: Path | PathNode,
|
||||
): sarif.ThreadFlow | undefined {
|
||||
): ThreadFlow | undefined {
|
||||
const result = getResult(results, key);
|
||||
if (result === undefined) {
|
||||
return undefined;
|
||||
@@ -76,9 +76,9 @@ export function getPath(
|
||||
* Looks up a specific path node in a result set.
|
||||
*/
|
||||
export function getPathNode(
|
||||
results: sarif.Result[],
|
||||
results: SarifResult[],
|
||||
key: PathNode,
|
||||
): sarif.Location | undefined {
|
||||
): Location | undefined {
|
||||
const path = getPath(results, key);
|
||||
if (path === undefined) {
|
||||
return undefined;
|
||||
@@ -108,7 +108,7 @@ export function equalsNotUndefined(
|
||||
*
|
||||
* Path nodes indices are relative to this flattened list.
|
||||
*/
|
||||
export function getAllPaths(result: sarif.Result): sarif.ThreadFlow[] {
|
||||
export function getAllPaths(result: SarifResult): ThreadFlow[] {
|
||||
if (result.codeFlows === undefined) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { readdirSync, readFileSync } from "fs-extra";
|
||||
import { join } from "path";
|
||||
import * as tmp from "tmp";
|
||||
import { DirResult, dirSync } from "tmp";
|
||||
import { BaseLogger, Logger, TeeLogger } from "../../../src/common/logging";
|
||||
import { OutputChannelLogger } from "../../../src/common/logging/vscode";
|
||||
|
||||
@@ -29,14 +29,14 @@ jest.mock(
|
||||
);
|
||||
|
||||
describe("OutputChannelLogger tests", function () {
|
||||
const tempFolders: Record<string, tmp.DirResult> = {};
|
||||
const tempFolders: Record<string, DirResult> = {};
|
||||
let logger: any;
|
||||
|
||||
beforeEach(async () => {
|
||||
tempFolders.globalStoragePath = tmp.dirSync({
|
||||
tempFolders.globalStoragePath = dirSync({
|
||||
prefix: "logging-tests-global",
|
||||
});
|
||||
tempFolders.storagePath = tmp.dirSync({
|
||||
tempFolders.storagePath = dirSync({
|
||||
prefix: "logging-tests-workspace",
|
||||
});
|
||||
logger = new OutputChannelLogger("test-logger");
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import * as Octokit from "@octokit/rest";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import { RequestInterface } from "@octokit/types/dist-types/RequestInterface";
|
||||
|
||||
import { Credentials } from "../../src/common/authentication";
|
||||
import { AppOctokit } from "../../src/common/octokit";
|
||||
|
||||
function makeTestOctokit(octokit: Octokit.Octokit): Credentials {
|
||||
function makeTestOctokit(octokit: Octokit): Credentials {
|
||||
return {
|
||||
getOctokit: async () => octokit,
|
||||
getAccessToken: async () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as vscode from "vscode";
|
||||
import { ExtensionContext, Memento, Uri } from "vscode";
|
||||
import { createMockMemento } from "../mock-memento";
|
||||
|
||||
/**
|
||||
@@ -12,13 +12,13 @@ export function createMockExtensionContext({
|
||||
extensionPath?: string;
|
||||
workspaceStoragePath?: string;
|
||||
globalStoragePath?: string;
|
||||
workspaceState?: vscode.Memento;
|
||||
}): vscode.ExtensionContext {
|
||||
workspaceState?: Memento;
|
||||
}): ExtensionContext {
|
||||
return {
|
||||
extensionPath,
|
||||
globalStorageUri: vscode.Uri.file(globalStoragePath),
|
||||
storageUri: vscode.Uri.file(workspaceStoragePath),
|
||||
globalStorageUri: Uri.file(globalStoragePath),
|
||||
storageUri: Uri.file(workspaceStoragePath),
|
||||
workspaceState: createMockMemento(),
|
||||
subscriptions: [],
|
||||
} as any as vscode.ExtensionContext;
|
||||
} as any as ExtensionContext;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as fetch from "node-fetch";
|
||||
import { Response } from "node-fetch";
|
||||
import { Range } from "semver";
|
||||
|
||||
import {
|
||||
@@ -73,10 +73,10 @@ describe("Releases API consumer", () => {
|
||||
];
|
||||
|
||||
class MockReleasesApiConsumer extends ReleasesApiConsumer {
|
||||
protected async makeApiCall(apiPath: string): Promise<fetch.Response> {
|
||||
protected async makeApiCall(apiPath: string): Promise<Response> {
|
||||
if (apiPath === `/repos/${repositoryNwo}/releases`) {
|
||||
return Promise.resolve(
|
||||
new fetch.Response(JSON.stringify(sampleReleaseResponse)),
|
||||
new Response(JSON.stringify(sampleReleaseResponse)),
|
||||
);
|
||||
}
|
||||
return Promise.reject(new Error(`Unknown API path: ${apiPath}`));
|
||||
@@ -181,7 +181,7 @@ describe("Releases API consumer", () => {
|
||||
];
|
||||
|
||||
class MockReleasesApiConsumer extends ReleasesApiConsumer {
|
||||
protected async makeApiCall(apiPath: string): Promise<fetch.Response> {
|
||||
protected async makeApiCall(apiPath: string): Promise<Response> {
|
||||
if (apiPath === `/repos/${repositoryNwo}/releases`) {
|
||||
const responseBody: GithubRelease[] = [
|
||||
{
|
||||
@@ -194,9 +194,7 @@ describe("Releases API consumer", () => {
|
||||
},
|
||||
];
|
||||
|
||||
return Promise.resolve(
|
||||
new fetch.Response(JSON.stringify(responseBody)),
|
||||
);
|
||||
return Promise.resolve(new Response(JSON.stringify(responseBody)));
|
||||
}
|
||||
return Promise.reject(new Error(`Unknown API path: ${apiPath}`));
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ import {
|
||||
readDirFullPaths,
|
||||
walkDirectory,
|
||||
} from "../../../src/common/files";
|
||||
import { DirResult } from "tmp";
|
||||
import * as tmp from "tmp";
|
||||
import { DirResult, dirSync } from "tmp";
|
||||
import { ensureDirSync, symlinkSync, writeFileSync } from "fs-extra";
|
||||
|
||||
describe("files", () => {
|
||||
@@ -360,7 +359,7 @@ describe("walkDirectory", () => {
|
||||
let dir2: string;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = tmp.dirSync({ unsafeCleanup: true });
|
||||
tmpDir = dirSync({ unsafeCleanup: true });
|
||||
dir = join(tmpDir.name, "dir");
|
||||
ensureDirSync(dir);
|
||||
dir2 = join(tmpDir.name, "dir2");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as Sarif from "sarif";
|
||||
import { Location } from "sarif";
|
||||
|
||||
import {
|
||||
getPathRelativeToSourceLocationPrefix,
|
||||
@@ -109,7 +109,7 @@ describe("parsing sarif", () => {
|
||||
});
|
||||
|
||||
it("should parse a sarif location with no region and no file protocol", () => {
|
||||
const location: Sarif.Location = {
|
||||
const location: Location = {
|
||||
physicalLocation: {
|
||||
artifactLocation: {
|
||||
uri: "abc?x=test",
|
||||
@@ -124,7 +124,7 @@ describe("parsing sarif", () => {
|
||||
});
|
||||
|
||||
it("should parse a sarif location with no region and file protocol", () => {
|
||||
const location: Sarif.Location = {
|
||||
const location: Location = {
|
||||
physicalLocation: {
|
||||
artifactLocation: {
|
||||
uri: "file:/abc%3Fx%3Dtest",
|
||||
@@ -139,7 +139,7 @@ describe("parsing sarif", () => {
|
||||
});
|
||||
|
||||
it("should parse a sarif location with a region and file protocol", () => {
|
||||
const location: Sarif.Location = {
|
||||
const location: Location = {
|
||||
physicalLocation: {
|
||||
artifactLocation: {
|
||||
uri: "file:abc%3Fx%3Dtest",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as tmp from "tmp";
|
||||
import { DirResult, dirSync } from "tmp";
|
||||
import { join } from "path";
|
||||
import { mkdirSync, writeFileSync } from "fs-extra";
|
||||
import {
|
||||
@@ -7,9 +7,9 @@ import {
|
||||
} from "../../../../src/databases/local-databases/db-contents-heuristics";
|
||||
|
||||
describe("isLikelyDatabaseRoot", () => {
|
||||
let dir: tmp.DirResult;
|
||||
let dir: DirResult;
|
||||
beforeEach(() => {
|
||||
dir = tmp.dirSync({
|
||||
dir = dirSync({
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
});
|
||||
@@ -54,9 +54,9 @@ describe("isLikelyDatabaseRoot", () => {
|
||||
});
|
||||
|
||||
describe("isLikelyDbLanguageFolder", () => {
|
||||
let dir: tmp.DirResult;
|
||||
let dir: DirResult;
|
||||
beforeEach(() => {
|
||||
dir = tmp.dirSync({
|
||||
dir = dirSync({
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as tmp from "tmp";
|
||||
import { DirResult, dirSync } from "tmp";
|
||||
import { dump } from "js-yaml";
|
||||
import { writeFileSync } from "fs-extra";
|
||||
import { join } from "path";
|
||||
@@ -6,11 +6,11 @@ import { QueryLanguage } from "../../../src/common/query-language";
|
||||
import { getInitialQueryContents } from "../../../src/local-queries/query-contents";
|
||||
|
||||
describe("getInitialQueryContents", () => {
|
||||
let dir: tmp.DirResult;
|
||||
let dir: DirResult;
|
||||
let language: QueryLanguage;
|
||||
|
||||
beforeEach(() => {
|
||||
dir = tmp.dirSync({
|
||||
dir = dirSync({
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
language = QueryLanguage.Cpp;
|
||||
|
||||
@@ -6,13 +6,13 @@ import {
|
||||
import { Mode } from "../../../src/model-editor/shared/mode";
|
||||
import { AutomodelMode } from "../../../src/model-editor/auto-model-api";
|
||||
import { AutoModelQueriesResult } from "../../../src/model-editor/auto-model-codeml-queries";
|
||||
import * as sarif from "sarif";
|
||||
import { Log } from "sarif";
|
||||
import { gzipDecode } from "../../../src/common/zlib";
|
||||
import { Method } from "../../../src/model-editor/method";
|
||||
import { ModeledMethod } from "../../../src/model-editor/modeled-method";
|
||||
|
||||
describe("createAutoModelRequest", () => {
|
||||
const createSarifLog = (queryId: string): sarif.Log => {
|
||||
const createSarifLog = (queryId: string): Log => {
|
||||
return {
|
||||
version: "2.1.0",
|
||||
$schema: "http://json.schemastore.org/sarif-2.1.0-rtm.4",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as sarif from "sarif";
|
||||
import { Log, PhysicalLocation, ReportingDescriptor, Result, Run } from "sarif";
|
||||
import {
|
||||
extractAnalysisAlerts,
|
||||
tryGetFilePath,
|
||||
@@ -17,11 +17,11 @@ describe("SARIF processing", () => {
|
||||
const result = {
|
||||
message: "msg",
|
||||
// Rule is missing here.
|
||||
} as sarif.Result;
|
||||
} as Result;
|
||||
|
||||
const sarifRun = {
|
||||
results: [result],
|
||||
} as sarif.Run;
|
||||
} as Run;
|
||||
|
||||
const rule = tryGetRule(sarifRun, result);
|
||||
|
||||
@@ -34,7 +34,7 @@ describe("SARIF processing", () => {
|
||||
rule: {
|
||||
id: "NonExistentRule",
|
||||
},
|
||||
} as sarif.Result;
|
||||
} as Result;
|
||||
|
||||
const sarifRun = {
|
||||
results: [result],
|
||||
@@ -51,7 +51,7 @@ describe("SARIF processing", () => {
|
||||
],
|
||||
},
|
||||
},
|
||||
} as sarif.Run;
|
||||
} as Run;
|
||||
|
||||
const rule = tryGetRule(sarifRun, result);
|
||||
|
||||
@@ -64,7 +64,7 @@ describe("SARIF processing", () => {
|
||||
rule: {
|
||||
id: "B",
|
||||
},
|
||||
} as sarif.Result;
|
||||
} as Result;
|
||||
|
||||
const sarifRun = {
|
||||
results: [result],
|
||||
@@ -78,7 +78,7 @@ describe("SARIF processing", () => {
|
||||
],
|
||||
},
|
||||
},
|
||||
} as sarif.Run;
|
||||
} as Run;
|
||||
|
||||
const rule = tryGetRule(sarifRun, result);
|
||||
|
||||
@@ -97,7 +97,7 @@ describe("SARIF processing", () => {
|
||||
index: 1,
|
||||
},
|
||||
},
|
||||
} as sarif.Result;
|
||||
} as Result;
|
||||
|
||||
const sarifRun = {
|
||||
results: [result],
|
||||
@@ -127,7 +127,7 @@ describe("SARIF processing", () => {
|
||||
},
|
||||
],
|
||||
},
|
||||
} as sarif.Run;
|
||||
} as Run;
|
||||
|
||||
const rule = tryGetRule(sarifRun, result);
|
||||
|
||||
@@ -143,7 +143,7 @@ describe("SARIF processing", () => {
|
||||
// The tool component index should be set here.
|
||||
},
|
||||
},
|
||||
} as sarif.Result;
|
||||
} as Result;
|
||||
|
||||
const sarifRun = {
|
||||
results: [result],
|
||||
@@ -173,7 +173,7 @@ describe("SARIF processing", () => {
|
||||
},
|
||||
],
|
||||
},
|
||||
} as sarif.Run;
|
||||
} as Run;
|
||||
|
||||
const rule = tryGetRule(sarifRun, result);
|
||||
|
||||
@@ -189,14 +189,14 @@ describe("SARIF processing", () => {
|
||||
index: 1,
|
||||
},
|
||||
},
|
||||
} as sarif.Result;
|
||||
} as Result;
|
||||
|
||||
const sarifRun = {
|
||||
results: [result],
|
||||
tool: {
|
||||
// Extensions should be set here.
|
||||
},
|
||||
} as sarif.Run;
|
||||
} as Run;
|
||||
|
||||
const rule = tryGetRule(sarifRun, result);
|
||||
|
||||
@@ -212,7 +212,7 @@ describe("SARIF processing", () => {
|
||||
index: 1,
|
||||
},
|
||||
},
|
||||
} as sarif.Result;
|
||||
} as Result;
|
||||
|
||||
const sarifRun = {
|
||||
results: [result],
|
||||
@@ -232,7 +232,7 @@ describe("SARIF processing", () => {
|
||||
// There should be one more extension here (index 1).
|
||||
],
|
||||
},
|
||||
} as sarif.Run;
|
||||
} as Run;
|
||||
|
||||
const rule = tryGetRule(sarifRun, result);
|
||||
|
||||
@@ -249,7 +249,7 @@ describe("SARIF processing", () => {
|
||||
index: 1,
|
||||
},
|
||||
},
|
||||
} as sarif.Result;
|
||||
} as Result;
|
||||
|
||||
const sarifRun = {
|
||||
results: [result],
|
||||
@@ -279,7 +279,7 @@ describe("SARIF processing", () => {
|
||||
},
|
||||
],
|
||||
},
|
||||
} as sarif.Run;
|
||||
} as Run;
|
||||
|
||||
const rule = tryGetRule(sarifRun, result);
|
||||
|
||||
@@ -291,7 +291,7 @@ describe("SARIF processing", () => {
|
||||
|
||||
describe("tryGetFilePath", () => {
|
||||
it("should return value when uri is a file path", () => {
|
||||
const physicalLocation: sarif.PhysicalLocation = {
|
||||
const physicalLocation: PhysicalLocation = {
|
||||
artifactLocation: {
|
||||
uri: "foo/bar",
|
||||
},
|
||||
@@ -300,7 +300,7 @@ describe("SARIF processing", () => {
|
||||
});
|
||||
|
||||
it("should return undefined when uri has a file scheme", () => {
|
||||
const physicalLocation: sarif.PhysicalLocation = {
|
||||
const physicalLocation: PhysicalLocation = {
|
||||
artifactLocation: {
|
||||
uri: "file:/",
|
||||
},
|
||||
@@ -309,7 +309,7 @@ describe("SARIF processing", () => {
|
||||
});
|
||||
|
||||
it("should return undefined when uri is empty", () => {
|
||||
const physicalLocation: sarif.PhysicalLocation = {
|
||||
const physicalLocation: PhysicalLocation = {
|
||||
artifactLocation: {
|
||||
uri: "",
|
||||
},
|
||||
@@ -318,7 +318,7 @@ describe("SARIF processing", () => {
|
||||
});
|
||||
|
||||
it("should return undefined if artifact location uri is undefined", () => {
|
||||
const physicalLocation: sarif.PhysicalLocation = {
|
||||
const physicalLocation: PhysicalLocation = {
|
||||
artifactLocation: {
|
||||
uri: undefined,
|
||||
},
|
||||
@@ -327,7 +327,7 @@ describe("SARIF processing", () => {
|
||||
});
|
||||
|
||||
it("should return undefined if artifact location is undefined", () => {
|
||||
const physicalLocation: sarif.PhysicalLocation = {
|
||||
const physicalLocation: PhysicalLocation = {
|
||||
artifactLocation: undefined,
|
||||
};
|
||||
expect(tryGetFilePath(physicalLocation)).toBe(undefined);
|
||||
@@ -338,14 +338,14 @@ describe("SARIF processing", () => {
|
||||
it("should return undefined if no rule set", () => {
|
||||
const result = {
|
||||
message: "msg",
|
||||
} as sarif.Result;
|
||||
} as Result;
|
||||
|
||||
// The rule should be set here.
|
||||
const rule: sarif.ReportingDescriptor | undefined = undefined;
|
||||
const rule: ReportingDescriptor | undefined = undefined;
|
||||
|
||||
const sarifRun = {
|
||||
results: [result],
|
||||
} as sarif.Run;
|
||||
} as Run;
|
||||
|
||||
const severity = tryGetSeverity(sarifRun, result, rule);
|
||||
expect(severity).toBeUndefined();
|
||||
@@ -357,14 +357,14 @@ describe("SARIF processing", () => {
|
||||
rule: {
|
||||
id: "A",
|
||||
},
|
||||
} as sarif.Result;
|
||||
} as Result;
|
||||
|
||||
const rule = {
|
||||
id: "A",
|
||||
properties: {
|
||||
// Severity not set
|
||||
},
|
||||
} as sarif.ReportingDescriptor;
|
||||
} as ReportingDescriptor;
|
||||
|
||||
const sarifRun = {
|
||||
results: [result],
|
||||
@@ -373,7 +373,7 @@ describe("SARIF processing", () => {
|
||||
rules: [rule, result.rule],
|
||||
},
|
||||
},
|
||||
} as sarif.Run;
|
||||
} as Run;
|
||||
|
||||
const severity = tryGetSeverity(sarifRun, result, rule);
|
||||
expect(severity).toBeUndefined();
|
||||
@@ -392,14 +392,14 @@ describe("SARIF processing", () => {
|
||||
rule: {
|
||||
id: "A",
|
||||
},
|
||||
} as sarif.Result;
|
||||
} as Result;
|
||||
|
||||
const rule = {
|
||||
id: "A",
|
||||
properties: {
|
||||
"problem.severity": sarifSeverity,
|
||||
},
|
||||
} as sarif.ReportingDescriptor;
|
||||
} as ReportingDescriptor;
|
||||
|
||||
const sarifRun = {
|
||||
results: [result],
|
||||
@@ -408,7 +408,7 @@ describe("SARIF processing", () => {
|
||||
rules: [rule, result.rule],
|
||||
},
|
||||
},
|
||||
} as sarif.Run;
|
||||
} as Run;
|
||||
|
||||
const severity = tryGetSeverity(sarifRun, result, rule);
|
||||
expect(severity).toBe(parsedSeverity);
|
||||
@@ -421,7 +421,7 @@ describe("SARIF processing", () => {
|
||||
it("should not return any results if no runs found in the SARIF", () => {
|
||||
const sarif = {
|
||||
// Runs are missing here.
|
||||
} as sarif.Log;
|
||||
} as Log;
|
||||
|
||||
const result = extractAnalysisAlerts(sarif, fakefileLinkPrefix);
|
||||
|
||||
@@ -439,7 +439,7 @@ describe("SARIF processing", () => {
|
||||
// Results are missing here.
|
||||
},
|
||||
],
|
||||
} as sarif.Log;
|
||||
} as Log;
|
||||
|
||||
const result = extractAnalysisAlerts(sarif, fakefileLinkPrefix);
|
||||
|
||||
@@ -524,7 +524,7 @@ describe("SARIF processing", () => {
|
||||
|
||||
it("should return results for all alerts", () => {
|
||||
const sarif = {
|
||||
version: "0.0.1" as sarif.Log.version,
|
||||
version: "0.0.1" as Log.version,
|
||||
runs: [
|
||||
{
|
||||
results: [
|
||||
@@ -602,7 +602,7 @@ describe("SARIF processing", () => {
|
||||
],
|
||||
},
|
||||
],
|
||||
} as sarif.Log;
|
||||
} as Log;
|
||||
|
||||
const result = extractAnalysisAlerts(sarif, fakefileLinkPrefix);
|
||||
expect(result).toBeTruthy();
|
||||
@@ -770,7 +770,7 @@ describe("SARIF processing", () => {
|
||||
expect(array).toEqual([]);
|
||||
}
|
||||
|
||||
function buildValidSarifLog(): sarif.Log {
|
||||
function buildValidSarifLog(): Log {
|
||||
return {
|
||||
version: "2.1.0",
|
||||
runs: [
|
||||
@@ -805,7 +805,7 @@ describe("SARIF processing", () => {
|
||||
],
|
||||
},
|
||||
],
|
||||
} as sarif.Log;
|
||||
} as Log;
|
||||
}
|
||||
|
||||
function getMessageText(message: AnalysisMessage) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { window } from "vscode";
|
||||
|
||||
import { readJson } from "fs-extra";
|
||||
import * as path from "path";
|
||||
import { join } from "path";
|
||||
import {
|
||||
DbConfig,
|
||||
SelectedDbItemKind,
|
||||
@@ -32,10 +32,7 @@ describe("Db panel UI commands", () => {
|
||||
storagePath =
|
||||
extension.ctx.storageUri?.fsPath || extension.ctx.globalStorageUri.fsPath;
|
||||
|
||||
dbConfigFilePath = path.join(
|
||||
storagePath,
|
||||
DbConfigStore.databaseConfigFileName,
|
||||
);
|
||||
dbConfigFilePath = join(storagePath, DbConfigStore.databaseConfigFileName);
|
||||
});
|
||||
|
||||
it("should add new remote db list", async () => {
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
SkeletonQueryWizard,
|
||||
} from "../../../../src/local-queries/skeleton-query-wizard";
|
||||
import { mockedObject, mockedQuickPickItem } from "../../utils/mocking.helpers";
|
||||
import * as tmp from "tmp";
|
||||
import { DirResult, dirSync } from "tmp";
|
||||
import {
|
||||
MessageItem,
|
||||
TextDocument,
|
||||
@@ -48,7 +48,7 @@ describe("SkeletonQueryWizard", () => {
|
||||
let mockApp: App;
|
||||
let wizard: SkeletonQueryWizard;
|
||||
let mockDatabaseManager: DatabaseManager;
|
||||
let dir: tmp.DirResult;
|
||||
let dir: DirResult;
|
||||
let storagePath: string;
|
||||
let quickPickSpy: jest.SpiedFunction<typeof window.showQuickPick>;
|
||||
let showInputBoxSpy: jest.SpiedFunction<typeof window.showInputBox>;
|
||||
@@ -104,7 +104,7 @@ describe("SkeletonQueryWizard", () => {
|
||||
databaseItems: [] as DatabaseItem[],
|
||||
});
|
||||
|
||||
dir = tmp.dirSync({
|
||||
dir = dirSync({
|
||||
prefix: "skeleton_query_wizard_",
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
@@ -699,10 +699,10 @@ describe("SkeletonQueryWizard", () => {
|
||||
});
|
||||
|
||||
describe("with folders and files", () => {
|
||||
let queriesDir: tmp.DirResult;
|
||||
let queriesDir: DirResult;
|
||||
|
||||
beforeEach(async () => {
|
||||
queriesDir = tmp.dirSync({
|
||||
queriesDir = dirSync({
|
||||
prefix: "queries_",
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import { join, basename } from "path";
|
||||
import { dirSync } from "tmp";
|
||||
import { CancellationTokenSource } from "vscode-jsonrpc";
|
||||
import * as messages from "../../../../src/query-server/messages";
|
||||
import * as qsClient from "../../../../src/query-server/query-server-client";
|
||||
import * as cli from "../../../../src/codeql-cli/cli";
|
||||
import {
|
||||
QueryResultType,
|
||||
registerDatabases,
|
||||
runQuery,
|
||||
RunQueryParams,
|
||||
} from "../../../../src/query-server/messages";
|
||||
import { CodeQLCliServer } from "../../../../src/codeql-cli/cli";
|
||||
import { BqrsCellValue } from "../../../../src/common/bqrs-cli-types";
|
||||
import { describeWithCodeQL } from "../../cli";
|
||||
import { QueryServerClient } from "../../../../src/query-server/query-server-client";
|
||||
@@ -11,7 +15,6 @@ import {
|
||||
extLogger,
|
||||
ProgressReporter,
|
||||
} from "../../../../src/common/logging/vscode";
|
||||
import { QueryResultType } from "../../../../src/query-server/messages";
|
||||
import { ensureTestDatabase, getActivatedExtension } from "../../global.helper";
|
||||
import { createMockApp } from "../../../__mocks__/appMock";
|
||||
|
||||
@@ -101,8 +104,8 @@ const nullProgressReporter: ProgressReporter = {
|
||||
};
|
||||
|
||||
describeWithCodeQL()("using the query server", () => {
|
||||
let qs: qsClient.QueryServerClient;
|
||||
let cliServer: cli.CodeQLCliServer;
|
||||
let qs: QueryServerClient;
|
||||
let cliServer: CodeQLCliServer;
|
||||
let db: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
@@ -146,12 +149,12 @@ describeWithCodeQL()("using the query server", () => {
|
||||
const parsedResults = new Checkpoint<void>();
|
||||
|
||||
it("should register the database", async () => {
|
||||
await qs.sendRequest(messages.registerDatabases, { databases: [db] });
|
||||
await qs.sendRequest(registerDatabases, { databases: [db] });
|
||||
});
|
||||
|
||||
it(`should be able to run query ${queryName}`, async () => {
|
||||
try {
|
||||
const params: messages.RunQueryParams = {
|
||||
const params: RunQueryParams = {
|
||||
db,
|
||||
queryPath: queryTestCase.queryPath,
|
||||
outputPath: RESULTS_PATH,
|
||||
@@ -160,14 +163,9 @@ describeWithCodeQL()("using the query server", () => {
|
||||
singletonExternalInputs: {},
|
||||
target: { query: {} },
|
||||
};
|
||||
const result = await qs.sendRequest(
|
||||
messages.runQuery,
|
||||
params,
|
||||
token,
|
||||
() => {
|
||||
/**/
|
||||
},
|
||||
);
|
||||
const result = await qs.sendRequest(runQuery, params, token, () => {
|
||||
/**/
|
||||
});
|
||||
expect(result.resultType).toBe(QueryResultType.SUCCESS);
|
||||
await evaluationSucceeded.resolve();
|
||||
} catch (e) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { env } from "vscode";
|
||||
import { beforeEachAction as testConfigBeforeEachAction } from "./test-config";
|
||||
import * as tmp from "tmp";
|
||||
import { DirResult, dirSync } from "tmp";
|
||||
import { realpathSync } from "fs-extra";
|
||||
import {
|
||||
getActivatedExtension,
|
||||
@@ -15,11 +15,11 @@ if (process.env.CI) {
|
||||
}
|
||||
|
||||
// create an extension storage location
|
||||
let removeStorage: tmp.DirResult["removeCallback"] | undefined;
|
||||
let removeStorage: DirResult["removeCallback"] | undefined;
|
||||
|
||||
export async function beforeAllAction() {
|
||||
// Create the temp directory to be used as extension local storage.
|
||||
const dir = tmp.dirSync({
|
||||
const dir = dirSync({
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
let storagePath = realpathSync(dir.name);
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
import { FilePathDiscovery } from "../../../../../src/common/vscode/file-path-discovery";
|
||||
import { basename, dirname, join } from "path";
|
||||
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
||||
import * as tmp from "tmp";
|
||||
import { dirSync } from "tmp";
|
||||
import { normalizePath } from "../../../../../src/common/files";
|
||||
import { extLogger } from "../../../../../src/common/logging/vscode/loggers";
|
||||
import { getErrorMessage } from "../../../../../src/common/helpers-pure";
|
||||
@@ -83,7 +83,7 @@ describe("FilePathDiscovery", () => {
|
||||
let discovery: TestFilePathDiscovery;
|
||||
|
||||
beforeEach(() => {
|
||||
const t = tmp.dirSync({
|
||||
const t = dirSync({
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
tmpDir = normalizePath(t.name);
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import { resolve, join } from "path";
|
||||
import * as vscode from "vscode";
|
||||
import { Uri } from "vscode";
|
||||
import { join, resolve } from "path";
|
||||
import { TextDocument, Uri, window, workspace } from "vscode";
|
||||
import {
|
||||
getQuickEvalContext,
|
||||
validateQueryUri,
|
||||
} from "../../../../src/run-queries-shared";
|
||||
|
||||
async function showQlDocument(name: string): Promise<vscode.TextDocument> {
|
||||
const folderPath = vscode.workspace.workspaceFolders![0].uri.fsPath;
|
||||
async function showQlDocument(name: string): Promise<TextDocument> {
|
||||
const folderPath = workspace.workspaceFolders![0].uri.fsPath;
|
||||
const documentPath = resolve(folderPath, name);
|
||||
const document = await vscode.workspace.openTextDocument(documentPath);
|
||||
await vscode.window.showTextDocument(document!);
|
||||
const document = await workspace.openTextDocument(documentPath);
|
||||
await window.showTextDocument(document!);
|
||||
return document;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as tmp from "tmp";
|
||||
import { DirResult, dirSync } from "tmp";
|
||||
import { ensureDir, ensureFile, pathExists, writeFile } from "fs-extra";
|
||||
import { join } from "path";
|
||||
import { ExtensionContext, Uri, workspace } from "vscode";
|
||||
@@ -48,11 +48,11 @@ describe("local databases", () => {
|
||||
typeof dialog.showNeverAskAgainDialog
|
||||
>;
|
||||
|
||||
let dir: tmp.DirResult;
|
||||
let dir: DirResult;
|
||||
let extensionContextStoragePath: string;
|
||||
|
||||
beforeEach(() => {
|
||||
dir = tmp.dirSync({
|
||||
dir = dirSync({
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { QueryLanguage } from "../../../src/common/query-language";
|
||||
import { CodeQLCliServer } from "../../../src/codeql-cli/cli";
|
||||
import { Uri, workspace } from "vscode";
|
||||
import { getErrorMessage } from "../../../src/common/helpers-pure";
|
||||
import * as tmp from "tmp";
|
||||
import { DirResult, dirSync } from "tmp";
|
||||
import { mockedObject } from "../utils/mocking.helpers";
|
||||
import { ensureDir, readFile } from "fs-extra";
|
||||
import { load } from "js-yaml";
|
||||
@@ -22,10 +22,10 @@ describe("QlPackGenerator", () => {
|
||||
typeof CodeQLCliServer.prototype.resolveQlpacks
|
||||
>;
|
||||
let mockCli: CodeQLCliServer;
|
||||
let dir: tmp.DirResult;
|
||||
let dir: DirResult;
|
||||
|
||||
beforeEach(async () => {
|
||||
dir = tmp.dirSync({
|
||||
dir = dirSync({
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
} from "../../../../src/queries-panel/query-discovery";
|
||||
import { createMockApp } from "../../../__mocks__/appMock";
|
||||
import { basename, dirname, join } from "path";
|
||||
import * as tmp from "tmp";
|
||||
import { dirSync } from "tmp";
|
||||
import {
|
||||
FileTreeDirectory,
|
||||
FileTreeLeaf,
|
||||
@@ -31,7 +31,7 @@ describe("Query pack discovery", () => {
|
||||
let discovery: QueryDiscovery;
|
||||
|
||||
beforeEach(() => {
|
||||
const t = tmp.dirSync({
|
||||
const t = dirSync({
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
tmpDir = t.name;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Uri, workspace } from "vscode";
|
||||
import { QueryPackDiscovery } from "../../../../src/queries-panel/query-pack-discovery";
|
||||
import * as tmp from "tmp";
|
||||
import { dirSync } from "tmp";
|
||||
import { dirname, join } from "path";
|
||||
import { ensureDir, writeJSON } from "fs-extra";
|
||||
import { QueryLanguage } from "../../../../src/common/query-language";
|
||||
@@ -14,7 +14,7 @@ describe("Query pack discovery", () => {
|
||||
let discovery: QueryPackDiscovery;
|
||||
|
||||
beforeEach(() => {
|
||||
const t = tmp.dirSync({
|
||||
const t = dirSync({
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
tmpDir = t.name;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Uri, WorkspaceFolder } from "vscode";
|
||||
import * as fs from "fs-extra";
|
||||
import { remove } from "fs-extra";
|
||||
import { join } from "path";
|
||||
|
||||
import { QLTestDiscovery } from "../../../../src/query-testing/qltest-discovery";
|
||||
import { DirectoryResult } from "tmp-promise";
|
||||
import * as tmp from "tmp-promise";
|
||||
import { DirectoryResult, dir } from "tmp-promise";
|
||||
|
||||
import "../../../matchers/toEqualPath";
|
||||
import { mockedObject } from "../../utils/mocking.helpers";
|
||||
@@ -22,7 +21,7 @@ describe("qltest-discovery", () => {
|
||||
let qlTestDiscover: QLTestDiscovery;
|
||||
|
||||
beforeEach(async () => {
|
||||
directory = await tmp.dir({
|
||||
directory = await dir({
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
|
||||
@@ -83,7 +82,7 @@ describe("qltest-discovery", () => {
|
||||
});
|
||||
|
||||
it("should avoid discovery if a folder does not exist", async () => {
|
||||
await fs.remove(baseDir);
|
||||
await remove(baseDir);
|
||||
|
||||
await qlTestDiscover.refresh();
|
||||
const testDirectory = qlTestDiscover.testDirectory;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Uri, window, workspace, WorkspaceFolder } from "vscode";
|
||||
import * as tmp from "tmp";
|
||||
import { DirResult, dirSync } from "tmp";
|
||||
import { join } from "path";
|
||||
import { mkdir, writeFile } from "fs-extra";
|
||||
|
||||
@@ -8,13 +8,13 @@ import { Setting } from "../../../../src/config";
|
||||
import { createMockCommandManager } from "../../../__mocks__/commandsMock";
|
||||
|
||||
describe("prepareCodeTour", () => {
|
||||
let dir: tmp.DirResult;
|
||||
let dir: DirResult;
|
||||
let showInformationMessageSpy: jest.SpiedFunction<
|
||||
typeof window.showInformationMessage
|
||||
>;
|
||||
|
||||
beforeEach(() => {
|
||||
dir = tmp.dirSync({
|
||||
dir = dirSync({
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import * as log from "../../../../src/common/logging/notifications";
|
||||
import { extLogger } from "../../../../src/common/logging/vscode";
|
||||
import * as fs from "fs-extra";
|
||||
import * as path from "path";
|
||||
import { writeFile } from "fs-extra";
|
||||
import { join } from "path";
|
||||
import * as os from "os";
|
||||
import * as tmp from "tmp-promise";
|
||||
import { DirectoryResult } from "tmp-promise";
|
||||
import { dir, DirectoryResult } from "tmp-promise";
|
||||
import {
|
||||
DistributionManager,
|
||||
getExecutableFromDirectory,
|
||||
@@ -45,12 +44,12 @@ describe("Launcher path", () => {
|
||||
|
||||
mockedOS.platform.mockReturnValue("win32");
|
||||
|
||||
directory = await tmp.dir({
|
||||
directory = await dir({
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
|
||||
pathToCmd = path.join(directory.path, "codeql.cmd");
|
||||
pathToExe = path.join(directory.path, "codeql.exe");
|
||||
pathToCmd = join(directory.path, "codeql.cmd");
|
||||
pathToExe = join(directory.path, "codeql.exe");
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
@@ -58,7 +57,7 @@ describe("Launcher path", () => {
|
||||
});
|
||||
|
||||
it("should not warn with proper launcher name", async () => {
|
||||
await fs.writeFile(pathToExe, "");
|
||||
await writeFile(pathToExe, "");
|
||||
|
||||
const result = await getExecutableFromDirectory(directory.path);
|
||||
|
||||
@@ -70,7 +69,7 @@ describe("Launcher path", () => {
|
||||
});
|
||||
|
||||
it("should warn when using a hard-coded deprecated launcher name", async () => {
|
||||
await fs.writeFile(pathToCmd, "");
|
||||
await writeFile(pathToCmd, "");
|
||||
|
||||
const result = await getExecutableFromDirectory(directory.path);
|
||||
|
||||
@@ -102,7 +101,7 @@ describe("Launcher path", () => {
|
||||
});
|
||||
|
||||
it("should not warn when deprecated launcher is used, but no new launcher is available", async function () {
|
||||
await fs.writeFile(pathToCmd, "");
|
||||
await writeFile(pathToCmd, "");
|
||||
|
||||
const manager = new DistributionManager(
|
||||
{ customCodeQlPath: pathToCmd } as any,
|
||||
@@ -119,8 +118,8 @@ describe("Launcher path", () => {
|
||||
});
|
||||
|
||||
it("should warn when deprecated launcher is used, and new launcher is available", async () => {
|
||||
await fs.writeFile(pathToCmd, "");
|
||||
await fs.writeFile(pathToExe, "");
|
||||
await writeFile(pathToCmd, "");
|
||||
await writeFile(pathToExe, "");
|
||||
|
||||
const manager = new DistributionManager(
|
||||
{ customCodeQlPath: pathToCmd } as any,
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
import * as vscode from "vscode";
|
||||
import { TextEditor, Uri, window } from "vscode";
|
||||
import { tryOpenExternalFile } from "../../../../../src/common/vscode/external-files";
|
||||
import { createMockCommandManager } from "../../../../__mocks__/commandsMock";
|
||||
import { mockedObject } from "../../../utils/mocking.helpers";
|
||||
|
||||
describe("tryOpenExternalFile", () => {
|
||||
let showTextDocumentSpy: jest.SpiedFunction<
|
||||
typeof vscode.window.showTextDocument
|
||||
>;
|
||||
let showTextDocumentSpy: jest.SpiedFunction<typeof window.showTextDocument>;
|
||||
let showInformationMessageSpy: jest.SpiedFunction<
|
||||
typeof vscode.window.showInformationMessage
|
||||
typeof window.showInformationMessage
|
||||
>;
|
||||
|
||||
beforeEach(() => {
|
||||
showTextDocumentSpy = jest
|
||||
.spyOn(vscode.window, "showTextDocument")
|
||||
.mockResolvedValue(mockedObject<vscode.TextEditor>({}));
|
||||
.spyOn(window, "showTextDocument")
|
||||
.mockResolvedValue(mockedObject<TextEditor>({}));
|
||||
showInformationMessageSpy = jest
|
||||
.spyOn(vscode.window, "showInformationMessage")
|
||||
.spyOn(window, "showInformationMessage")
|
||||
.mockResolvedValue(undefined);
|
||||
});
|
||||
|
||||
@@ -27,7 +25,7 @@ describe("tryOpenExternalFile", () => {
|
||||
await tryOpenExternalFile(commandManager, "xxx");
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledWith(
|
||||
vscode.Uri.file("xxx"),
|
||||
Uri.file("xxx"),
|
||||
expect.anything(),
|
||||
);
|
||||
expect(executeCommand).not.toBeCalled();
|
||||
@@ -45,7 +43,7 @@ describe("tryOpenExternalFile", () => {
|
||||
showInformationMessageSpy.mockResolvedValue({ title: "Yes" });
|
||||
|
||||
await tryOpenExternalFile(commandManager, "xxx");
|
||||
const uri = vscode.Uri.file("xxx");
|
||||
const uri = Uri.file("xxx");
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledWith(uri, expect.anything());
|
||||
expect(executeCommand).toHaveBeenCalledWith("revealFileInOS", uri);
|
||||
@@ -59,7 +57,7 @@ describe("tryOpenExternalFile", () => {
|
||||
showInformationMessageSpy.mockResolvedValue({ title: "No" });
|
||||
|
||||
await tryOpenExternalFile(commandManager, "xxx");
|
||||
const uri = vscode.Uri.file("xxx");
|
||||
const uri = Uri.file("xxx");
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledWith(uri, expect.anything());
|
||||
expect(showInformationMessageSpy).toBeCalled();
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { join } from "path";
|
||||
import { createFileSync, mkdirSync } from "fs-extra";
|
||||
import * as tmp from "tmp";
|
||||
import { DirResult, dirSync } from "tmp";
|
||||
import { window } from "vscode";
|
||||
|
||||
import {
|
||||
convertGithubNwoToDatabaseUrl,
|
||||
findDirWithFile,
|
||||
} from "../../../../src/databases/database-fetcher";
|
||||
import * as Octokit from "@octokit/rest";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import {
|
||||
mockedObject,
|
||||
mockedOctokitFunction,
|
||||
@@ -26,7 +26,7 @@ describe("database-fetcher", () => {
|
||||
"codeScanning",
|
||||
"listCodeqlDatabases"
|
||||
>();
|
||||
const octokit = mockedObject<Octokit.Octokit>({
|
||||
const octokit = mockedObject<Octokit>({
|
||||
rest: {
|
||||
codeScanning: {
|
||||
listCodeqlDatabases: mockListCodeqlDatabases,
|
||||
@@ -202,9 +202,9 @@ describe("database-fetcher", () => {
|
||||
});
|
||||
|
||||
describe("findDirWithFile", () => {
|
||||
let dir: tmp.DirResult;
|
||||
let dir: DirResult;
|
||||
beforeEach(() => {
|
||||
dir = tmp.dirSync({ unsafeCleanup: true });
|
||||
dir = dirSync({ unsafeCleanup: true });
|
||||
createFile("a");
|
||||
createFile("b");
|
||||
createFile("c");
|
||||
|
||||
@@ -6,7 +6,7 @@ import { GitHubDatabaseConfig } from "../../../../../src/config";
|
||||
import * as dialog from "../../../../../src/common/vscode/dialog";
|
||||
import { listDatabases } from "../../../../../src/databases/github-databases/api";
|
||||
import { Credentials } from "../../../../../src/common/authentication";
|
||||
import * as Octokit from "@octokit/rest";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import { AppOctokit } from "../../../../../src/common/octokit";
|
||||
import { RequestError } from "@octokit/request-error";
|
||||
|
||||
@@ -18,7 +18,7 @@ const appMockListCodeqlDatabases = mockedOctokitFunction<
|
||||
"codeScanning",
|
||||
"listCodeqlDatabases"
|
||||
>();
|
||||
const appOctokit = mockedObject<Octokit.Octokit>({
|
||||
const appOctokit = mockedObject<Octokit>({
|
||||
rest: {
|
||||
codeScanning: {
|
||||
listCodeqlDatabases: appMockListCodeqlDatabases,
|
||||
@@ -41,7 +41,7 @@ describe("listDatabases", () => {
|
||||
"codeScanning",
|
||||
"listCodeqlDatabases"
|
||||
>();
|
||||
const octokit = mockedObject<Octokit.Octokit>({
|
||||
const octokit = mockedObject<Octokit>({
|
||||
rest: {
|
||||
codeScanning: {
|
||||
listCodeqlDatabases: mockListCodeqlDatabases,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { load } from "js-yaml";
|
||||
import * as fs from "fs-extra";
|
||||
import { readFile } from "fs-extra";
|
||||
|
||||
import { getErrorMessage } from "../../../../../src/common/helpers-pure";
|
||||
|
||||
@@ -109,7 +109,7 @@ describe("queryResolver", () => {
|
||||
|
||||
const fileName = resolveQueriesInSuite.mock.calls[0][0];
|
||||
|
||||
expect(load(await fs.readFile(fileName, "utf-8"))).toEqual([
|
||||
expect(load(await readFile(fileName, "utf-8"))).toEqual([
|
||||
{
|
||||
from: "my-qlpack",
|
||||
queries: ".",
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as qlpack from "../../../../src/databases/qlpack";
|
||||
import * as workspaceFolders from "../../../../src/common/vscode/workspace-folders";
|
||||
import * as log from "../../../../src/common/logging/notifications";
|
||||
import { load } from "js-yaml";
|
||||
import * as fs from "fs-extra";
|
||||
import { readFile } from "fs-extra";
|
||||
|
||||
describe("qlpackOfDatabase", () => {
|
||||
let getQlPackForDbschemeSpy: jest.SpiedFunction<
|
||||
@@ -87,7 +87,7 @@ describe("resolveQueries", () => {
|
||||
|
||||
const fileName = resolveQueriesInSuite.mock.calls[0][0];
|
||||
|
||||
expect(load(await fs.readFile(fileName, "utf-8"))).toEqual([
|
||||
expect(load(await readFile(fileName, "utf-8"))).toEqual([
|
||||
{
|
||||
from: "my-qlpack",
|
||||
queries: ".",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { join } from "path";
|
||||
import * as vscode from "vscode";
|
||||
import {
|
||||
ExtensionContext,
|
||||
ThemeColor,
|
||||
ThemeIcon,
|
||||
Uri,
|
||||
workspace,
|
||||
} from "vscode";
|
||||
|
||||
import { extLogger } from "../../../../src/common/logging/vscode";
|
||||
import { QueryHistoryConfigListener } from "../../../../src/config";
|
||||
@@ -165,7 +171,7 @@ describe("HistoryTreeDataProvider", () => {
|
||||
});
|
||||
expect(treeItem.label).toContain("query-file.ql");
|
||||
expect(treeItem.contextValue).toBe("rawResultsItem");
|
||||
expect(treeItem.iconPath).toEqual(new vscode.ThemeIcon("database"));
|
||||
expect(treeItem.iconPath).toEqual(new ThemeIcon("database"));
|
||||
});
|
||||
|
||||
it("should get a tree item with interpreted results", async () => {
|
||||
@@ -181,7 +187,7 @@ describe("HistoryTreeDataProvider", () => {
|
||||
mockQueryWithInterpretedResults,
|
||||
);
|
||||
expect(treeItem.contextValue).toBe("interpretedResultsItem");
|
||||
expect(treeItem.iconPath).toEqual(new vscode.ThemeIcon("database"));
|
||||
expect(treeItem.iconPath).toEqual(new ThemeIcon("database"));
|
||||
});
|
||||
|
||||
it("should get a tree item that did not complete successfully", async () => {
|
||||
@@ -195,7 +201,7 @@ describe("HistoryTreeDataProvider", () => {
|
||||
|
||||
const treeItem = await historyTreeDataProvider.getTreeItem(mockQuery);
|
||||
expect(treeItem.iconPath).toEqual(
|
||||
new vscode.ThemeIcon("error", new vscode.ThemeColor("errorForeground")),
|
||||
new ThemeIcon("error", new ThemeColor("errorForeground")),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -207,7 +213,7 @@ describe("HistoryTreeDataProvider", () => {
|
||||
|
||||
const treeItem = await historyTreeDataProvider.getTreeItem(mockQuery);
|
||||
expect(treeItem.iconPath).toEqual(
|
||||
new vscode.ThemeIcon("error", new vscode.ThemeColor("errorForeground")),
|
||||
new ThemeIcon("error", new ThemeColor("errorForeground")),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -497,9 +503,9 @@ describe("HistoryTreeDataProvider", () => {
|
||||
{} as EvalLogViewer,
|
||||
createMockQueryHistoryDirs(),
|
||||
{
|
||||
globalStorageUri: vscode.Uri.file(mockExtensionLocation),
|
||||
extensionPath: vscode.Uri.file("/x/y/z").fsPath,
|
||||
} as vscode.ExtensionContext,
|
||||
globalStorageUri: Uri.file(mockExtensionLocation),
|
||||
extensionPath: Uri.file("/x/y/z").fsPath,
|
||||
} as ExtensionContext,
|
||||
configListener,
|
||||
new HistoryItemLabelProvider({
|
||||
format: "",
|
||||
@@ -510,7 +516,7 @@ describe("HistoryTreeDataProvider", () => {
|
||||
doCompareCallback,
|
||||
);
|
||||
(qhm.treeDataProvider as any).history = [...allHistory];
|
||||
await vscode.workspace.saveAll();
|
||||
await workspace.saveAll();
|
||||
await qhm.refreshTreeView();
|
||||
return qhm;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { join } from "path";
|
||||
import * as vscode from "vscode";
|
||||
import { ExtensionContext, Uri, window, workspace } from "vscode";
|
||||
|
||||
import { extLogger } from "../../../../src/common/logging/vscode";
|
||||
import { QueryHistoryManager } from "../../../../src/query-history/query-history-manager";
|
||||
@@ -33,7 +33,7 @@ import { LanguageContextStore } from "../../../../src/language-context-store";
|
||||
describe("QueryHistoryManager", () => {
|
||||
const mockExtensionLocation = join(tmpDir.name, "mock-extension-location");
|
||||
let configListener: QueryHistoryConfigListener;
|
||||
let showQuickPickSpy: jest.SpiedFunction<typeof vscode.window.showQuickPick>;
|
||||
let showQuickPickSpy: jest.SpiedFunction<typeof window.showQuickPick>;
|
||||
let cancelVariantAnalysisSpy: jest.SpiedFunction<
|
||||
typeof variantAnalysisManagerStub.cancelVariantAnalysis
|
||||
>;
|
||||
@@ -55,7 +55,7 @@ describe("QueryHistoryManager", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
showQuickPickSpy = jest
|
||||
.spyOn(vscode.window, "showQuickPick")
|
||||
.spyOn(window, "showQuickPick")
|
||||
.mockResolvedValue(undefined);
|
||||
|
||||
executeCommand = jest.fn();
|
||||
@@ -929,9 +929,9 @@ describe("QueryHistoryManager", () => {
|
||||
{} as EvalLogViewer,
|
||||
createMockQueryHistoryDirs(),
|
||||
{
|
||||
globalStorageUri: vscode.Uri.file(mockExtensionLocation),
|
||||
extensionPath: vscode.Uri.file("/x/y/z").fsPath,
|
||||
} as vscode.ExtensionContext,
|
||||
globalStorageUri: Uri.file(mockExtensionLocation),
|
||||
extensionPath: Uri.file("/x/y/z").fsPath,
|
||||
} as ExtensionContext,
|
||||
configListener,
|
||||
new HistoryItemLabelProvider({
|
||||
format: "",
|
||||
@@ -942,7 +942,7 @@ describe("QueryHistoryManager", () => {
|
||||
doCompareCallback,
|
||||
);
|
||||
(qhm.treeDataProvider as any).history = [...allHistory];
|
||||
await vscode.workspace.saveAll();
|
||||
await workspace.saveAll();
|
||||
await qhm.refreshTreeView();
|
||||
return qhm;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { readdirSync, mkdirSync, writeFileSync } from "fs-extra";
|
||||
import { join } from "path";
|
||||
import * as vscode from "vscode";
|
||||
import { Disposable, ExtensionContext } from "vscode";
|
||||
|
||||
import { extLogger } from "../../../../src/common/logging/vscode";
|
||||
import { registerQueryHistoryScrubber } from "../../../../src/query-history/query-history-scrubber";
|
||||
@@ -21,7 +21,7 @@ const now = Date.now();
|
||||
const LESS_THAN_ONE_DAY = ONE_DAY_IN_MS - 1000;
|
||||
|
||||
describe("query history scrubber", () => {
|
||||
let deregister: vscode.Disposable | undefined;
|
||||
let deregister: Disposable | undefined;
|
||||
let tmpDir: DirResult;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -160,7 +160,7 @@ describe("query history scrubber", () => {
|
||||
return `query-${timestamp}`;
|
||||
}
|
||||
|
||||
function createMockContext(): vscode.ExtensionContext {
|
||||
function createMockContext(): ExtensionContext {
|
||||
return {
|
||||
globalState: {
|
||||
lastScrubTime: now,
|
||||
@@ -177,13 +177,10 @@ describe("query history scrubber", () => {
|
||||
this.lastScrubTime = value;
|
||||
},
|
||||
},
|
||||
} as any as vscode.ExtensionContext;
|
||||
} as any as ExtensionContext;
|
||||
}
|
||||
|
||||
function registerScrubber(
|
||||
dir: string,
|
||||
ctx: vscode.ExtensionContext,
|
||||
): jest.Mock {
|
||||
function registerScrubber(dir: string, ctx: ExtensionContext): jest.Mock {
|
||||
const onScrubberRun = jest.fn();
|
||||
deregister = registerQueryHistoryScrubber(
|
||||
ONE_HOUR_IN_MS,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { QuickPickItem, window, Uri } from "vscode";
|
||||
import { DatabaseItem } from "../../../src/databases/local-databases";
|
||||
import * as Octokit from "@octokit/rest";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
|
||||
export type DeepPartial<T> = T extends object
|
||||
? {
|
||||
@@ -84,11 +84,11 @@ export function mockedObject<T extends object>(
|
||||
}
|
||||
|
||||
export function mockedOctokitFunction<
|
||||
Namespace extends keyof Octokit.Octokit["rest"],
|
||||
Name extends keyof Octokit.Octokit["rest"][Namespace],
|
||||
>(): Octokit.Octokit["rest"][Namespace][Name] & jest.Mock {
|
||||
Namespace extends keyof Octokit["rest"],
|
||||
Name extends keyof Octokit["rest"][Namespace],
|
||||
>(): Octokit["rest"][Namespace][Name] & jest.Mock {
|
||||
const fn = jest.fn();
|
||||
return fn as unknown as Octokit.Octokit["rest"][Namespace][Name] & jest.Mock;
|
||||
return fn as unknown as Octokit["rest"][Namespace][Name] & jest.Mock;
|
||||
}
|
||||
|
||||
export function mockDatabaseItem(
|
||||
|
||||
Reference in New Issue
Block a user