diff --git a/common/web/types/src/util/compiler-interfaces.ts b/common/web/types/src/util/compiler-interfaces.ts index 8ac2fe7709..fa7bdeca46 100644 --- a/common/web/types/src/util/compiler-interfaces.ts +++ b/common/web/types/src/util/compiler-interfaces.ts @@ -79,6 +79,10 @@ export enum CompilerErrorNamespace { * kmc and related infrastructure errors between 0x5000…0x5FFF; */ Infrastructure = 0x5000, + /** + * kmc-analyze 0x6000…0x6FFF; + */ + Analyzer = 0x6000, }; export type CompilerSchema = diff --git a/developer/src/kmc-analyze/src/messages.ts b/developer/src/kmc-analyze/src/messages.ts new file mode 100644 index 0000000000..2512fbdc19 --- /dev/null +++ b/developer/src/kmc-analyze/src/messages.ts @@ -0,0 +1,17 @@ +import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerMessageSpec as m, compilerExceptionToString as exc } from "@keymanapp/common-types"; + +const Namespace = CompilerErrorNamespace.Analyzer; +const SevInfo = CompilerErrorSeverity.Info | Namespace; +// const SevHint = CompilerErrorSeverity.Hint | Namespace; +// const SevWarn = CompilerErrorSeverity.Warn | Namespace; +// const SevError = CompilerErrorSeverity.Error | Namespace; +const SevFatal = CompilerErrorSeverity.Fatal | Namespace; + +export class AnalyzerMessages { + static Fatal_UnexpectedException = (o:{e: any}) => m(this.FATAL_UnexpectedException, `Unexpected exception: ${exc(o.e)}`); + static FATAL_UnexpectedException = SevFatal | 0x0001; + + static Info_ScanningFile = (o:{type: string, name: string}) => m(this.INFO_ScanningFile, + `Scanning ${o.type} file ${o.name}`); + static INFO_ScanningFile = SevInfo | 0x0002; +}; diff --git a/developer/src/kmc-analyze/src/osk-character-use/index.ts b/developer/src/kmc-analyze/src/osk-character-use/index.ts index 118144dd1f..4c8166d6bc 100644 --- a/developer/src/kmc-analyze/src/osk-character-use/index.ts +++ b/developer/src/kmc-analyze/src/osk-character-use/index.ts @@ -1,5 +1,6 @@ import { CompilerCallbacks, KeymanDeveloperProject, KMX, KmxFileReader, KPJFileReader, KvksFileReader, TouchLayout, TouchLayoutFileReader } from "@keymanapp/common-types"; import { KmnCompiler } from '@keymanapp/kmc-kmn'; +import { AnalyzerMessages } from "../messages.js"; export class AnalyzeOskCharacterUse { private _strings: string[] = []; @@ -47,7 +48,6 @@ export class AnalyzeOskCharacterUse { } private async analyzeProject(filename: string): Promise { - // TODO: this.callbacks.reportMessage(...) console.log(`Scanning project ${filename}`); const reader = new KPJFileReader(this.callbacks); const source = reader.read(this.callbacks.loadFile(filename)); const project = reader.transform(filename, source); @@ -64,8 +64,10 @@ export class AnalyzeOskCharacterUse { let kpjFile = this.callbacks.path.join(folder, this.callbacks.path.basename(folder) + '.kpj'); if(this.callbacks.fs.existsSync(kpjFile)) { + this.callbacks.reportMessage(AnalyzerMessages.Info_ScanningFile({type:'project', name:kpjFile})); await this.analyzeProject(kpjFile); } else { + this.callbacks.reportMessage(AnalyzerMessages.Info_ScanningFile({type:'project folder', name:folder})); const project = new KeymanDeveloperProject(kpjFile, '2.0', this.callbacks); project.populateFiles(); let files = project.files.map(file => this.callbacks.resolveFilename(kpjFile, file.filePath)); @@ -75,37 +77,36 @@ export class AnalyzeOskCharacterUse { } private async analyzeKmnKeyboard(filename: string): Promise { - // let ... + this.callbacks.reportMessage(AnalyzerMessages.Info_ScanningFile({type:'keyboard source', name:filename})); - const kmxCompiler = new KmnCompiler(); - if(!await kmxCompiler.init(this.callbacks)) { + const kmnCompiler = new KmnCompiler(); + if(!await kmnCompiler.init(this.callbacks)) { // TODO: error handling console.error('kmx compiler failed to init'); process.exit(1); } - // TODO: this belongs in kmxCompiler.run, or better, by fixing kmxCompiler to use callbacks.loadFile - filename = filename.replace(/\\/g, '/'); - - // TODO: runToMemory, add option to kmxCompiler to store debug-data for conversion to .js (e.g. store metadata, group readonly metadata, etc) - if(!kmxCompiler.run(filename, filename + '.tmp', { + // Note, output filename here is just to provide path data, + // as nothing is written to disk + let result = kmnCompiler.runCompiler(filename, filename + '.tmp', { shouldAddCompilerVersion: false, saveDebug: false, target: 'js' - })) { + }); + + if(!result) { //TODO: error handling + process.exit(1); + } + + if(result.data.kvksFilename) { + this.addStrings(this.scanVisualKeyboard(this.callbacks.resolveFilename(filename, result.data.kvksFilename))); } const reader = new KmxFileReader(); - const keyboard: KMX.KEYBOARD = reader.read(this.callbacks.loadFile(filename + '.tmp')); - - const kvkStore = keyboard.stores.find(store => store.dwSystemID == KMX.KMXFile.TSS_VISUALKEYBOARD); + const keyboard: KMX.KEYBOARD = reader.read(result.kmx.data); const touchLayoutStore = keyboard.stores.find(store => store.dwSystemID == KMX.KMXFile.TSS_LAYOUTFILE); - if(kvkStore) { - this.addStrings(this.scanVisualKeyboard(this.callbacks.resolveFilename(filename, kvkStore.dpString))); - } - if(touchLayoutStore) { this.addStrings(this.scanTouchLayout(this.callbacks.resolveFilename(filename, touchLayoutStore.dpString))); } @@ -120,8 +121,8 @@ export class AnalyzeOskCharacterUse { // private scanVisualKeyboard(filename: string): string[] { + this.callbacks.reportMessage(AnalyzerMessages.Info_ScanningFile({type:'visual keyboard', name:filename})); let strings: string[] = []; - // TODO: this.callbacks.reportMessage(...) console.log(`Scanning visual keyboard ${filename}`); const reader = new KvksFileReader(); const source = reader.read(this.callbacks.loadFile(filename)); let invalidKeys: string[] = []; @@ -136,8 +137,8 @@ export class AnalyzeOskCharacterUse { } private scanTouchLayout(filename: string): string[] { + this.callbacks.reportMessage(AnalyzerMessages.Info_ScanningFile({type:'touch layout', name:filename})); let strings: string[] = []; - // TODO: this.callbacks.reportMessage(...) console.log(`Scanning touch layout ${filename}`); const reader = new TouchLayoutFileReader(); const source = reader.read(this.callbacks.loadFile(filename)); // TODO: handle errors diff --git a/developer/src/kmc-kmn/src/compiler/compiler.ts b/developer/src/kmc-kmn/src/compiler/compiler.ts index 5e910ff45b..63d4885849 100644 --- a/developer/src/kmc-kmn/src/compiler/compiler.ts +++ b/developer/src/kmc-kmn/src/compiler/compiler.ts @@ -15,10 +15,15 @@ export interface CompilerResultFile { data: Uint8Array; }; +export interface CompilerResultMetadata { + kvksFilename?: string; +}; + export interface CompilerResult { kmx?: CompilerResultFile; kvk?: CompilerResultFile; js?: CompilerResultFile; + data: CompilerResultMetadata; }; export interface CompilerOptions { @@ -159,7 +164,7 @@ export class KmnCompiler { loadFile: this.loadFileCallback }; - let result: CompilerResult = {}; + let result: CompilerResult = {data:{}}; let wasm_interface = new this.Module.CompilerInterface(); let wasm_options = new this.Module.CompilerOptions(); let wasm_result = null; @@ -175,8 +180,9 @@ export class KmnCompiler { return null; } - if(wasm_result.kvksFilename) { - result.kvk = this.runKvkCompiler(wasm_result.kvksFilename, infile, outfile); + result.data.kvksFilename = wasm_result.kvksFilename; + if(result.data.kvksFilename) { + result.kvk = this.runKvkCompiler(result.data.kvksFilename, infile, outfile); if(!result.kvk) { return null; } diff --git a/developer/src/kmc/src/commands/analyze.ts b/developer/src/kmc/src/commands/analyze.ts index b30e736794..489f37625c 100644 --- a/developer/src/kmc/src/commands/analyze.ts +++ b/developer/src/kmc/src/commands/analyze.ts @@ -40,8 +40,6 @@ async function analyze(filenames: string[], options: AnalysisActivityOptions): P let callbacks = new NodeCompilerCallbacks({logLevel: options.outFile ? options.logLevel : 'silent'}); try { - // callbacks.reportMessage(InfrastructureMessages.Info_AnalyzingFile({filename})); - switch(options.action) { case 'osk-char-use': return await analyzeOskCharUse(callbacks, filenames, options);