Vendored
+5
-1
@@ -9,5 +9,9 @@
|
||||
"dist": true // set this to false to include "dist" folder in search results
|
||||
},
|
||||
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
|
||||
"typescript.tsc.autoDetect": "off"
|
||||
"typescript.tsc.autoDetect": "off",
|
||||
"cSpell.words": [
|
||||
"dutchie",
|
||||
"dutchies"
|
||||
]
|
||||
}
|
||||
+165
-41
@@ -4,6 +4,8 @@ import * as path from 'path';
|
||||
export interface CompilationError {
|
||||
filePath: string;
|
||||
line: number;
|
||||
charStart?: number;
|
||||
charEnd?: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
@@ -15,49 +17,93 @@ export interface ScriptCompilerOptions {
|
||||
onError?: (error: CompilationError) => void
|
||||
}
|
||||
|
||||
export interface ICompilationLogger {
|
||||
info(message: string): void;
|
||||
error(message: string): void;
|
||||
writeLine(message: string): void;
|
||||
}
|
||||
|
||||
class Metrics {
|
||||
public totalLinesRead : number = 0;
|
||||
public totalLinesWritten: number = 0;
|
||||
public readTimeMs : number = 0;
|
||||
public writeTimeMs : number = 0;
|
||||
public totalTimeMs : number = 0;
|
||||
public filesRead : number = 0;
|
||||
public filesWritten : number = 0;
|
||||
|
||||
log(logger: ICompilationLogger){
|
||||
logger.writeLine("Compilation Metrics: ")
|
||||
logger.writeLine(`=====================`)
|
||||
logger.writeLine(`Lines Read: ${this.totalLinesRead}`)
|
||||
logger.writeLine(`Lines Written: ${this.totalLinesWritten}`)
|
||||
logger.writeLine(`Files Processed: ${this.filesRead} | ${this.filesWritten}`)
|
||||
logger.writeLine(`=====================`)
|
||||
logger.writeLine(`Read Time (ms): ${this.readTimeMs} ms`)
|
||||
logger.writeLine(`Write Time (ms): ${this.writeTimeMs} ms`)
|
||||
logger.writeLine(`Total Time (ms): ${this.totalTimeMs} ms`)
|
||||
}
|
||||
}
|
||||
|
||||
const LUA_SCRIPT_GLOBAL_KEYWORD = 'ScriptGlobals';
|
||||
|
||||
export class ScriptCompiler {
|
||||
|
||||
constructor(private options: ScriptCompilerOptions) {
|
||||
constructor(private options: ScriptCompilerOptions, private logger: ICompilationLogger) {
|
||||
if (options.outputFileName === undefined) {
|
||||
this.options.outputFileName = 'compiled.lua';
|
||||
}
|
||||
}
|
||||
|
||||
public async compile(): Promise<void> {
|
||||
public async compile(includeDevScript: boolean): Promise<void> {
|
||||
const start = Date.now();
|
||||
const metricsMeter = new Metrics();
|
||||
const entries = fs.readdirSync(this.options.sourcePath, { recursive: true, withFileTypes: true });
|
||||
const parsedFiles: Map<string, ParsedFile> = new Map();
|
||||
|
||||
const readStart = Date.now();
|
||||
for (const entry of entries) {
|
||||
if (entry.isFile() && entry.name.endsWith('.lua')) {
|
||||
const fullPath = path.join(entry.parentPath ?? entry.path, entry.name);
|
||||
const fullPath = path.join(entry.parentPath, entry.name);
|
||||
const relativePath = path.relative(this.options.sourcePath, fullPath);
|
||||
const content = fs.readFileSync(fullPath, 'utf-8');
|
||||
|
||||
const parsedFile = this.parseFile(relativePath, content, fullPath);
|
||||
const parsedFile = this.parseFile(relativePath, content, fullPath, metricsMeter);
|
||||
parsedFiles.set(parsedFile.fileKey, parsedFile);
|
||||
metricsMeter.filesRead++;
|
||||
}
|
||||
}
|
||||
const readEnd = Date.now();
|
||||
metricsMeter.readTimeMs = readEnd - readStart;
|
||||
|
||||
const writer = new Writer(
|
||||
path.join(this.options.outputPath, this.options.outputFileName!),
|
||||
parsedFiles,
|
||||
this.logger,
|
||||
this.options.onError
|
||||
);
|
||||
|
||||
const writeStart = Date.now();
|
||||
writer.write(includeDevScript, metricsMeter);
|
||||
const writeEnd = Date.now();
|
||||
metricsMeter.writeTimeMs = (writeEnd - writeStart);
|
||||
|
||||
writer.write();
|
||||
console.log(`Compilation complete. Output written to ${path.join(this.options.outputPath, this.options.outputFileName!)}`);
|
||||
// writer.logDependencyTree();
|
||||
this.logger.info(`Compilation complete. Output written to ${path.join(this.options.outputPath, this.options.outputFileName!)}`);
|
||||
const end = Date.now();
|
||||
|
||||
metricsMeter.totalTimeMs = (end-start);
|
||||
metricsMeter.log(this.logger);
|
||||
}
|
||||
|
||||
private reportError(filePath: string, line: number, message: string): void {
|
||||
private reportError(filePath: string, line: number, charStart: number | undefined, charEnd: number | undefined, message: string): void {
|
||||
if (this.options.onError) {
|
||||
this.options.onError({ filePath, line, message });
|
||||
this.options.onError({ filePath, line, charStart, charEnd, message });
|
||||
}
|
||||
}
|
||||
|
||||
private parseFile(filePath: string, content: string, fullPath: string): ParsedFile {
|
||||
const dependencies: string[] = [];
|
||||
private parseFile(filePath: string, content: string, fullPath: string, metricsMeter: Metrics): ParsedFile {
|
||||
const dependencies: Dependency[] = [];
|
||||
const newLines: string[] = [`do --${filePath}`];
|
||||
|
||||
content = stripLuaMultilineComments(content);
|
||||
@@ -83,6 +129,7 @@ export class ScriptCompiler {
|
||||
};
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
metricsMeter.totalLinesRead++;
|
||||
let line = lines[i];
|
||||
const trimmedLine = line.trim();
|
||||
|
||||
@@ -103,7 +150,7 @@ export class ScriptCompiler {
|
||||
}
|
||||
newLines.push(line);
|
||||
} else {
|
||||
this.reportError(fullPath, i, `Code found after module-level return: ${trimmedLine}`);
|
||||
this.reportError(fullPath, i, undefined, undefined, `Code found after module-level return: ${trimmedLine}`);
|
||||
newLines.push(line); // Continue processing despite error
|
||||
}
|
||||
continue;
|
||||
@@ -112,8 +159,10 @@ export class ScriptCompiler {
|
||||
// Handle require statements
|
||||
const requireMatch = line.match(/require\(['"](.+?)['"]\)/);
|
||||
if (requireMatch) {
|
||||
const requiredModule = fileReferenceToLuaVariable(requireMatch[1]);
|
||||
dependencies.push(requiredModule);
|
||||
const textMatch = requireMatch[1];
|
||||
const requiredModule = fileReferenceToLuaVariable(textMatch);
|
||||
|
||||
dependencies.push(new Dependency(textMatch, i, requireMatch.index ?? 0, (requireMatch.index ?? 0) + requireMatch[0].length));
|
||||
line = line.replace(requireMatch[0], requiredModule);
|
||||
}
|
||||
|
||||
@@ -164,7 +213,7 @@ export class ScriptCompiler {
|
||||
const afterReturn = trimmedLine.substring(afterReturnPos).trim();
|
||||
|
||||
if (afterReturn === '') {
|
||||
this.reportError(fullPath, i, 'Empty return statement at module level');
|
||||
this.reportError(fullPath, i, afterReturnPos, afterReturnPos, 'Empty return statement at module level');
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -207,7 +256,7 @@ export class ScriptCompiler {
|
||||
}
|
||||
|
||||
if (hasMultipleValues) {
|
||||
this.reportError(fullPath, i, `Multiple return values not supported: ${trimmedLine}`);
|
||||
this.reportError(fullPath, i, afterReturnPos, afterReturnPos + afterReturn.length, `Multiple return values not supported: ${trimmedLine}`);
|
||||
} else {
|
||||
// Replace return with assignment
|
||||
const moduleVariable = fileReferenceToLuaVariable(filePath);
|
||||
@@ -241,6 +290,20 @@ function stripLuaMultilineComments(content: string): string {
|
||||
return content.replace(/--\[(=*)\[[\s\S]*?\]\1\]/g, '');
|
||||
}
|
||||
|
||||
class Dependency {
|
||||
public readonly fileKey: string;
|
||||
|
||||
constructor(
|
||||
public readonly requiredModule: string,
|
||||
public readonly requiredAtLine: number,
|
||||
public readonly charStart: number,
|
||||
public readonly charEnd: number
|
||||
)
|
||||
{
|
||||
this.fileKey = fileReferenceToLuaVariable(requiredModule);
|
||||
}
|
||||
}
|
||||
|
||||
class ParsedFile {
|
||||
public readonly fileKey: string;
|
||||
|
||||
@@ -248,7 +311,7 @@ class ParsedFile {
|
||||
public readonly filePath: string,
|
||||
public readonly fullPath: string,
|
||||
public readonly lines: string[],
|
||||
public readonly dependencies: string[]
|
||||
public readonly dependencies: Dependency[]
|
||||
) {
|
||||
this.fileKey = fileReferenceToLuaVariable(filePath);
|
||||
}
|
||||
@@ -289,37 +352,55 @@ class Writer {
|
||||
constructor(
|
||||
public location: string,
|
||||
public files: Map<string, ParsedFile>,
|
||||
private readonly logger: ICompilationLogger,
|
||||
public onError?: (error: CompilationError) => void
|
||||
) {}
|
||||
|
||||
private getStartLines(): string[] {
|
||||
return [`local ${LUA_SCRIPT_GLOBAL_KEYWORD} = {}`];
|
||||
return [
|
||||
`-- Transpiled at (UTC): ${new Date().toISOString()}`,
|
||||
`local ${LUA_SCRIPT_GLOBAL_KEYWORD} = {}`
|
||||
];
|
||||
}
|
||||
|
||||
write(): void {
|
||||
logDependencyTree(): void {
|
||||
const visited: Set<string> = new Set();
|
||||
const depth : number = 1;
|
||||
this.logger.writeLine('Dependency Tree <root>:');
|
||||
const logFileRecursive = (parsedFile: ParsedFile, currentDepth: number) => {
|
||||
if(currentDepth === 0 && visited.has(parsedFile.fileKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
visited.add(parsedFile.fileKey);
|
||||
let padding = ' '.repeat(currentDepth * 2);
|
||||
if (currentDepth > 0) {
|
||||
padding += '└─>';
|
||||
}
|
||||
|
||||
const printable = parsedFile.fileKey.replace(LUA_SCRIPT_GLOBAL_KEYWORD + '.', '');
|
||||
const lastPart = printable.split('.').pop();
|
||||
this.logger.writeLine(`${padding} ${lastPart} ${' '.repeat(Math.max(0, 64 - padding.length - (lastPart ? lastPart.length : 0)))} ${printable}`);
|
||||
for (const dep of parsedFile.dependencies) {
|
||||
const depFile = this.files.get(dep.fileKey);
|
||||
if (depFile) {
|
||||
logFileRecursive(depFile, currentDepth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const parsedFile of this.files.values()) {
|
||||
logFileRecursive(parsedFile, depth);
|
||||
}
|
||||
};
|
||||
|
||||
write(includeDevScript: boolean, metrics: Metrics): void {
|
||||
const writtenFiles: Set<string> = new Set();
|
||||
const outputLines: string[] = [];
|
||||
|
||||
outputLines.push(...this.getStartLines());
|
||||
|
||||
const writeFileRecursive = (fileKey: string) => {
|
||||
if (writtenFiles.has(fileKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const file = this.files.get(fileKey);
|
||||
if (!file) {
|
||||
throw new Error(`File not found in compiler: ${fileKey}`);
|
||||
}
|
||||
|
||||
// Write dependencies first
|
||||
for (const dep of file.dependencies) {
|
||||
writeFileRecursive(dep);
|
||||
}
|
||||
|
||||
outputLines.push(...file.lines);
|
||||
writtenFiles.add(fileKey);
|
||||
};
|
||||
const startLines = this.getStartLines();
|
||||
metrics.totalLinesWritten+=startLines.length;
|
||||
outputLines.push(...startLines);
|
||||
|
||||
//Check for circular dependencies before writing
|
||||
const visited: Set<string> = new Set();
|
||||
@@ -347,7 +428,7 @@ class Writer {
|
||||
const file = this.files.get(key);
|
||||
if (file) {
|
||||
for (const dep of file.dependencies) {
|
||||
if (checkCircular(dep)) {
|
||||
if (checkCircular(dep.fileKey)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -361,12 +442,55 @@ class Writer {
|
||||
}
|
||||
}
|
||||
|
||||
const writeFileRecursive = (parsedFile: ParsedFile) => {
|
||||
if (writtenFiles.has(parsedFile.fileKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Write dependencies first
|
||||
for (const dep of parsedFile.dependencies) {
|
||||
const depFile = this.files.get(dep.fileKey);
|
||||
if (depFile) {
|
||||
writeFileRecursive(depFile);
|
||||
} else {
|
||||
this.onError?.({
|
||||
filePath: parsedFile.fullPath,
|
||||
line: dep.requiredAtLine,
|
||||
charStart: dep.charStart,
|
||||
charEnd: dep.charEnd,
|
||||
message: `Missing dependency: ${dep.fileKey}`
|
||||
});
|
||||
}
|
||||
}
|
||||
metrics.totalLinesWritten += parsedFile.lines.length;
|
||||
outputLines.push(...parsedFile.lines);
|
||||
writtenFiles.add(parsedFile.fileKey);
|
||||
metrics.filesWritten++;
|
||||
};
|
||||
|
||||
// Write all files in dependency order
|
||||
for (const fileKey of this.files.keys()) {
|
||||
writeFileRecursive(fileKey);
|
||||
for (const parsedFile of this.files.values()) {
|
||||
writeFileRecursive(parsedFile);
|
||||
}
|
||||
|
||||
fs.mkdirSync(path.dirname(this.location), { recursive: true });
|
||||
fs.writeFileSync(this.location, outputLines.join('\n'), 'utf-8');
|
||||
|
||||
if(includeDevScript) {
|
||||
const devFileLocation = this.location.replace('.lua', '.dev.lua');
|
||||
this.writeDevScript(devFileLocation, this.location);
|
||||
}
|
||||
}
|
||||
|
||||
private writeDevScript(devFileLocation: string, actualFileLocation: string){
|
||||
const devLines = [
|
||||
`-- DEV SCRIPT - NOT FOR PRODUCTION USE`,
|
||||
`-- This script can be referenced in DCS. Compiled script will then be loaded dynamically.`,
|
||||
`-- This way you can test the compiled output without having to re-import the script into the mission every time.`,
|
||||
`-- This file will only have to be re-imported when the name or location of the compiled script file changes.`,
|
||||
`assert(loadfile("${actualFileLocation}"))()`
|
||||
];
|
||||
fs.writeFileSync(devFileLocation, devLines.join('\n'), 'utf-8');
|
||||
this.logger.info(`Development script written to ${devFileLocation}`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "Node16",
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2022"],
|
||||
"strict": true,
|
||||
"sourceMap": true,
|
||||
"types": ["node"],
|
||||
"esModuleInterop": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
@@ -65,6 +65,12 @@ return utils
|
||||
|
||||
## Release Notes
|
||||
|
||||
### 0.0.2
|
||||
|
||||
- Improved error handling and reporting in the script compiler.
|
||||
- Added Output channel for compilation logs and errors.
|
||||
- Improved Settings for better user experience.
|
||||
|
||||
### 0.0.1
|
||||
|
||||
Initial.
|
||||
|
||||
@@ -24,9 +24,49 @@
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"activationEvents": [],
|
||||
"activationEvents": [
|
||||
"onLanguage:lua",
|
||||
"workspaceContains:**/*.lua"
|
||||
],
|
||||
"main": "./dist/extension.js",
|
||||
"contributes": {
|
||||
"configuration": {
|
||||
"title": "Dutchies DCS Tools",
|
||||
"type" : "object",
|
||||
"properties": {
|
||||
"dutchies-dcs-scripting-tools.dcsTypes": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Enable or disable DCS Types (adds types for DCS functions and objects)"
|
||||
},
|
||||
"dutchies-dcs-scripting-tools.spearheadTypes": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "(Coming Soon) Enable or disable Spearhead Types (requires DCS Types to be enabled)"
|
||||
},
|
||||
"dutchies-dcs-scripting-tools.compileAt" : {
|
||||
"type": "string",
|
||||
"enum": ["onSave", "onCompileCommand"],
|
||||
"default": "onCompileCommand",
|
||||
"description": "When to compile the Lua script"
|
||||
},
|
||||
"dutchies-dcs-scripting-tools.includeDevelopmentScript": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Adds an additional script. This can be referenced from DCS through doScriptFile. This will then execute the compiles script. This way you don't have to reinsert the script on each change, but can just hit 'restart'."
|
||||
},
|
||||
"dutchies-dcs-scripting-tools.luaSrcDirectory" : {
|
||||
"type":"string",
|
||||
"default": "${workspaceFolder}/src",
|
||||
"description": "Where the source files start. default: ${workspaceFolder}/src"
|
||||
},
|
||||
"dutchies-dcs-scripting-tools.luaOutputPath" : {
|
||||
"type":"string",
|
||||
"default": "${workspaceFolder}/dist",
|
||||
"description": "Where the compiled Lua files will be output. default: ${workspaceFolder}/dist"
|
||||
}
|
||||
}
|
||||
},
|
||||
"grammars": [
|
||||
{
|
||||
"path": "./syntaxes/lua-slocal.json",
|
||||
@@ -35,6 +75,11 @@
|
||||
}
|
||||
],
|
||||
"commands": [
|
||||
{
|
||||
"command": "dutchies-dcs-scripting-tools.openSettings",
|
||||
"title": "Open Settings",
|
||||
"category": "Dutchies DCS Tools"
|
||||
},
|
||||
{
|
||||
"command": "dutchies-dcs-scripting-tools.enable",
|
||||
"title": "Enable",
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// The module 'vscode' contains the VS Code extensibility API
|
||||
// Import the module and reference it with the alias vscode in your code below
|
||||
import * as vscode from 'vscode';
|
||||
import { ScriptCompiler, ScriptCompilerOptions, CompilationError } from 'dcs-script-compiler';
|
||||
import { ScriptCompiler, ScriptCompilerOptions, CompilationError, ICompilationLogger } from 'dcs-script-compiler';
|
||||
import { Logger } from './logger';
|
||||
|
||||
const luaWorkSpaceSettingKey = "Lua.workspace";
|
||||
const librarySettingsKey = "library";
|
||||
@@ -9,54 +10,108 @@ const diagnosticCollection = vscode.languages.createDiagnosticCollection('lua-tr
|
||||
|
||||
let pluginPath : string | undefined;
|
||||
|
||||
const logger = new Logger();
|
||||
|
||||
const extensionName = 'dutchies-dcs-scripting-tools';
|
||||
const publisherName = 'dutchie031';
|
||||
const extensionSettingsFilter = `@ext:${publisherName}.${extensionName}`;
|
||||
|
||||
//TODO:
|
||||
// - ENABLE/DISABLE with settings instead of commands (or both)
|
||||
|
||||
// This method is called when your extension is activated
|
||||
// Your extension is activated the very first time the command is executed
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
pluginPath = context.asAbsolutePath('lua-addons');
|
||||
|
||||
vscode.commands.registerCommand('dutchies-dcs-scripting-tools.enable', () => {
|
||||
addPluginPathToSettings();
|
||||
vscode.commands.executeCommand(
|
||||
"lua.startServer"
|
||||
);
|
||||
vscode.window.showInformationMessage('Dutchies DCS Scripting Tools enabled.');
|
||||
});
|
||||
|
||||
vscode.commands.registerCommand('dutchies-dcs-scripting-tools.disable', () => {
|
||||
removePluginPathFromSettings();
|
||||
vscode.commands.executeCommand(
|
||||
"lua.startServer"
|
||||
);
|
||||
vscode.window.showInformationMessage('Dutchies DCS Scripting Tools disabled.');
|
||||
});
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('dutchies-dcs-scripting-tools.enable', async () => {
|
||||
enableIntellisense();
|
||||
})
|
||||
);
|
||||
|
||||
vscode.commands.registerCommand('dutchies-dcs-scripting-tools.compileLuaScripts', async () => {
|
||||
try{
|
||||
const start = Date.now();
|
||||
await compileLuaScripts();
|
||||
const end = Date.now();
|
||||
console.log(`Lua scripts compiled in ${(end - start) / 1000} seconds.`);
|
||||
vscode.window.showInformationMessage(`Lua scripts compiled successfully in ${(end - start) / 1000} seconds.`);
|
||||
}catch(err){
|
||||
vscode.window.showErrorMessage('Error compiling Lua scripts: ' + (err as Error).message);
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('dutchies-dcs-scripting-tools.disable', async () => {
|
||||
disableIntellisense();
|
||||
})
|
||||
);
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('dutchies-dcs-scripting-tools.openSettings', async () => {
|
||||
await vscode.commands.executeCommand("workbench.action.openSettings", `@ext:${extensionSettingsFilter}`);
|
||||
}));
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('dutchies-dcs-scripting-tools.compileLuaScripts', async () => {
|
||||
try{
|
||||
const start = Date.now();
|
||||
await compileLuaScripts();
|
||||
const end = Date.now();
|
||||
vscode.window.showInformationMessage(`Lua scripts compiled successfully in ${(end - start) / 1000} seconds.`);
|
||||
}catch(err){
|
||||
vscode.window.showErrorMessage('Error compiling Lua scripts: ' + (err as Error).message);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
vscode.workspace.onDidSaveTextDocument(async(document) => {
|
||||
logger.info(`Document saved: ${document.uri.fsPath} | Language: ${document.languageId}`);
|
||||
if (document.languageId === 'lua') {
|
||||
const config = vscode.workspace.getConfiguration(extensionName);
|
||||
const compileAt = config.get<string>('compileAt') || "undefined";
|
||||
if (compileAt === 'onSave') {
|
||||
await compileLuaScripts();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
vscode.workspace.onDidChangeConfiguration(async(event) => {
|
||||
if (event.affectsConfiguration(`${extensionName}.dcsTypes`)) {
|
||||
const config = vscode.workspace.getConfiguration(extensionName);
|
||||
const dcsTypesEnabled = config.get<boolean>('dcsTypes') || false;
|
||||
if (dcsTypesEnabled) {
|
||||
addPluginPathToSettings();
|
||||
} else {
|
||||
removePluginPathFromSettings();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
logger.info('Dutchies DCS Scripting Tools extension activated');
|
||||
}
|
||||
|
||||
// This method is called when your extension is deactivated
|
||||
export function deactivate()
|
||||
{
|
||||
removePluginPathFromSettings();
|
||||
logger.info('Dutchies DCS Scripting Tools extension deactivated');
|
||||
}
|
||||
|
||||
class CompilationLogger implements ICompilationLogger {
|
||||
|
||||
constructor(
|
||||
private readonly logger: Logger) {
|
||||
}
|
||||
info(message: string): void {
|
||||
this.logger.info(message);
|
||||
}
|
||||
error(message: string): void {
|
||||
this.logger.error(message);
|
||||
}
|
||||
writeLine(message: string): void {
|
||||
this.logger.log(message);
|
||||
}
|
||||
}
|
||||
|
||||
async function compileLuaScripts() {
|
||||
logger.clear();
|
||||
logger.info("Compiling...");
|
||||
|
||||
const config = vscode.workspace.getConfiguration('dcsScriptingTools');
|
||||
const sourcePath = config.get<string>('luaSourcePath') || '${workspaceFolder}/src';
|
||||
const config = vscode.workspace.getConfiguration(extensionName);
|
||||
const sourcePath = config.get<string>('luaSrcDirectory') || '${workspaceFolder}/src';
|
||||
const outputPath = config.get<string>('luaOutputPath') || '${workspaceFolder}/dist';
|
||||
const minify = config.get<boolean>('minifyLuaScripts') || false;
|
||||
|
||||
|
||||
const resolvedSourcePath = sourcePath.replace('${workspaceFolder}', vscode.workspace.workspaceFolders?.[0].uri.fsPath || '');
|
||||
const resolvedOutputPath = outputPath.replace('${workspaceFolder}', vscode.workspace.workspaceFolders?.[0].uri.fsPath || '');
|
||||
|
||||
@@ -66,7 +121,7 @@ async function compileLuaScripts() {
|
||||
const options: ScriptCompilerOptions = {
|
||||
sourcePath: resolvedSourcePath,
|
||||
outputPath: resolvedOutputPath,
|
||||
minify: minify,
|
||||
minify: false,
|
||||
onError: (error: CompilationError) => {
|
||||
const errors = errorsByFile.get(error.filePath) || [];
|
||||
errors.push(error);
|
||||
@@ -74,9 +129,13 @@ async function compileLuaScripts() {
|
||||
}
|
||||
};
|
||||
|
||||
const compiler = new ScriptCompiler(options);
|
||||
const compilationLogger = new CompilationLogger(logger);
|
||||
const compiler = new ScriptCompiler(options, compilationLogger);
|
||||
|
||||
const includeDevScript = config.get<boolean>('includeDevelopmentScript') || false;
|
||||
|
||||
try {
|
||||
await compiler.compile();
|
||||
await compiler.compile(includeDevScript);
|
||||
} catch (err) {
|
||||
vscode.window.showErrorMessage('Compilation failed: ' + (err as Error).message);
|
||||
}
|
||||
@@ -86,7 +145,7 @@ async function compileLuaScripts() {
|
||||
for (const [filePath, errors] of errorsByFile) {
|
||||
const uri = vscode.Uri.file(filePath);
|
||||
const diagnostics = errors.map(error => {
|
||||
const range = new vscode.Range(error.line, 0, error.line, 0);
|
||||
const range = new vscode.Range(error.line, error.charStart ?? 0, error.line, error.charEnd ?? 0);
|
||||
const diagnostic = new vscode.Diagnostic(range, error.message, vscode.DiagnosticSeverity.Error);
|
||||
diagnostic.source = 'DCS Lua Transpiler';
|
||||
return diagnostic;
|
||||
@@ -95,6 +154,33 @@ async function compileLuaScripts() {
|
||||
}
|
||||
}
|
||||
|
||||
async function enableIntellisense() {
|
||||
|
||||
const config = vscode.workspace.getConfiguration(extensionName);
|
||||
if (config.get<boolean>("dcsTypes") === false) {
|
||||
config.update("dcsTypes", true, vscode.ConfigurationTarget.Workspace);
|
||||
}
|
||||
|
||||
addPluginPathToSettings();
|
||||
await vscode.commands.executeCommand(
|
||||
"lua.startServer"
|
||||
);
|
||||
vscode.window.showInformationMessage('Dutchies DCS Scripting Tools enabled.');
|
||||
}
|
||||
|
||||
async function disableIntellisense() {
|
||||
const config = vscode.workspace.getConfiguration(extensionName);
|
||||
if (config.get<boolean>("dcsTypes") === true) {
|
||||
config.update("dcsTypes", false, vscode.ConfigurationTarget.Workspace);
|
||||
}
|
||||
|
||||
removePluginPathFromSettings();
|
||||
await vscode.commands.executeCommand(
|
||||
"lua.startServer"
|
||||
);
|
||||
vscode.window.showInformationMessage('Dutchies DCS Scripting Tools disabled.');
|
||||
}
|
||||
|
||||
function addPluginPathToSettings() {
|
||||
if (pluginPath) {
|
||||
const luaSettings = vscode.workspace.getConfiguration(luaWorkSpaceSettingKey);
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export class Logger {
|
||||
|
||||
private outputChannel: vscode.OutputChannel;
|
||||
|
||||
constructor(){
|
||||
this.outputChannel = vscode.window.createOutputChannel('DCS Scripting Tools');
|
||||
}
|
||||
|
||||
log(message: string) {
|
||||
this.outputChannel.appendLine(message);
|
||||
}
|
||||
|
||||
info(message: string) {
|
||||
this.outputChannel.appendLine(`[${new Date().toISOString()}][INFO] ${message}`);
|
||||
}
|
||||
|
||||
error(message: string) {
|
||||
this.outputChannel.appendLine(`[${new Date().toISOString()}][ERROR] ${message}`);
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.outputChannel.clear();
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.outputChannel.dispose();
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,10 @@
|
||||
"paths": {
|
||||
"dcs-script-compiler": ["../compiler/src/ScriptCompiler.ts"]
|
||||
},
|
||||
"types": [
|
||||
"node",
|
||||
"mocha"
|
||||
],
|
||||
/* Additional Checks */
|
||||
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
"noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
|
||||
Generated
+26
-5
@@ -8,7 +8,11 @@
|
||||
"workspaces": [
|
||||
"compiler",
|
||||
"dutchies-dcs-scripting-tools"
|
||||
]
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@types/node": "^25.5.2"
|
||||
}
|
||||
},
|
||||
"compiler": {
|
||||
"name": "dcs-script-compiler",
|
||||
@@ -38,6 +42,16 @@
|
||||
"vscode": "^1.108.1"
|
||||
}
|
||||
},
|
||||
"dutchies-dcs-scripting-tools/node_modules/@types/node": {
|
||||
"version": "22.19.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.17.tgz",
|
||||
"integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@bcoe/v8-coverage": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
|
||||
@@ -830,15 +844,22 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.19.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.7.tgz",
|
||||
"integrity": "sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==",
|
||||
"version": "25.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.2.tgz",
|
||||
"integrity": "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.21.0"
|
||||
"undici-types": "~7.18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node/node_modules/undici-types": {
|
||||
"version": "7.18.2",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
|
||||
"integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/vscode": {
|
||||
"version": "1.108.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.108.1.tgz",
|
||||
|
||||
+14
-2
@@ -4,5 +4,17 @@
|
||||
"workspaces": [
|
||||
"compiler",
|
||||
"dutchies-dcs-scripting-tools"
|
||||
]
|
||||
}
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/vscode": "^1.108.1",
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@types/node": "22.x",
|
||||
"typescript-eslint": "^8.52.0",
|
||||
"eslint": "^9.39.2",
|
||||
"esbuild": "^0.27.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"typescript": "^5.9.3",
|
||||
"@vscode/test-cli": "^0.0.12",
|
||||
"@vscode/test-electron": "^2.5.2"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user