182 lines
9.2 KiB
JavaScript
182 lines
9.2 KiB
JavaScript
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
}
|
|
Object.defineProperty(o, k2, desc);
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || (function () {
|
|
var ownKeys = function(o) {
|
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
var ar = [];
|
|
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
return ar;
|
|
};
|
|
return ownKeys(o);
|
|
};
|
|
return function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
})();
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.activate = activate;
|
|
exports.deactivate = deactivate;
|
|
const vscode = __importStar(require("vscode"));
|
|
const cp = __importStar(require("child_process"));
|
|
const fs = __importStar(require("fs"));
|
|
const path = __importStar(require("path"));
|
|
const codelensProvider_1 = require("./codelensProvider");
|
|
function getConfig(key, def) { const v = vscode.workspace.getConfiguration().get(key); return v === undefined ? def : v; }
|
|
function getWorkspaceFolderUri(docUri) { return docUri ? vscode.workspace.getWorkspaceFolder(docUri)?.uri : vscode.workspace.workspaceFolders?.[0]?.uri; }
|
|
function toAbs(folder, workspace) { return path.isAbsolute(folder) ? folder : (workspace ? path.join(workspace.fsPath, folder) : folder); }
|
|
function buildClasspath(folders) { return folders.join(path.delimiter); }
|
|
function readPackageName(text) { return text.match(/^\s*package\s+([\w\.]+)\s*;/m)?.[1]; }
|
|
function fqcnFromDocument(doc) { const pkg = readPackageName(doc.getText()); const simple = path.basename(doc.fileName).replace(/\.java$/i, ""); return pkg ? `${pkg}.${simple}` : simple; }
|
|
function execInTerminal(cmd, cwd, name = "Java Class Runner") { const t = vscode.window.terminals.find(tt => tt.name === name) || vscode.window.createTerminal({ name }); t.show(true); if (cwd)
|
|
t.sendText(`cd "${cwd}"`); t.sendText(cmd); }
|
|
function ensureDir(dir) { if (!fs.existsSync(dir))
|
|
fs.mkdirSync(dir, { recursive: true }); }
|
|
function psExec(cmdPath) { if (process.platform === "win32" && (cmdPath.includes("\\") || cmdPath.includes("/") || cmdPath.includes(" ")))
|
|
return `& "${cmdPath}"`; return cmdPath; }
|
|
function nearestOutFoldersFor(docPath, workspace) {
|
|
const res = [];
|
|
const fileDir = path.dirname(docPath);
|
|
const add = (p) => { if (fs.existsSync(p) && !res.includes(p))
|
|
res.push(p); };
|
|
add(path.join(fileDir, "out"));
|
|
if (workspace)
|
|
add(path.join(workspace.fsPath, "out"));
|
|
if (workspace) {
|
|
let cur = fileDir;
|
|
while (cur.startsWith(workspace.fsPath)) {
|
|
add(path.join(cur, "out"));
|
|
const parent = path.dirname(cur);
|
|
if (parent === cur)
|
|
break;
|
|
cur = parent;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
async function compileJava(javaFile, outDir, classpath, javacPath) {
|
|
ensureDir(outDir);
|
|
return new Promise((resolve, reject) => {
|
|
const args = ["-d", outDir];
|
|
if (classpath.trim().length > 0) {
|
|
args.push("-cp", classpath);
|
|
}
|
|
args.push(javaFile);
|
|
const proc = cp.spawn(javacPath, args, { shell: process.platform === "win32" });
|
|
let stderr = "";
|
|
proc.stderr.on("data", d => stderr += d.toString());
|
|
proc.on("close", code => code === 0 ? resolve() : reject(new Error(`javac exit code ${code}\n${stderr}`)));
|
|
});
|
|
}
|
|
function activate(ctx) {
|
|
ctx.subscriptions.push(vscode.languages.registerCodeLensProvider({ language: "java" }, new codelensProvider_1.JavaMainCodeLensProvider()));
|
|
ctx.subscriptions.push(vscode.commands.registerCommand("javaClassRunner.runMain", async () => {
|
|
const ed = vscode.window.activeTextEditor;
|
|
if (!ed || ed.document.languageId !== "java") {
|
|
vscode.window.showErrorMessage("Öffne eine Java-Datei mit main(...)");
|
|
return;
|
|
}
|
|
const ws = getWorkspaceFolderUri(ed.document.uri);
|
|
const cpFolders = getConfig("javaClassRunner.classpathFolders", ["classes"]).map(f => toAbs(f, ws)).filter(f => f && fs.existsSync(f));
|
|
const outDirCfg = getConfig("javaClassRunner.compile.outDir", ".java-class-runner/out");
|
|
const outDir = toAbs(outDirCfg, ws);
|
|
const compileEnabled = getConfig("javaClassRunner.compile.enabled", true);
|
|
const javaPath = getConfig("javaClassRunner.java.path", "java");
|
|
const javacPath = getConfig("javaClassRunner.javac.path", "javac");
|
|
const wdCfg = getConfig("javaClassRunner.run.workingDirectory", "${workspaceFolder}");
|
|
const wd = wdCfg.replace("${workspaceFolder}", ws?.fsPath ?? process.cwd());
|
|
const vmArgs = getConfig("javaClassRunner.run.vmArgs", []);
|
|
const programArgs = getConfig("javaClassRunner.run.programArgs", []);
|
|
const fqcn = fqcnFromDocument(ed.document);
|
|
if (!fqcn) {
|
|
vscode.window.showErrorMessage("Konnte FQCN nicht bestimmen.");
|
|
return;
|
|
}
|
|
const detectedOuts = nearestOutFoldersFor(ed.document.fileName, ws);
|
|
// compile: include detected outs so javac can resolve prebuilt dependencies (.class)
|
|
if (compileEnabled) {
|
|
try {
|
|
await compileJava(ed.document.fileName, outDir, buildClasspath([...cpFolders, ...detectedOuts]), javacPath);
|
|
}
|
|
catch (err) {
|
|
vscode.window.showErrorMessage(`Kompilierung fehlgeschlagen: ${err?.message || String(err)}`);
|
|
return;
|
|
}
|
|
}
|
|
// runtime cp: compile out + configured + detected outs
|
|
const cpCombined = buildClasspath([outDir, ...cpFolders, ...detectedOuts].filter(Boolean));
|
|
const cpArg = cpCombined.length ? `-cp "${cpCombined}"` : "";
|
|
const cmd = `${psExec(javaPath)} ${cpArg} ${vmArgs.join(" ")} ${fqcn} ${programArgs.join(" ")}`.trim();
|
|
execInTerminal(cmd, wd);
|
|
}));
|
|
ctx.subscriptions.push(vscode.commands.registerCommand("javaClassRunner.runFromClassesFolder", async () => {
|
|
const ws = getWorkspaceFolderUri();
|
|
const cpFolders = getConfig("javaClassRunner.classpathFolders", ["classes"]).map(f => toAbs(f, ws)).filter(f => f && fs.existsSync(f));
|
|
if (cpFolders.length === 0) {
|
|
vscode.window.showErrorMessage("Kein gültiger Klassen-Ordner gefunden. Prüfe 'javaClassRunner.classpathFolders'.");
|
|
return;
|
|
}
|
|
const javaPath = getConfig("javaClassRunner.java.path", "java");
|
|
const wdCfg = getConfig("javaClassRunner.run.workingDirectory", "${workspaceFolder}");
|
|
const wd = wdCfg.replace("${workspaceFolder}", ws?.fsPath ?? process.cwd());
|
|
const vmArgs = getConfig("javaClassRunner.run.vmArgs", []);
|
|
const programArgs = getConfig("javaClassRunner.run.programArgs", []);
|
|
async function listMainClassesInFolder(root) {
|
|
const out = [];
|
|
const walk = async (dir) => {
|
|
const entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
for (const e of entries) {
|
|
const full = path.join(dir, e.name);
|
|
if (e.isDirectory())
|
|
await walk(full);
|
|
else if (e.isFile() && e.name.endsWith(".class") && !e.name.includes("$")) {
|
|
const rel = path.relative(root, full).replace(/\.class$/, "");
|
|
const fqcn = rel.split(path.sep).join(".");
|
|
out.push(fqcn);
|
|
}
|
|
}
|
|
};
|
|
if (fs.existsSync(root))
|
|
await walk(root);
|
|
return out.sort();
|
|
}
|
|
const classes = [];
|
|
for (const folder of cpFolders) {
|
|
const list = await listMainClassesInFolder(folder);
|
|
for (const c of list)
|
|
if (!classes.includes(c))
|
|
classes.push(c);
|
|
}
|
|
if (classes.length === 0) {
|
|
vscode.window.showWarningMessage("Keine .class-Dateien gefunden (ohne $).");
|
|
return;
|
|
}
|
|
const picked = await vscode.window.showQuickPick(classes, { placeHolder: "Wähle eine Main-Klasse (FQCN)" });
|
|
if (!picked)
|
|
return;
|
|
const cpCombined = buildClasspath(cpFolders);
|
|
const cpArg = cpCombined.length ? `-cp "${cpCombined}"` : "";
|
|
const cmd = `${psExec(javaPath)} ${cpArg} ${vmArgs.join(" ")} ${picked} ${programArgs.join(" ")}`.trim();
|
|
execInTerminal(cmd, wd);
|
|
}));
|
|
}
|
|
function deactivate() { }
|
|
//# sourceMappingURL=extension.js.map
|