Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed bug of regular errors being reported as unexpected cli error despite expected failure #502

10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,20 @@ To use development versions of Kipper download the

### Changed

- Moved function `executeKipperProgram` to `Run` as a private function.
- Moved class `KipperCompileResult` to new file `compile-result.ts` in the same directory.
- Field `KipperCompileResult.programCtx` can now be also `undefined`, due to the changed behaviour that now
a `KipperCompileResult` is also returned for syntax errors (where it has no value).

### Fixed

- CLI error handling bug as described in [#491](https://github.com/Luna-Klatzer/Kipper/issues/491). This includes
multiple bugs where errors were reported as "Unexpected CLI Error".

### Deprecated

- CLI flag `--abort-on-first-error` in favour of `--no-recover`. [#501](https://github.com/Luna-Klatzer/Kipper/issues/501).

### Removed

</details>
Expand Down
17 changes: 16 additions & 1 deletion kipper/cli/src/commands/compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
KipperCompiler,
KipperCompileResult,
KipperCompileTarget,
KipperError,
KipperLogger,
KipperParseStream,
LogLevel,
Expand Down Expand Up @@ -87,6 +88,10 @@ export default class Compile extends Command {
description: "Recover from compiler errors and log all detected semantic issues.",
allowNo: true,
}),
/**
* TODO! Remove this flag
* @deprecated
*/
"abort-on-first-error": flags.boolean({
default: EvaluatedCompileConfig.defaults.abortOnFirstError,
description: "Abort on the first error the compiler encounters.",
Expand Down Expand Up @@ -139,7 +144,17 @@ export default class Compile extends Command {
const startTime: number = new Date().getTime();

// Compile the file
let result: KipperCompileResult = await compiler.compile(config.stream, config.compilerOptions);
let result: KipperCompileResult;
try {
result = await compiler.compile(config.stream, config.compilerOptions);
} catch (e) {
if (e instanceof KipperError && config.compilerOptions.abortOnFirstError) {
// Ignore the error thrown by the compiler (the logger already logged it)
// TODO! This will be removed once 'abortOnFirstError' has been fully removed with v0.11.0 -> #501
return;
}
throw e;
}

// If the compilation failed, abort
if (!result.success) {
Expand Down
46 changes: 26 additions & 20 deletions kipper/cli/src/commands/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,6 @@ import { getParseStream, getTarget, KipperEncoding, KipperEncodings, verifyEncod
import { writeCompilationResult } from "../output";
import { prettifiedErrors } from "../decorators";

/**
* Run the Kipper program.
* @param jsCode
*/
export async function executeKipperProgram(jsCode: string) {
const kipperProgram = spawn(process.execPath, ["-e", jsCode]);

// Per default the encoding should be 'utf-8'
kipperProgram.stdin.setDefaultEncoding("utf-8");

// Set how to handle streams
kipperProgram.stdout.pipe(process.stdout);
kipperProgram.stderr.pipe(process.stderr);

// Close immediately after the Kipper program
kipperProgram.on("close", (code: number) => process.exit(code));
}

export default class Run extends Command {
static override description: string = "Compile and execute a Kipper program.";

Expand Down Expand Up @@ -107,6 +89,10 @@ export default class Run extends Command {
description: "Recover from compiler errors and display all detected compiler errors.",
allowNo: true,
}),
/**
* TODO! Remove this flag
* @deprecated
*/
"abort-on-first-error": flags.boolean({
default: EvaluatedCompileConfig.defaults.abortOnFirstError,
description: "Abort on the first error the compiler encounters. Same behaviour as '--no-recover'.",
Expand Down Expand Up @@ -150,6 +136,24 @@ export default class Run extends Command {
};
}

/**
* Run the Kipper program in a new spawned process.
* @param jsCode The JavaScript code to execute using the same JavaScript runtime as this CLI is being executed from.
*/
private async executeKipperProgram(jsCode: string): Promise<void> {
const kipperProgram = spawn(process.execPath, ["-e", jsCode]);

// Per default the encoding should be 'utf-8'
kipperProgram.stdin.setDefaultEncoding("utf-8");

// Set how to handle streams
kipperProgram.stdout.pipe(process.stdout);
kipperProgram.stderr.pipe(process.stderr);

// Close immediately after the Kipper program
kipperProgram.on("close", (code: number) => process.exit(code));
}

@prettifiedErrors<Run>()
public async run() {
const { flags, config } = await this.getRunConfig();
Expand All @@ -166,7 +170,9 @@ export default class Run extends Command {
result = await compiler.compile(config.stream, config.compilerOptions);
} catch (e) {
if (e instanceof KipperError && config.compilerOptions.abortOnFirstError) {
return; // Ignore the error thrown by the compiler (the logger already logged it)
// Ignore the error thrown by the compiler (the logger already logged it)
// TODO! This will be removed once 'abortOnFirstError' has been fully removed with v0.11.0 -> #501
return;
}
throw e;
}
Expand All @@ -193,6 +199,6 @@ export default class Run extends Command {
}

// Execute the program
await executeKipperProgram(jsProgram);
await this.executeKipperProgram(jsProgram);
}
}
2 changes: 2 additions & 0 deletions kipper/cli/src/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export function prettifiedErrors<TProto extends Command>() {
: undefined,
};

// 'Command.error' (i.e. 'this.error') will throw the CLI error we want, which means we need to catch it and
// modify it, so we have the correct result we want
try {
this.error(msg, errConfig);
} catch (e) {
Expand Down
14 changes: 7 additions & 7 deletions kipper/cli/src/input/file-stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export async function getParseStream(
* @since 0.0.2
*/
export class KipperParseFile extends KipperParseStream {
public static SPECIAL_CHARACTER_REPLACE_REGEX =
/[\x00-\x09\x0B-\x1F\x7F-\x9F\xAD\u0378\u0379\u037F-\u0383\u038B\u038D\u03A2\u0528-\u0530\u0557\u0558\u0560\u0588\u058B-\u058E\u0590\u05C8-\u05CF\u05EB-\u05EF\u05F5-\u0605\u061C\u061D\u06DD\u070E\u070F\u074B\u074C\u07B2-\u07BF\u07FB-\u07FF\u082E\u082F\u083F\u085C\u085D\u085F-\u089F\u08A1\u08AD-\u08E3\u08FF\u0978\u0980\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FC-\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B55\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0C00\u0C04\u0C0D\u0C11\u0C29\u0C34\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5A-\u0C5F\u0C64\u0C65\u0C70-\u0C77\u0C80\u0C81\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0D01\u0D04\u0D0D\u0D11\u0D3B\u0D3C\u0D45\u0D49\u0D4F-\u0D56\u0D58-\u0D5F\u0D64\u0D65\u0D76-\u0D78\u0D80\u0D81\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E86\u0E89\u0E8B\u0E8C\u0E8E-\u0E93\u0E98\u0EA0\u0EA4\u0EA6\u0EA8\u0EA9\u0EAC\u0EBA\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F5-\u13FF\u169D-\u169F\u16F1-\u16FF\u170D\u1715-\u171F\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u180F\u181A-\u181F\u1878-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191D-\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE-\u1AFF\u1B4C-\u1B4F\u1B7D-\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C80-\u1CBF\u1CC8-\u1CCF\u1CF7-\u1CFF\u1DE7-\u1DFB\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u200B-\u200F\u202A-\u202E\u2060-\u206F\u2072\u2073\u208F\u209D-\u209F\u20BB-\u20CF\u20F1-\u20FF\u218A-\u218F\u23F4-\u23FF\u2427-\u243F\u244B-\u245F\u2700\u2B4D-\u2B4F\u2B5A-\u2BFF\u2C2F\u2C5F\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E3C-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u312E-\u3130\u318F\u31BB-\u31BF\u31E4-\u31EF\u321F\u32FF\u4DB6-\u4DBF\u9FCD-\u9FFF\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA698-\uA69E\uA6F8-\uA6FF\uA78F\uA794-\uA79F\uA7AB-\uA7F7\uA82C-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C5-\uA8CD\uA8DA-\uA8DF\uA8FC-\uA8FF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9E0-\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAA7C-\uAA7F\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F-\uABBF\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFE\uFDFF\uFE1A-\uFE1F\uFE27-\uFE2F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD-\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFFB\uFFFE\uFFFF]/g;
private readonly _absolutePath: string;
private readonly _encoding: BufferEncoding;
private readonly _path: path.ParsedPath;
Expand Down Expand Up @@ -118,23 +120,21 @@ export class KipperParseFile extends KipperParseStream {
return items2[items2.length - 1];
})();

// Read in the content of the file
let content: string = (await fs.readFile(fileLocation, encoding as BufferEncoding)).toString();

// Ensure the file can be accessed
try {
await fs.access(fileLocation, constants.R_OK);
} catch (e) {
throw new KipperFileAccessError(fileLocation);
}

// Read in the content of the file
let content: string = (await fs.readFile(fileLocation, encoding as BufferEncoding)).toString();

// Standardising the line endings to '\n'
content = content.replace(/(\r(\n)?)/gi, "\n");

// Remove non-printable unicode characters
content = content.replace(
/[\x00-\x09\x0B-\x1F\x7F-\x9F\xAD\u0378\u0379\u037F-\u0383\u038B\u038D\u03A2\u0528-\u0530\u0557\u0558\u0560\u0588\u058B-\u058E\u0590\u05C8-\u05CF\u05EB-\u05EF\u05F5-\u0605\u061C\u061D\u06DD\u070E\u070F\u074B\u074C\u07B2-\u07BF\u07FB-\u07FF\u082E\u082F\u083F\u085C\u085D\u085F-\u089F\u08A1\u08AD-\u08E3\u08FF\u0978\u0980\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FC-\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B55\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0C00\u0C04\u0C0D\u0C11\u0C29\u0C34\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5A-\u0C5F\u0C64\u0C65\u0C70-\u0C77\u0C80\u0C81\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0D01\u0D04\u0D0D\u0D11\u0D3B\u0D3C\u0D45\u0D49\u0D4F-\u0D56\u0D58-\u0D5F\u0D64\u0D65\u0D76-\u0D78\u0D80\u0D81\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E86\u0E89\u0E8B\u0E8C\u0E8E-\u0E93\u0E98\u0EA0\u0EA4\u0EA6\u0EA8\u0EA9\u0EAC\u0EBA\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F5-\u13FF\u169D-\u169F\u16F1-\u16FF\u170D\u1715-\u171F\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u180F\u181A-\u181F\u1878-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191D-\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE-\u1AFF\u1B4C-\u1B4F\u1B7D-\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C80-\u1CBF\u1CC8-\u1CCF\u1CF7-\u1CFF\u1DE7-\u1DFB\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u200B-\u200F\u202A-\u202E\u2060-\u206F\u2072\u2073\u208F\u209D-\u209F\u20BB-\u20CF\u20F1-\u20FF\u218A-\u218F\u23F4-\u23FF\u2427-\u243F\u244B-\u245F\u2700\u2B4D-\u2B4F\u2B5A-\u2BFF\u2C2F\u2C5F\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E3C-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u312E-\u3130\u318F\u31BB-\u31BF\u31E4-\u31EF\u321F\u32FF\u4DB6-\u4DBF\u9FCD-\u9FFF\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA698-\uA69E\uA6F8-\uA6FF\uA78F\uA794-\uA79F\uA7AB-\uA7F7\uA82C-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C5-\uA8CD\uA8DA-\uA8DF\uA8FC-\uA8FF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9E0-\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAA7C-\uAA7F\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F-\uABBF\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFE\uFDFF\uFE1A-\uFE1F\uFE27-\uFE2F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD-\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFFB\uFFFE\uFFFF]/g,
"",
);
content = content.replace(KipperParseFile.SPECIAL_CHARACTER_REPLACE_REGEX, "");

return new KipperParseFile(content, fileLocation, name, encoding as BufferEncoding);
}
Expand Down
87 changes: 87 additions & 0 deletions kipper/core/src/compiler/compile-result.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* The result of a {@link KipperCompiler} compilation.
* @since 0.0.3
*/
import { KipperProgramContext } from "./program-ctx";
import { TranslatedCodeLine } from "./const";
import { KipperError, KipperSyntaxError } from "../errors";

/**
* The result of a {@link KipperCompiler} compilation.
* @since 0.0.3
*/
export class KipperCompileResult {
private readonly _programCtx: KipperProgramContext | undefined;
private readonly _result: Array<TranslatedCodeLine> | undefined;
private readonly _syntaxErrors: Array<KipperSyntaxError> | undefined;

constructor(
fileCtx?: KipperProgramContext,
result?: Array<TranslatedCodeLine>,
syntaxErrors?: Array<KipperSyntaxError>,
) {
this._programCtx = fileCtx;
this._result = result;
this._syntaxErrors = syntaxErrors;
}

/**
* The program context for the compilation run, which stores the content of the program and meta-data.
*
* If undefined is returned that automatically indicates that the compilation failed due to a syntax error.
*/
public get programCtx(): KipperProgramContext | undefined {
return this._programCtx;
}

/**
* The result of the compilation in TypeScript form (every line is represented as an entry in the array).
*/
public get result(): Array<TranslatedCodeLine> | undefined {
return this._result;
}

/**
* Returns true, if the compilation was successful without errors.
* @since 0.10.0
*/
public get success(): boolean {
return this.result !== undefined;
}

/**
* The list of warnings that were raised during the compilation process.
*
* Warnings are non-fatal errors, which are raised when the compiler encounters a situation that it considers to
* be problematic, but which do not prevent the program from being compiled.
* @since 0.9.0
*/
public get warnings(): Array<KipperError> {
return this.programCtx?.warnings ?? [];
}

/**
* The list of errors that were raised during the compilation process.
*
* Errors are either syntax or compilation errors, which are raised when the compiler encounters a situation that it
* prevents it from continuing processing.
* @since 0.10.0
*/
public get errors(): Array<KipperError> {
// We can assume that either there will be compilation errors or syntax errors. If neither are present that means
// there is a bug, as such the usage of !! has a reason
return this.programCtx?.errors ?? this._syntaxErrors!!;
}

/**
* Creates a string from the compiled code that can be written to a file in a human-readable way.
* @param lineEnding The line ending for each line of the file. Default line ending is LF ('\n').
*/
public write(lineEnding: string = "\n"): string {
if (this.result === undefined) {
throw Error("Can not generate code for a failed compilation");
}

return this.result.map((line: TranslatedCodeLine) => line.join("") + lineEnding).join("");
}
}
Loading