mirror of
https://github.com/Microsoft/vscode
synced 2024-10-04 02:14:06 +00:00
npm: move debug script lens into npm, clean up parsing logic
This keeps our npm logic in one place and avoids activating the heavier- weight `js-debug` extension on every .json file. Also, use the same command to debug both from the explorer and from script lens. Fixes https://github.com/microsoft/vscode-js-debug/issues/782
This commit is contained in:
parent
05b3f6f7ad
commit
5b2dc0cad2
|
@ -22,10 +22,7 @@ export function runSelectedScript(context: vscode.ExtensionContext) {
|
|||
}
|
||||
let document = editor.document;
|
||||
let contents = document.getText();
|
||||
let selection = editor.selection;
|
||||
let offset = document.offsetAt(selection.anchor);
|
||||
|
||||
let script = findScriptAtPosition(contents, offset);
|
||||
let script = findScriptAtPosition(editor.document, contents, editor.selection.anchor);
|
||||
if (script) {
|
||||
runScript(context, script, document);
|
||||
} else {
|
||||
|
|
|
@ -10,6 +10,7 @@ import { runSelectedScript, selectAndRunScriptFromFolder } from './commands';
|
|||
import { NpmScriptsTreeDataProvider } from './npmView';
|
||||
import { getPackageManager, invalidateTasksCache, NpmTaskProvider } from './tasks';
|
||||
import { invalidateHoverScriptsCache, NpmScriptHoverProvider } from './scriptHover';
|
||||
import { NpmScriptLensProvider } from './npmScriptLens';
|
||||
|
||||
let treeDataProvider: NpmScriptsTreeDataProvider | undefined;
|
||||
|
||||
|
@ -62,6 +63,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
|
|||
}
|
||||
return '';
|
||||
}));
|
||||
context.subscriptions.push(new NpmScriptLensProvider());
|
||||
}
|
||||
|
||||
function canRunNpmInCurrentWorkspace() {
|
||||
|
|
113
extensions/npm/src/npmScriptLens.ts
Normal file
113
extensions/npm/src/npmScriptLens.ts
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as path from 'path';
|
||||
import {
|
||||
CodeLens,
|
||||
CodeLensProvider,
|
||||
Disposable,
|
||||
EventEmitter,
|
||||
languages,
|
||||
TextDocument,
|
||||
Uri,
|
||||
workspace
|
||||
} from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { findPreferredPM } from './preferred-pm';
|
||||
import { readScripts } from './readScripts';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
const enum Constants {
|
||||
ConfigKey = 'debug.javascript.codelens.npmScripts',
|
||||
}
|
||||
|
||||
const getFreshLensLocation = () => workspace.getConfiguration().get(Constants.ConfigKey);
|
||||
|
||||
/**
|
||||
* Npm script lens provider implementation. Can show a "Debug" text above any
|
||||
* npm script, or the npm scripts section.
|
||||
*/
|
||||
export class NpmScriptLensProvider implements CodeLensProvider, Disposable {
|
||||
private lensLocation = getFreshLensLocation();
|
||||
private changeEmitter = new EventEmitter<void>();
|
||||
private subscriptions: Disposable[] = [];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public onDidChangeCodeLenses = this.changeEmitter.event;
|
||||
|
||||
constructor() {
|
||||
this.subscriptions.push(
|
||||
workspace.onDidChangeConfiguration(evt => {
|
||||
if (evt.affectsConfiguration(Constants.ConfigKey)) {
|
||||
this.lensLocation = getFreshLensLocation();
|
||||
this.changeEmitter.fire();
|
||||
}
|
||||
}),
|
||||
languages.registerCodeLensProvider(
|
||||
{
|
||||
language: 'json',
|
||||
pattern: '**/package.json',
|
||||
},
|
||||
this,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public async provideCodeLenses(document: TextDocument): Promise<CodeLens[]> {
|
||||
if (this.lensLocation === 'never') {
|
||||
return [];
|
||||
}
|
||||
|
||||
const tokens = readScripts(document);
|
||||
if (!tokens) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const title = localize('codelens.debug', '{0} Debug', '$(debug-start)');
|
||||
const cwd = path.dirname(document.uri.fsPath);
|
||||
if (this.lensLocation === 'top') {
|
||||
return [
|
||||
new CodeLens(
|
||||
tokens.location.range,
|
||||
{
|
||||
title,
|
||||
command: 'extension.js-debug.npmScript',
|
||||
arguments: [cwd],
|
||||
},
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
if (this.lensLocation === 'all') {
|
||||
const packageManager = await findPreferredPM(Uri.joinPath(document.uri, '..').fsPath);
|
||||
return tokens.scripts.map(
|
||||
({ name, nameRange }) =>
|
||||
new CodeLens(
|
||||
nameRange,
|
||||
{
|
||||
title,
|
||||
command: 'extension.js-debug.createDebuggerTerminal',
|
||||
arguments: [`${packageManager.name} run ${name}`, workspace.getWorkspaceFolder(document.uri), { cwd }],
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public dispose() {
|
||||
this.subscriptions.forEach(s => s.dispose());
|
||||
}
|
||||
}
|
|
@ -3,21 +3,20 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { JSONVisitor, visit } from 'jsonc-parser';
|
||||
import * as path from 'path';
|
||||
import {
|
||||
commands, Event, EventEmitter, ExtensionContext,
|
||||
Range,
|
||||
Selection, Task,
|
||||
TaskGroup, tasks, TextDocument, TextDocumentShowOptions, ThemeIcon, TreeDataProvider, TreeItem, TreeItemLabel, TreeItemCollapsibleState, Uri,
|
||||
window, workspace, WorkspaceFolder
|
||||
window, workspace, WorkspaceFolder, Position, Location
|
||||
} from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { readScripts } from './readScripts';
|
||||
import {
|
||||
createTask, getPackageManager, getTaskName, isAutoDetectionEnabled, isWorkspaceFolder, NpmTaskDefinition,
|
||||
NpmTaskProvider,
|
||||
startDebugging,
|
||||
TaskLocation,
|
||||
TaskWithLocation
|
||||
} from './tasks';
|
||||
|
||||
|
@ -78,7 +77,7 @@ class NpmScript extends TreeItem {
|
|||
task: Task;
|
||||
package: PackageJSON;
|
||||
|
||||
constructor(_context: ExtensionContext, packageJson: PackageJSON, task: Task, public taskLocation?: TaskLocation) {
|
||||
constructor(_context: ExtensionContext, packageJson: PackageJSON, task: Task, public taskLocation?: Location) {
|
||||
super(task.name, TreeItemCollapsibleState.None);
|
||||
const command: ExplorerCommands = workspace.getConfiguration('npm').get<ExplorerCommands>('scriptExplorerAction') || 'open';
|
||||
|
||||
|
@ -87,9 +86,9 @@ class NpmScript extends TreeItem {
|
|||
title: 'Edit Script',
|
||||
command: 'vscode.open',
|
||||
arguments: [
|
||||
taskLocation?.document,
|
||||
taskLocation?.uri,
|
||||
taskLocation ? <TextDocumentShowOptions>{
|
||||
selection: new Range(taskLocation.line, taskLocation.line)
|
||||
selection: new Range(taskLocation.range.start, taskLocation.range.start)
|
||||
} : undefined
|
||||
]
|
||||
},
|
||||
|
@ -153,37 +152,18 @@ export class NpmScriptsTreeDataProvider implements TreeDataProvider<TreeItem> {
|
|||
startDebugging(this.extensionContext, script.task.definition.script, path.dirname(script.package.resourceUri!.fsPath), script.getFolder());
|
||||
}
|
||||
|
||||
private findScript(document: TextDocument, script?: NpmScript): number {
|
||||
let scriptOffset = 0;
|
||||
let inScripts = false;
|
||||
private findScriptPosition(document: TextDocument, script?: NpmScript) {
|
||||
const scripts = readScripts(document);
|
||||
if (!scripts) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let visitor: JSONVisitor = {
|
||||
onError() {
|
||||
return scriptOffset;
|
||||
},
|
||||
onObjectEnd() {
|
||||
if (inScripts) {
|
||||
inScripts = false;
|
||||
if (!script) {
|
||||
return scripts.location.range.start;
|
||||
}
|
||||
},
|
||||
onObjectProperty(property: string, offset: number, _length: number) {
|
||||
if (property === 'scripts') {
|
||||
inScripts = true;
|
||||
if (!script) { // select the script section
|
||||
scriptOffset = offset;
|
||||
}
|
||||
}
|
||||
else if (inScripts && script) {
|
||||
let label = getTaskName(property, script.task.definition.path);
|
||||
if (script.task.name === label) {
|
||||
scriptOffset = offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
visit(document.getText(), visitor);
|
||||
return scriptOffset;
|
||||
|
||||
const found = scripts.scripts.find(s => getTaskName(s.name, script.task.definition.path) === script.task.name);
|
||||
return found?.nameRange.start;
|
||||
}
|
||||
|
||||
private async runInstall(selection: PackageJSON) {
|
||||
|
@ -209,8 +189,7 @@ export class NpmScriptsTreeDataProvider implements TreeDataProvider<TreeItem> {
|
|||
return;
|
||||
}
|
||||
let document: TextDocument = await workspace.openTextDocument(uri);
|
||||
let offset = this.findScript(document, selection instanceof NpmScript ? selection : undefined);
|
||||
let position = document.positionAt(offset);
|
||||
let position = this.findScriptPosition(document, selection instanceof NpmScript ? selection : undefined) || new Position(0, 0);
|
||||
await window.showTextDocument(document, { preserveFocus: true, selection: new Selection(position, position) });
|
||||
}
|
||||
|
||||
|
|
73
extensions/npm/src/readScripts.ts
Normal file
73
extensions/npm/src/readScripts.ts
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { JSONVisitor, visit } from 'jsonc-parser';
|
||||
import { Location, Position, Range, TextDocument } from 'vscode';
|
||||
|
||||
export interface INpmScriptReference {
|
||||
name: string;
|
||||
value: string;
|
||||
nameRange: Range;
|
||||
valueRange: Range;
|
||||
}
|
||||
|
||||
export interface INpmScriptInfo {
|
||||
location: Location;
|
||||
scripts: INpmScriptReference[];
|
||||
}
|
||||
|
||||
export const readScripts = (document: TextDocument, buffer = document.getText()): INpmScriptInfo | undefined => {
|
||||
let start: Position | undefined;
|
||||
let end: Position | undefined;
|
||||
let inScripts = false;
|
||||
let buildingScript: { name: string; nameRange: Range } | void;
|
||||
let level = 0;
|
||||
|
||||
const scripts: INpmScriptReference[] = [];
|
||||
const visitor: JSONVisitor = {
|
||||
onError() {
|
||||
// no-op
|
||||
},
|
||||
onObjectBegin() {
|
||||
level++;
|
||||
},
|
||||
onObjectEnd(offset) {
|
||||
if (inScripts) {
|
||||
end = document.positionAt(offset);
|
||||
inScripts = false;
|
||||
}
|
||||
level--;
|
||||
},
|
||||
onLiteralValue(value: unknown, offset: number, length: number) {
|
||||
if (buildingScript && typeof value === 'string') {
|
||||
scripts.push({
|
||||
...buildingScript,
|
||||
value,
|
||||
valueRange: new Range(document.positionAt(offset), document.positionAt(offset + length)),
|
||||
});
|
||||
buildingScript = undefined;
|
||||
}
|
||||
},
|
||||
onObjectProperty(property: string, offset: number, length: number) {
|
||||
if (level === 1 && property === 'scripts') {
|
||||
inScripts = true;
|
||||
start = document.positionAt(offset);
|
||||
} else if (inScripts) {
|
||||
buildingScript = {
|
||||
name: property,
|
||||
nameRange: new Range(document.positionAt(offset), document.positionAt(offset + length))
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
visit(buffer, visitor);
|
||||
|
||||
if (start === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return { location: new Location(document.uri, new Range(start, end ?? start)), scripts };
|
||||
};
|
|
@ -3,20 +3,24 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import {
|
||||
ExtensionContext, TextDocument, commands, ProviderResult, CancellationToken,
|
||||
workspace, tasks, Range, HoverProvider, Hover, Position, MarkdownString, Uri
|
||||
} from 'vscode';
|
||||
import {
|
||||
createTask, startDebugging, findAllScriptRanges, getPackageManager
|
||||
} from './tasks';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { dirname } from 'path';
|
||||
import {
|
||||
CancellationToken, commands, ExtensionContext,
|
||||
Hover, HoverProvider, MarkdownString, Position, ProviderResult,
|
||||
tasks, TextDocument,
|
||||
Uri, workspace
|
||||
} from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { INpmScriptInfo, readScripts } from './readScripts';
|
||||
import {
|
||||
createTask,
|
||||
getPackageManager, startDebugging
|
||||
} from './tasks';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
let cachedDocument: Uri | undefined = undefined;
|
||||
let cachedScriptsMap: Map<string, [number, number, string]> | undefined = undefined;
|
||||
let cachedScripts: INpmScriptInfo | undefined = undefined;
|
||||
|
||||
export function invalidateHoverScriptsCache(document?: TextDocument) {
|
||||
if (!document) {
|
||||
|
@ -42,20 +46,16 @@ export class NpmScriptHoverProvider implements HoverProvider {
|
|||
let hover: Hover | undefined = undefined;
|
||||
|
||||
if (!cachedDocument || cachedDocument.fsPath !== document.uri.fsPath) {
|
||||
cachedScriptsMap = findAllScriptRanges(document.getText());
|
||||
cachedScripts = readScripts(document);
|
||||
cachedDocument = document.uri;
|
||||
}
|
||||
|
||||
cachedScriptsMap!.forEach((value, key) => {
|
||||
let start = document.positionAt(value[0]);
|
||||
let end = document.positionAt(value[0] + value[1]);
|
||||
let range = new Range(start, end);
|
||||
|
||||
if (range.contains(position)) {
|
||||
cachedScripts?.scripts.forEach(({ name, nameRange }) => {
|
||||
if (nameRange.contains(position)) {
|
||||
let contents: MarkdownString = new MarkdownString();
|
||||
contents.isTrusted = true;
|
||||
contents.appendMarkdown(this.createRunScriptMarkdown(key, document.uri));
|
||||
contents.appendMarkdown(this.createDebugScriptMarkdown(key, document.uri));
|
||||
contents.appendMarkdown(this.createRunScriptMarkdown(name, document.uri));
|
||||
contents.appendMarkdown(this.createDebugScriptMarkdown(name, document.uri));
|
||||
hover = new Hover(contents);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -5,15 +5,15 @@
|
|||
|
||||
import {
|
||||
TaskDefinition, Task, TaskGroup, WorkspaceFolder, RelativePattern, ShellExecution, Uri, workspace,
|
||||
DebugConfiguration, debug, TaskProvider, TextDocument, tasks, TaskScope, QuickPickItem, window, Position, ExtensionContext, env,
|
||||
ShellQuotedString, ShellQuoting
|
||||
TaskProvider, TextDocument, tasks, TaskScope, QuickPickItem, window, Position, ExtensionContext, env,
|
||||
ShellQuotedString, ShellQuoting, commands, Location
|
||||
} from 'vscode';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as minimatch from 'minimatch';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { JSONVisitor, visit, ParseErrorCode } from 'jsonc-parser';
|
||||
import { findPreferredPM } from './preferred-pm';
|
||||
import { readScripts } from './readScripts';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
|
@ -40,7 +40,7 @@ export interface TaskLocation {
|
|||
|
||||
export interface TaskWithLocation {
|
||||
task: Task,
|
||||
location?: TaskLocation
|
||||
location?: Location
|
||||
}
|
||||
|
||||
export class NpmTaskProvider implements TaskProvider {
|
||||
|
@ -280,24 +280,24 @@ async function provideNpmScriptsForFolder(context: ExtensionContext, packageJson
|
|||
const prePostScripts = getPrePostScripts(scripts);
|
||||
const packageManager = await getPackageManager(context, folder.uri, showWarning);
|
||||
|
||||
for (const each of scripts.keys()) {
|
||||
const scriptValue = scripts.get(each)!;
|
||||
const task = await createTask(packageManager, each, ['run', each], folder!, packageJsonUri, scriptValue.script);
|
||||
const lowerCaseTaskName = each.toLowerCase();
|
||||
for (const { name, value, nameRange } of scripts.scripts) {
|
||||
const task = await createTask(packageManager, name, ['run', name], folder!, packageJsonUri, value);
|
||||
const lowerCaseTaskName = name.toLowerCase();
|
||||
if (isBuildTask(lowerCaseTaskName)) {
|
||||
task.group = TaskGroup.Build;
|
||||
} else if (isTestTask(lowerCaseTaskName)) {
|
||||
task.group = TaskGroup.Test;
|
||||
}
|
||||
if (prePostScripts.has(each)) {
|
||||
if (prePostScripts.has(name)) {
|
||||
task.group = TaskGroup.Clean; // hack: use Clean group to tag pre/post scripts
|
||||
}
|
||||
|
||||
// todo@connor4312: all scripts are now debuggable, what is a 'debug script'?
|
||||
if (isDebugScript(scriptValue.script)) {
|
||||
if (isDebugScript(value)) {
|
||||
task.group = TaskGroup.Rebuild; // hack: use Rebuild group to tag debug scripts
|
||||
}
|
||||
result.push({ task, location: scriptValue.location });
|
||||
|
||||
result.push({ task, location: new Location(packageJsonUri, nameRange) });
|
||||
}
|
||||
|
||||
// always add npm install (without a problem matcher)
|
||||
|
@ -398,145 +398,33 @@ export async function runScript(context: ExtensionContext, script: string, docum
|
|||
}
|
||||
|
||||
export async function startDebugging(context: ExtensionContext, scriptName: string, cwd: string, folder: WorkspaceFolder) {
|
||||
const config: DebugConfiguration = {
|
||||
type: 'pwa-node',
|
||||
request: 'launch',
|
||||
name: `Debug ${scriptName}`,
|
||||
cwd,
|
||||
runtimeExecutable: await getPackageManager(context, folder.uri),
|
||||
runtimeArgs: [
|
||||
'run',
|
||||
scriptName,
|
||||
],
|
||||
};
|
||||
|
||||
if (folder) {
|
||||
debug.startDebugging(folder, config);
|
||||
}
|
||||
commands.executeCommand(
|
||||
'extension.js-debug.createDebuggerTerminal',
|
||||
`${await getPackageManager(context, folder.uri)} run ${scriptName}`,
|
||||
folder,
|
||||
{ cwd },
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export type StringMap = { [s: string]: string; };
|
||||
|
||||
async function findAllScripts(document: TextDocument, buffer: string): Promise<Map<string, { script: string, location: TaskLocation }>> {
|
||||
let scripts: Map<string, { script: string, location: TaskLocation }> = new Map();
|
||||
let script: string | undefined = undefined;
|
||||
let inScripts = false;
|
||||
let scriptOffset = 0;
|
||||
|
||||
let visitor: JSONVisitor = {
|
||||
onError(_error: ParseErrorCode, _offset: number, _length: number) {
|
||||
console.log(_error);
|
||||
},
|
||||
onObjectEnd() {
|
||||
if (inScripts) {
|
||||
inScripts = false;
|
||||
}
|
||||
},
|
||||
onLiteralValue(value: any, _offset: number, _length: number) {
|
||||
if (script) {
|
||||
if (typeof value === 'string') {
|
||||
scripts.set(script, { script: value, location: { document: document.uri, line: document.positionAt(scriptOffset) } });
|
||||
}
|
||||
script = undefined;
|
||||
}
|
||||
},
|
||||
onObjectProperty(property: string, offset: number, _length: number) {
|
||||
if (property === 'scripts') {
|
||||
inScripts = true;
|
||||
}
|
||||
else if (inScripts && !script) {
|
||||
script = property;
|
||||
scriptOffset = offset;
|
||||
} else { // nested object which is invalid, ignore the script
|
||||
script = undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
visit(buffer, visitor);
|
||||
return scripts;
|
||||
export function findScriptAtPosition(document: TextDocument, buffer: string, position: Position): string | undefined {
|
||||
const read = readScripts(document, buffer);
|
||||
if (!read) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function findAllScriptRanges(buffer: string): Map<string, [number, number, string]> {
|
||||
let scripts: Map<string, [number, number, string]> = new Map();
|
||||
let script: string | undefined = undefined;
|
||||
let offset: number;
|
||||
let length: number;
|
||||
|
||||
let inScripts = false;
|
||||
|
||||
let visitor: JSONVisitor = {
|
||||
onError(_error: ParseErrorCode, _offset: number, _length: number) {
|
||||
},
|
||||
onObjectEnd() {
|
||||
if (inScripts) {
|
||||
inScripts = false;
|
||||
for (const script of read.scripts) {
|
||||
if (script.nameRange.start.isBeforeOrEqual(position) && script.valueRange.end.isAfterOrEqual(position)) {
|
||||
return script.name;
|
||||
}
|
||||
},
|
||||
onLiteralValue(value: any, _offset: number, _length: number) {
|
||||
if (script) {
|
||||
scripts.set(script, [offset, length, value]);
|
||||
script = undefined;
|
||||
}
|
||||
},
|
||||
onObjectProperty(property: string, off: number, len: number) {
|
||||
if (property === 'scripts') {
|
||||
inScripts = true;
|
||||
}
|
||||
else if (inScripts) {
|
||||
script = property;
|
||||
offset = off;
|
||||
length = len;
|
||||
}
|
||||
}
|
||||
};
|
||||
visit(buffer, visitor);
|
||||
return scripts;
|
||||
}
|
||||
|
||||
export function findScriptAtPosition(buffer: string, offset: number): string | undefined {
|
||||
let script: string | undefined = undefined;
|
||||
let foundScript: string | undefined = undefined;
|
||||
let inScripts = false;
|
||||
let scriptStart: number | undefined;
|
||||
let visitor: JSONVisitor = {
|
||||
onError(_error: ParseErrorCode, _offset: number, _length: number) {
|
||||
},
|
||||
onObjectEnd() {
|
||||
if (inScripts) {
|
||||
inScripts = false;
|
||||
scriptStart = undefined;
|
||||
}
|
||||
},
|
||||
onLiteralValue(value: any, nodeOffset: number, nodeLength: number) {
|
||||
if (inScripts && scriptStart) {
|
||||
if (typeof value === 'string' && offset >= scriptStart && offset < nodeOffset + nodeLength) {
|
||||
// found the script
|
||||
inScripts = false;
|
||||
foundScript = script;
|
||||
} else {
|
||||
script = undefined;
|
||||
}
|
||||
}
|
||||
},
|
||||
onObjectProperty(property: string, nodeOffset: number) {
|
||||
if (property === 'scripts') {
|
||||
inScripts = true;
|
||||
}
|
||||
else if (inScripts) {
|
||||
scriptStart = nodeOffset;
|
||||
script = property;
|
||||
} else { // nested object which is invalid, ignore the script
|
||||
script = undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
visit(buffer, visitor);
|
||||
return foundScript;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export async function getScripts(packageJsonUri: Uri): Promise<Map<string, { script: string, location: TaskLocation }> | undefined> {
|
||||
|
||||
export async function getScripts(packageJsonUri: Uri) {
|
||||
if (packageJsonUri.scheme !== 'file') {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -548,9 +436,7 @@ export async function getScripts(packageJsonUri: Uri): Promise<Map<string, { scr
|
|||
|
||||
try {
|
||||
const document: TextDocument = await workspace.openTextDocument(packageJsonUri);
|
||||
let contents = document.getText();
|
||||
let json = findAllScripts(document, contents);//JSON.parse(contents);
|
||||
return json;
|
||||
return readScripts(document);
|
||||
} catch (e) {
|
||||
let localizedParseError = localize('npm.parseError', 'Npm task detection: failed to parse the file {0}', packageJsonUri.fsPath);
|
||||
throw new Error(localizedParseError);
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
},
|
||||
{
|
||||
"name": "ms-vscode.js-debug",
|
||||
"version": "1.53.0",
|
||||
"version": "1.54.0",
|
||||
"repo": "https://github.com/microsoft/vscode-js-debug",
|
||||
"metadata": {
|
||||
"id": "25629058-ddac-4e17-abba-74678e126c5d",
|
||||
|
|
Loading…
Reference in a new issue