Skip to content

Expose program diagnostics in cli main callback #1625

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

Merged
merged 3 commits into from
Jan 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ out/
raw/
.history
*.backup
.vscode
.vscode
.idea
1 change: 1 addition & 0 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ under the licensing terms detailed in LICENSE:
* Gabor Greif <[email protected]>
* Martin Fredriksson <[email protected]>
* forcepusher <[email protected]>
* Piotr Oleś <[email protected]>

Portions of this software are derived from third-party works licensed under
the following terms:
Expand Down
36 changes: 35 additions & 1 deletion cli/asc.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,38 @@ export interface MemoryStream extends OutputStream {
toString(): string;
}

/** A subset of Source interface from assemblyscript package */
export interface Source {
/** Normalized path with file extension. */
normalizedPath: string;
}

/** A subset of Range interface from assemblyscript package */
export interface Range {
/** Range start char index in a source */
start: number;
/** Range end char index in a source */
end: number;
source: Source;
}

/** A subset of DiagnosticMessage interface from assemblyscript package */
export interface DiagnosticMessage {
/** Message code. */
code: number;
/** Message category. */
category: number;
/** Message text. */
message: string;
/** Respective source range, if any. */
range: Range | null;
/** Related range, if any. */
relatedRange: Range | null;
}

/** A function that handles diagnostic */
type DiagnosticReporter = (diagnostic: DiagnosticMessage) => void;

/** Compiler options. */
export interface CompilerOptions {
/** Prints just the compiler's version and exits. */
Expand Down Expand Up @@ -157,6 +189,8 @@ export interface APIOptions {
writeFile?: (filename: string, contents: Uint8Array, baseDir: string) => void;
/** Lists all files within a directory. */
listFiles?: (dirname: string, baseDir: string) => string[] | null;
/** Handles diagnostic messages. */
reportDiagnostic?: DiagnosticReporter;
}

/** Convenience function that parses and compiles source strings directly. */
Expand All @@ -176,7 +210,7 @@ export function main(argv: string[], options: APIOptions, callback?: (err: Error
export function main(argv: string[], callback?: (err: Error | null) => number): number;

/** Checks diagnostics emitted so far for errors. */
export function checkDiagnostics(emitter: Record<string,unknown>, stderr?: OutputStream): boolean;
export function checkDiagnostics(emitter: Record<string,unknown>, stderr?: OutputStream, reportDiagnostic?: DiagnosticReporter): boolean;

/** An object of stats for the current task. */
export interface Stats {
Expand Down
47 changes: 44 additions & 3 deletions cli/asc.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,20 @@ function loadAssemblyScriptWasm(binaryPath) {
return exports;
}

/**
* Wraps object in WASM environment, returns untouched otherwise.
* @template T
* @param {number | T} ptrOrObj Pointer in WASM environment, object otherwise
* @param {typeof T} type Object type that provides wrap method in WASM environment
* @returns {T | null}
*/
function __wrap(ptrOrObj, type) {
if (typeof ptrOrObj === "number") {
return ptrOrObj === 0 ? null : type.wrap(ptrOrObj);
}
return ptrOrObj;
}

var assemblyscript, __newString, __getString, __pin, __unpin, __collect;

function loadAssemblyScript() {
Expand Down Expand Up @@ -702,7 +716,7 @@ exports.main = function main(argv, options, callback) {
});
}
}
var numErrors = checkDiagnostics(program, stderr);
var numErrors = checkDiagnostics(program, stderr, options.reportDiagnostic);
if (numErrors) {
const err = Error(numErrors + " parse error(s)");
err.stack = err.message; // omit stack
Expand Down Expand Up @@ -816,7 +830,7 @@ exports.main = function main(argv, options, callback) {
};
}
});
var numErrors = checkDiagnostics(program, stderr);
var numErrors = checkDiagnostics(program, stderr, options.reportDiagnostic);
if (numErrors) {
if (module) module.dispose();
const err = Error(numErrors + " compile error(s)");
Expand Down Expand Up @@ -1155,7 +1169,7 @@ function getAsconfig(file, baseDir, readFile) {
exports.getAsconfig = getAsconfig;

/** Checks diagnostics emitted so far for errors. */
function checkDiagnostics(program, stderr) {
function checkDiagnostics(program, stderr, reportDiagnostic) {
var numErrors = 0;
do {
let diagnosticPtr = assemblyscript.nextDiagnostic(program);
Expand All @@ -1167,6 +1181,33 @@ function checkDiagnostics(program, stderr) {
EOL + EOL
);
}
if (reportDiagnostic) {
const diagnostic = __wrap(diagnosticPtr, assemblyscript.DiagnosticMessage);
const range = __wrap(diagnostic.range, assemblyscript.Range);
const relatedRange = __wrap(diagnostic.relatedRange, assemblyscript.Range);
const rangeSource = range ? __wrap(range.source, assemblyscript.Source) : null;
const relatedRangeSource = relatedRange ? __wrap(relatedRange.source, assemblyscript.Source) : null;

reportDiagnostic({
message: __getString(diagnostic.message),
code: diagnostic.code,
category: diagnostic.category,
range: range ? {
start: range.start,
end: range.end,
source: rangeSource ? {
normalizedPath: __getString(rangeSource.normalizedPath)
} : null,
} : null,
relatedRange: relatedRange ? {
start: relatedRange.start,
end: relatedRange.end,
source: relatedRangeSource ? {
normalizedPath: __getString(relatedRangeSource.normalizedPath)
} : null
} : null
});
}
if (assemblyscript.isError(diagnosticPtr)) ++numErrors;
__unpin(diagnosticPtr);
} while (true);
Expand Down