Files
RunExtension/out/extension.js
2025-09-17 18:53:40 +02:00

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