mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-24 18:12:28 +03:00
adds README, extends error object
This commit is contained in:
parent
aadd998665
commit
0aa6eabb0c
6
.github/workflows/wasm.yml
vendored
6
.github/workflows/wasm.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: WASM Tests
|
||||
name: WASM
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
@ -14,14 +14,14 @@ env:
|
||||
|
||||
jobs:
|
||||
test-wasm-parser:
|
||||
name: Test WASM on ${{ matrix.os }}
|
||||
name: Test on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: wasm
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macOS-latest, windows-latest, ubuntu-latest]
|
||||
os: [windows-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1459,6 +1459,7 @@ dependencies = [
|
||||
"leo-errors",
|
||||
"leo-parser",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
|
@ -84,15 +84,23 @@ impl BacktracedError {
|
||||
|
||||
code
|
||||
}
|
||||
|
||||
/// Gets a unique error identifier.
|
||||
pub fn error_code(&self) -> String {
|
||||
format!(
|
||||
"E{error_type}{code_identifier:0>3}{exit_code:0>4}",
|
||||
error_type = self.error_type,
|
||||
code_identifier = self.code_identifier,
|
||||
exit_code = self.exit_code,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for BacktracedError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let error_message = format!(
|
||||
"Error [E{error_type}{code_identifier:0>3}{exit_code:0>4}]: {message}",
|
||||
error_type = self.error_type,
|
||||
code_identifier = self.code_identifier,
|
||||
exit_code = self.exit_code,
|
||||
"Error [{error_code}]: {message}",
|
||||
error_code = self.error_code(),
|
||||
message = self.message,
|
||||
);
|
||||
|
||||
|
@ -70,6 +70,11 @@ impl FormattedError {
|
||||
pub fn exit_code(&self) -> i32 {
|
||||
self.backtrace.exit_code()
|
||||
}
|
||||
|
||||
/// Returns an error identifier.
|
||||
pub fn error_code(&self) -> String {
|
||||
self.backtrace.error_code()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FormattedError {
|
||||
@ -96,10 +101,8 @@ impl fmt::Display for FormattedError {
|
||||
let underlined = underline(self.span.col_start, self.span.col_stop);
|
||||
|
||||
let error_message = format!(
|
||||
"Error [E{error_type}{code_identifier:0>3}{exit_code:0>4}]: {message}",
|
||||
error_type = self.backtrace.error_type,
|
||||
code_identifier = self.backtrace.code_identifier,
|
||||
exit_code = self.backtrace.exit_code,
|
||||
"Error [{error_code}]: {message}",
|
||||
error_code = self.error_code(),
|
||||
message = self.backtrace.message,
|
||||
);
|
||||
|
||||
|
@ -42,14 +42,17 @@ macro_rules! create_errors {
|
||||
#[inline(always)]
|
||||
fn exit_code(&self) -> i32 {
|
||||
match self {
|
||||
Self::FormattedError(formatted) => {
|
||||
formatted.exit_code()
|
||||
},
|
||||
Self::BacktracedError(backtraced) => {
|
||||
backtraced.exit_code()
|
||||
}
|
||||
Self::FormattedError(formatted) => formatted.exit_code(),
|
||||
Self::BacktracedError(backtraced) => backtraced.exit_code()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn error_code(&self) -> String {
|
||||
match self {
|
||||
Self::FormattedError(formatted) => formatted.error_code(),
|
||||
Self::BacktracedError(backtraced) => backtraced.error_code()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -19,6 +19,9 @@ pub trait LeoErrorCode: Sized {
|
||||
/// Returns the error's exit code for the program.
|
||||
fn exit_code(&self) -> i32;
|
||||
|
||||
/// Returns the prefixed error identifier.
|
||||
fn error_code(&self) -> String;
|
||||
|
||||
/// Returns the error's exit code mask, as to avoid conflicts.
|
||||
fn exit_code_mask() -> i32;
|
||||
|
||||
|
@ -109,6 +109,24 @@ pub enum LeoError {
|
||||
}
|
||||
|
||||
impl LeoError {
|
||||
/// Implement error code for each type of Error. For the unsupported use a default value.
|
||||
pub fn error_code(&self) -> String {
|
||||
use LeoError::*;
|
||||
|
||||
match self {
|
||||
AsgError(error) => error.error_code(),
|
||||
AstError(error) => error.error_code(),
|
||||
CliError(error) => error.error_code(),
|
||||
CompilerError(error) => error.error_code(),
|
||||
ImportError(error) => error.error_code(),
|
||||
InputError(_error) => Default::default(), // TODO migrate me, or not cause we want inputs to have 0 deps.
|
||||
PackageError(error) => error.error_code(),
|
||||
ParserError(error) => error.error_code(),
|
||||
SnarkVMError(_error) => Default::default(), // TODO update once snarkvm implments a global top level error similar to LeoError.
|
||||
StateError(error) => error.error_code(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Implment exit code for each type of Error, even the ones that don't have one.
|
||||
pub fn exit_code(&self) -> i32 {
|
||||
use LeoError::*;
|
||||
|
@ -45,8 +45,12 @@ path = "../ast-passes"
|
||||
version = "1.0"
|
||||
features = [ "derive" ]
|
||||
|
||||
[dependencies.serde_json]
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.wasm-bindgen]
|
||||
version = "0.2"
|
||||
features = [ "serde-serialize" ]
|
||||
|
||||
# Crate metadata
|
||||
|
||||
|
34
wasm/README.md
Normal file
34
wasm/README.md
Normal file
@ -0,0 +1,34 @@
|
||||
# Leo WASM
|
||||
|
||||
<!-- [![Crates.io](https://img.shields.io/crates/v/leo-wasm.svg?color=neon)](https://crates.io/crates/leo-wasm) -->
|
||||
[![Authors](https://img.shields.io/badge/authors-Aleo-orange.svg)](../AUTHORS)
|
||||
[![License](https://img.shields.io/badge/License-GPLv3-blue.svg)](./LICENSE.md)
|
||||
|
||||
This directory contains WASM bindings for the Leo compiler.
|
||||
|
||||
## Limitations
|
||||
|
||||
Currently, WASM target of the compiler supports parsing and canonicalization stages.
|
||||
|
||||
## API
|
||||
|
||||
This is a list of the supported methods and their signatures.
|
||||
|
||||
### leo.parse
|
||||
|
||||
Method takes in a Leo program as string and returns JSON string with the resulting AST or throws a LeoError.
|
||||
|
||||
```ts
|
||||
export interface LeoError {
|
||||
text: string, // Full error text (including span)
|
||||
code: string, // Leo error identifier (e.g. "EPAR0370005")
|
||||
exitCode: number // Exit code for an error (e.g. 370005)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} program Leo program text to parse and produce AST
|
||||
* @return {String} Resulting AST as a JSON string.
|
||||
* @throws {LeoError} When program contains invalid Leo code.
|
||||
*/
|
||||
export function parse(program: string): string;
|
||||
```
|
@ -18,12 +18,21 @@
|
||||
// which is not wasm compatible. All compiler passes (such as TypeInference)
|
||||
|
||||
use leo_ast::AstPass;
|
||||
use leo_errors::LeoError;
|
||||
|
||||
use serde_json::json;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(typescript_custom_section)]
|
||||
const TS_APPEND_CONTENT: &'static str = r#"
|
||||
export interface LeoError { text: string, code: string, exitCode: number }
|
||||
"#;
|
||||
|
||||
/// Publicly accessible method.
|
||||
/// Parse the code and return an AST as JSON or an error object. asd
|
||||
#[wasm_bindgen(method, catch)]
|
||||
pub fn parse(program: &str) -> Result<String, JsValue> {
|
||||
Ok(parse_program(program).map_err(|err| JsValue::from_str(&err.to_string()))?)
|
||||
Ok(parse_program(program).map_err(error_to_value)?)
|
||||
}
|
||||
|
||||
/// Parse the program and pass the Canonicalization phase;
|
||||
@ -35,3 +44,13 @@ fn parse_program(program: &str) -> leo_errors::Result<String> {
|
||||
|
||||
Ok(ast)
|
||||
}
|
||||
|
||||
/// Make a pretty-print JS object for the thrown error.
|
||||
fn error_to_value(err: LeoError) -> JsValue {
|
||||
JsValue::from_serde(&json!({
|
||||
"error": err.to_string(),
|
||||
"code": err.error_code(),
|
||||
"exitCode": err.exit_code()
|
||||
}))
|
||||
.expect("Unable to create an error object from JSON")
|
||||
}
|
||||
|
53
wasm/tests/package-lock.json
generated
53
wasm/tests/package-lock.json
generated
@ -1,59 +1,8 @@
|
||||
{
|
||||
"name": "parser-wasm-tests",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 2,
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "parser-wasm-tests",
|
||||
"version": "0.1.0",
|
||||
"license": "GNU",
|
||||
"dependencies": {
|
||||
"@types/js-yaml": "^4.0.3",
|
||||
"@types/node": "^16.9.4",
|
||||
"js-yaml": "^4.1.0",
|
||||
"typescript": "^3.9.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/js-yaml": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz",
|
||||
"integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg=="
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "16.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.4.tgz",
|
||||
"integrity": "sha512-KDazLNYAGIuJugdbULwFZULF9qQ13yNWEBFnfVpqlpgAAo6H/qnM9RjBgh0A0kmHf3XxAKLdN5mTIng9iUvVLA=="
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "3.9.10",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
|
||||
"integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.2.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/js-yaml": {
|
||||
"version": "4.0.3",
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as parser from '../../pkg/leo_wasm';
|
||||
import * as leo from '../../pkg/leo_wasm';
|
||||
import * as yaml from 'js-yaml';
|
||||
|
||||
// Path to the parser tests folder
|
||||
@ -100,7 +100,7 @@ function test(filePath: string, outFile: string|null): TestResult[] {
|
||||
// and collect outputs to later compare to saved .out expectations.
|
||||
for (const sample of samples) {
|
||||
try {
|
||||
outputs.push(JSON.parse(parser.parse(sample))); // Parser outputs JSON
|
||||
outputs.push(JSON.parse(leo.parse(sample))); // Parser outputs JSON
|
||||
if (expectation === Expectation.Fail) { // If expectation was Fail and it passed
|
||||
mismatches.push({
|
||||
filePath,
|
||||
@ -110,6 +110,10 @@ function test(filePath: string, outFile: string|null): TestResult[] {
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
console.log(error.code);
|
||||
console.log(error.exitCode);
|
||||
|
||||
outputs.push(error.toString());
|
||||
if (expectation === Expectation.Pass) { // If expectation was Pass and it failed
|
||||
mismatches.push({
|
||||
|
Loading…
Reference in New Issue
Block a user