Switch back to computing the file names in one place.

This commit is contained in:
alexet 2019-12-09 18:44:41 +00:00 коммит произвёл Jason Reed
Родитель 29f6ec9996
Коммит bd4f56e90f
5 изменённых файлов: 37 добавлений и 32 удалений

Просмотреть файл

@ -37,8 +37,9 @@ export interface Interpretation {
sarif: sarif.Log;
}
export interface ResultsInfo {
export interface ResultsPaths {
resultsPath: string;
interpretedResultsPath: string;
}
export interface SortedResultSetInfo {
@ -60,6 +61,7 @@ export interface ResultsUpdatingMsg {
export interface SetStateMsg {
t: 'setState';
resultsPath: string;
origResultsPaths: ResultsPaths;
sortedResultsMap: SortedResultsMap;
interpretation: undefined | Interpretation;
database: DatabaseInfo;
@ -94,7 +96,7 @@ interface ToggleDiagnostics {
t: 'toggleDiagnostics';
databaseUri: string;
metadata?: QueryMetadata
resultsPath: string;
origResultsPaths: ResultsPaths;
visible: boolean;
kind?: string;
};

Просмотреть файл

@ -6,13 +6,13 @@ import { parseSarifLocation, parseSarifPlainTextMessage } from './sarif-utils';
import { FivePartLocation, LocationValue, ResolvableLocationValue, WholeFileLocation, tryGetResolvableLocation, LocationStyle } from 'semmle-bqrs';
import { DisposableObject } from 'semmle-vscode-utils';
import * as vscode from 'vscode';
import { Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, languages, Location, Position, Range, Uri, window as Window, workspace } from 'vscode';
import { Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, languages, Location, Range, Uri, window as Window, workspace } from 'vscode';
import { CodeQLCliServer } from './cli';
import { DatabaseItem, DatabaseManager } from './databases';
import * as helpers from './helpers';
import { showAndLogErrorMessage } from './helpers';
import { assertNever } from './helpers-pure';
import { FromResultsViewMsg, Interpretation, IntoResultsViewMsg, ResultsInfo, SortedResultSetInfo, SortedResultsMap, INTERPRETED_RESULTS_PER_RUN_LIMIT, QueryMetadata } from './interface-types';
import { FromResultsViewMsg, Interpretation, IntoResultsViewMsg, ResultsPaths, SortedResultSetInfo, SortedResultsMap, INTERPRETED_RESULTS_PER_RUN_LIMIT, QueryMetadata } from './interface-types';
import { Logger } from './logging';
import * as messages from './messages';
import { EvaluationInfo, interpretResults, QueryInfo, tmpDir } from './queries';
@ -166,7 +166,7 @@ export class InterfaceManager extends DisposableObject {
if (msg.visible) {
const databaseItem = this.databaseManager.findDatabaseItem(Uri.parse(msg.databaseUri));
if (databaseItem !== undefined) {
await this.showResultsAsDiagnostics(msg.resultsPath, msg.metadata, databaseItem);
await this.showResultsAsDiagnostics(msg.origResultsPaths, msg.metadata, databaseItem);
}
} else {
// TODO: Only clear diagnostics on the same database.
@ -223,7 +223,7 @@ export class InterfaceManager extends DisposableObject {
return;
}
const interpretation = await this.interpretResultsInfo(info.query, info.query.resultsInfo);
const interpretation = await this.interpretResultsInfo(info.query, info.query.resultsPaths);
const sortedResultsMap: SortedResultsMap = {};
info.query.sortedResultsInfo.forEach((v, k) =>
@ -259,7 +259,8 @@ export class InterfaceManager extends DisposableObject {
await this.postMessage({
t: 'setState',
interpretation,
resultsPath: this.convertPathToWebviewUri(info.query.resultsInfo.resultsPath),
origResultsPaths: info.query.resultsPaths,
resultsPath: this.convertPathToWebviewUri(info.query.resultsPaths.resultsPath),
sortedResultsMap,
database: info.database,
shouldKeepOldResultsWhileRendering,
@ -267,8 +268,8 @@ export class InterfaceManager extends DisposableObject {
});
}
private async getTruncatedResults(metadata : QueryMetadata | undefined ,resultsPathOnDisk: string, sourceInfo : cli.SourceInfo | undefined, sourceLocationPrefix : string ) : Promise<Interpretation> {
const sarif = await interpretResults(this.cliServer, metadata, resultsPathOnDisk, sourceInfo);
private async getTruncatedResults(metadata : QueryMetadata | undefined ,resultsInfo: ResultsPaths, sourceInfo : cli.SourceInfo | undefined, sourceLocationPrefix : string ) : Promise<Interpretation> {
const sarif = await interpretResults(this.cliServer, metadata, resultsInfo, sourceInfo);
// For performance reasons, limit the number of results we try
// to serialize and send to the webview. TODO: possibly also
// limit number of paths per result, number of steps per path,
@ -288,7 +289,7 @@ private async getTruncatedResults(metadata : QueryMetadata | undefined ,resultsP
;
}
private async interpretResultsInfo(query: QueryInfo, resultsInfo: ResultsInfo): Promise<Interpretation | undefined> {
private async interpretResultsInfo(query: QueryInfo, resultsInfo: ResultsPaths): Promise<Interpretation | undefined> {
let interpretation: Interpretation | undefined = undefined;
if (query.hasInterpretedResults()
&& query.quickEvalPosition === undefined // never do results interpretation if quickEval
@ -299,7 +300,7 @@ private async getTruncatedResults(metadata : QueryMetadata | undefined ,resultsP
const sourceInfo = sourceArchiveUri === undefined ?
undefined :
{ sourceArchive: sourceArchiveUri.fsPath, sourceLocationPrefix };
interpretation = await this.getTruncatedResults(query.metadata, resultsInfo.resultsPath, sourceInfo, sourceLocationPrefix);
interpretation = await this.getTruncatedResults(query.metadata, resultsInfo, sourceInfo, sourceLocationPrefix);
}
catch (e) {
// If interpretation fails, accept the error and continue
@ -311,15 +312,13 @@ private async getTruncatedResults(metadata : QueryMetadata | undefined ,resultsP
}
private async showResultsAsDiagnostics(webviewResultsUri: string, metadata: QueryMetadata | undefined, database: DatabaseItem) {
// URIs from the webview have the vscode-resource scheme, so convert into a filesystem URI first.
const resultsPathOnDisk = webviewUriToFileUri(webviewResultsUri).fsPath;
private async showResultsAsDiagnostics(resultsInfo: ResultsPaths, metadata: QueryMetadata | undefined, database: DatabaseItem) {
const sourceLocationPrefix = await database.getSourceLocationPrefix(this.cliServer);
const sourceArchiveUri = database.sourceArchive;
const sourceInfo = sourceArchiveUri === undefined ?
undefined :
{ sourceArchive: sourceArchiveUri.fsPath, sourceLocationPrefix };
const interpretation = await this.getTruncatedResults(metadata, resultsPathOnDisk, sourceInfo, sourceLocationPrefix);
const interpretation = await this.getTruncatedResults(metadata, resultsInfo, sourceInfo, sourceLocationPrefix);
try {
await this.showProblemResultsAsDiagnostics(interpretation, database);

Просмотреть файл

@ -7,7 +7,7 @@ import * as vscode from 'vscode';
import * as cli from './cli';
import { DatabaseItem, getUpgradesDirectories } from './databases';
import * as helpers from './helpers';
import { DatabaseInfo, SortState, ResultsInfo, SortedResultSetInfo, QueryMetadata } from './interface-types';
import { DatabaseInfo, SortState, ResultsPaths, SortedResultSetInfo, QueryMetadata } from './interface-types';
import { logger } from './logging';
import * as messages from './messages';
import * as qsClient from './queryserver-client';
@ -50,7 +50,7 @@ export class UserCancellationException extends Error { }
*/
export class QueryInfo {
compiledQueryPath: string;
resultsInfo: ResultsInfo;
resultsPaths: ResultsPaths;
private static nextQueryId = 0;
/**
@ -68,7 +68,8 @@ export class QueryInfo {
) {
this.queryId = QueryInfo.nextQueryId++;
this.compiledQueryPath = path.join(tmpDir.name, `compiledQuery${this.queryId}.qlo`);
this.resultsInfo = {
this.resultsPaths = {
interpretedResultsPath: path.join(tmpDir.name, `interpretedResults${this.queryId}.sarif`),
resultsPath: path.join(tmpDir.name, `results${this.queryId}.bqrs`),
};
this.sortedResultsInfo = new Map();
@ -86,7 +87,7 @@ export class QueryInfo {
const callbackId = qs.registerCallback(res => { result = res });
const queryToRun: messages.QueryToRun = {
resultsPath: this.resultsInfo.resultsPath,
resultsPath: this.resultsPaths.resultsPath,
qlo: vscode.Uri.file(this.compiledQueryPath).toString(),
allowUnknownTemplates: true,
id: callbackId,
@ -177,7 +178,7 @@ export class QueryInfo {
sortState
};
await server.sortBqrs(this.resultsInfo.resultsPath, sortedResultSetInfo.resultsPath, resultSetName, [sortState.columnIndex], [sortState.direction]);
await server.sortBqrs(this.resultsPaths.resultsPath, sortedResultSetInfo.resultsPath, resultSetName, [sortState.columnIndex], [sortState.direction]);
this.sortedResultsInfo.set(resultSetName, sortedResultSetInfo);
}
}
@ -185,11 +186,10 @@ export class QueryInfo {
/**
* Call cli command to interpret results.
*/
export async function interpretResults(server: cli.CodeQLCliServer, metadata: QueryMetadata | undefined, resultsPath: string, sourceInfo?: cli.SourceInfo): Promise<sarif.Log> {
const interpretedResultsPath = resultsPath + ".interpreted.sarif"
export async function interpretResults(server: cli.CodeQLCliServer, metadata: QueryMetadata | undefined, resultsInfo: ResultsPaths, sourceInfo?: cli.SourceInfo): Promise<sarif.Log> {
if (await fs.pathExists(interpretedResultsPath)) {
return JSON.parse(await fs.readFile(interpretedResultsPath, 'utf8'));
if (await fs.pathExists(resultsInfo.interpretedResultsPath)) {
return JSON.parse(await fs.readFile(resultsInfo.interpretedResultsPath, 'utf8'));
}
if (metadata == undefined) {
throw new Error('Can\'t interpret results without query metadata');
@ -203,7 +203,7 @@ export async function interpretResults(server: cli.CodeQLCliServer, metadata: Qu
// SARIF format does, so in the absence of one, we use a dummy id.
id = "dummy-id";
}
return await server.interpretBqrs( { kind, id }, resultsPath, interpretedResultsPath, sourceInfo);
return await server.interpretBqrs( { kind, id }, resultsInfo.resultsPath, resultsInfo.interpretedResultsPath, sourceInfo);
}
export interface EvaluationInfo {

Просмотреть файл

@ -1,5 +1,5 @@
import * as React from 'react';
import { DatabaseInfo, Interpretation, SortState, QueryMetadata } from '../interface-types';
import { DatabaseInfo, Interpretation, SortState, QueryMetadata, ResultsPaths } from '../interface-types';
import { PathTable } from './alert-table';
import { RawTable } from './raw-results-table';
import { ResultTableProps, tableSelectionHeaderClassName, toggleDiagnosticsClassName } from './result-table-utils';
@ -13,7 +13,8 @@ export interface ResultTablesProps {
interpretation: Interpretation | undefined;
database: DatabaseInfo;
metadata? : QueryMetadata
resultsPath: string | undefined;
resultsPath: string ;
origResultsPaths: ResultsPaths;
sortStates: Map<string, SortState>;
isLoadingNewResults: boolean;
}
@ -95,7 +96,7 @@ export class ResultTables
render(): React.ReactNode {
const { selectedTable } = this.state;
const resultSets = this.getResultSets();
const { database, resultsPath, metadata } = this.props;
const { database, resultsPath, metadata, origResultsPaths } = this.props;
// Only show the Problems view display checkbox for the alerts table.
const diagnosticsCheckBox = selectedTable === ALERTS_TABLE_NAME ?
@ -104,7 +105,7 @@ export class ResultTables
if (resultsPath !== undefined) {
vscode.postMessage({
t: 'toggleDiagnostics',
resultsPath: resultsPath,
origResultsPaths: origResultsPaths,
databaseUri: database.databaseUri,
visible: e.target.checked,
metadata: metadata

Просмотреть файл

@ -3,7 +3,7 @@ import * as Rdom from 'react-dom';
import * as bqrs from 'semmle-bqrs';
import { ElementBase, LocationValue, PrimitiveColumnValue, PrimitiveTypeKind, ResultSetSchema, tryGetResolvableLocation } from 'semmle-bqrs';
import { assertNever } from '../helpers-pure';
import { DatabaseInfo, FromResultsViewMsg, Interpretation, IntoResultsViewMsg, SortedResultSetInfo, SortState, NavigatePathMsg, QueryMetadata } from '../interface-types';
import { DatabaseInfo, FromResultsViewMsg, Interpretation, IntoResultsViewMsg, SortedResultSetInfo, SortState, NavigatePathMsg, QueryMetadata, ResultsPaths } from '../interface-types';
import { ResultTables } from './result-tables';
import { EventHandlers as EventHandlerList } from './event-handler-list';
@ -127,6 +127,7 @@ async function parseResultSets(response: Response): Promise<readonly ResultSet[]
interface ResultsInfo {
resultsPath: string;
origResultsPaths: ResultsPaths;
database: DatabaseInfo;
interpretation: Interpretation | undefined;
sortedResultsMap: Map<string, SortedResultSetInfo>;
@ -186,6 +187,7 @@ class App extends React.Component<{}, ResultsViewState> {
case 'setState':
this.updateStateWithNewResultsInfo({
resultsPath: msg.resultsPath,
origResultsPaths: msg.origResultsPaths,
sortedResultsMap: new Map(Object.entries(msg.sortedResultsMap)),
database: msg.database,
interpretation: msg.interpretation,
@ -304,11 +306,12 @@ class App extends React.Component<{}, ResultsViewState> {
render() {
const displayedResults = this.state.displayedResults;
if (displayedResults.results !== null) {
if (displayedResults.results !== null && displayedResults.resultsInfo !== null) {
return <ResultTables rawResultSets={displayedResults.results.resultSets}
interpretation={displayedResults.resultsInfo ? displayedResults.resultsInfo.interpretation : undefined}
database={displayedResults.results.database}
resultsPath={displayedResults.resultsInfo ? displayedResults.resultsInfo.resultsPath : undefined}
origResultsPaths={displayedResults.resultsInfo.origResultsPaths}
resultsPath={displayedResults.resultsInfo.resultsPath}
metadata={displayedResults.resultsInfo ? displayedResults.resultsInfo.metadata : undefined}
sortStates={displayedResults.results.sortStates}
isLoadingNewResults={this.state.isExpectingResultsUpdate || this.state.nextResultsInfo !== null} />;