feat(developer): use new memory-based kmx compiler in analyze

* Also adds info messages for scanning.
This commit is contained in:
Marc Durdin 2023-06-09 12:38:20 +07:00
parent fde428fb70
commit 3b5c38aa80
5 changed files with 50 additions and 24 deletions

View file

@ -79,6 +79,10 @@ export enum CompilerErrorNamespace {
* kmc and related infrastructure errors between 0x50000x5FFF;
*/
Infrastructure = 0x5000,
/**
* kmc-analyze 0x60000x6FFF;
*/
Analyzer = 0x6000,
};
export type CompilerSchema =

View file

@ -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;
};

View file

@ -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<void> {
// 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<void> {
// 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

View file

@ -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;
}

View file

@ -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);