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

Improvements to properties + intrinsic types #157

Merged
merged 20 commits into from
Aug 8, 2024
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
67 changes: 47 additions & 20 deletions .github/workflows/performance-and-size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,6 @@ jobs:
with:
packages: hyperfine

# For displaying line count in file
- name: Download scc
run: |
mkdir scc
cd scc
gh release download v3.1.0 -R boyter/scc -p '*Linux_x86_64.tar.gz' -O scc.tar.gz
tar -xf scc.tar.gz
chmod +x scc
pwd >> $GITHUB_PATH
env:
GH_TOKEN: ${{ github.token }}

- name: Build Ezno
run: cargo build --release
env:
Expand All @@ -52,8 +40,6 @@ jobs:
# Generate a file which contains everything that Ezno currently implements
cargo run -p ezno-parser --example code_blocks_to_script ./checker/specification/specification.md --comment-headers --out ./demo.tsx

LINES_OF_CODE=$(scc -c --no-cocomo -f json demo.tsx | jq ".[0].Code")

echo "### Checking
\`\`\`shell
$(hyperfine -i './target/release/ezno check demo.tsx')
Expand All @@ -62,33 +48,74 @@ jobs:
echo "<details>
<summary>Input</summary>

> Code generated from specification.md. this is not meant to accurately represent a program but instead give an idea for how it scales across all the type checking features
\`\`\`tsx
// $LINES_OF_CODE lines of TypeScript generated from specification.md
// this is not meant to accurately represent a program but instead give an idea
// for how it scales across all the type checking features
$(cat ./demo.tsx)
\`\`\`
</details>
" >> $GITHUB_STEP_SUMMARY

echo "::info::Wrote code to summary"

command_output=$(./target/release/ezno check demo.tsx --timings --max-diagnostics all 2>&1 || true)
diagnostics=""; statistics=""; found_splitter=false;

while IFS= read -r line; do
if [[ "$line" == "---"* ]]; then found_splitter=true;
elif [[ "$found_splitter" == false ]]; then diagnostics+="$line"$'\n';
else statistics+="$line"$'\n'; fi
done <<< "$command_output"

echo "<details>
<summary>Diagnostics</summary>

\`\`\`
$(./target/release/ezno check demo.tsx --timings --max-diagnostics all 2>&1 || true)
$diagnostics
\`\`\`
</details>

<details>
<summary>Statistics</summary>

\`\`\`
$statistics
\`\`\`
</details>
" >> $GITHUB_STEP_SUMMARY

- name: Run checker performance w/staging
shell: bash
if: github.ref_name != 'main'
run: |
echo "::group::Running all"

cat ./checker/specification/specification.md ./checker/specification/staging.md > all.md
cargo run -p ezno-parser --example code_blocks_to_script all.md --comment-headers --out ./all.tsx

./target/release/ezno check all.tsx --timings || true
echo "::endgroup::"

- name: Run checker performance on large file
shell: bash
run: |
echo "::group::Running large"

cat ./checker/specification/specification.md > main.md
cargo run -p ezno-parser --example code_blocks_to_script all.md --comment-headers --out ./code.tsx
for i in {1..10}; do
cat ./code.tsx >> large.tsx
done

./target/release/ezno check large.tsx --timings --max-diagnostics 0 || true
echo "::endgroup::"

- name: Run parser, minfier/stringer performance
shell: bash
run: |
strings=(
"https://esm.sh/v128/[email protected]/es2022/react-dom.mjs"
"https://esm.sh/v135/[email protected]/es2022/typescript.mjs"
)
# Currently broken "https://esm.sh/v135/[email protected]/es2022/typescript.mjs"

for url in "${strings[@]}"; do
curl -sS $url > input.js
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ node_modules
/TODO.txt
checker/specification/Cargo.lock
checker/definitions/es5.d.ts
.grit
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Now in the `ezno` directory, `cargo run` should show the CLI.
You can run just the checker with

```shell
cargo run -p ezno-checker --example run-checker path/to/file.ts
cargo run -p ezno-checker --example run_checker path/to/file.ts
```

> [!TIP]
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,20 @@ js-sys = "0.3"
tsify = "0.4.5"

[workspace.lints.clippy]
all = "deny"
pedantic = "deny"
all = { level = "deny", priority = -1 }
pedantic = { level = "deny", priority = -1 }
cast_precision_loss = "warn"
cast_possible_truncation = "warn"
cast_sign_loss = "warn"
default_trait_access = "allow"
missing_errors_doc = "allow"
missing_panics_doc = "allow"
implicit_hasher = "allow"
module_name_repetitions = "allow"
too_many_lines = "allow"
new_without_default = "allow"
result_unit_err = "allow"
thread_local_initializer_can_be_made_const = "allow"
implicit_hasher = "allow"

[profile.dev]
debug = false
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
A JavaScript compiler and TypeScript checker written in Rust with a focus on static analysis and runtime performance.

> [!IMPORTANT]
> Ezno is in active development and **does not currently support enough features to check existing projects**. Check out the [getting started guide](./checker/documentation/getting-started.md) for experimenting with what it [currently supports](./checker/specification/specification.md).
> Ezno is in active development and **does not currently support enough features to check existing projects** (see [blocking issues](https://github.com/kaleidawave/ezno/labels/blocking)). Check out the [getting started guide](./checker/documentation/getting-started.md) for experimenting with what it [currently supports](./checker/specification/specification.md).

<!-- ![project lines of code](https://projects.kaleidawave.workers.dev/project/ezno/badge) -->

Expand All @@ -21,7 +21,7 @@ What Ezno is not
- Be on parity with TSC or 1:1, it has some different behaviors **but** should work in existing projects using TSC
- Faster as a means to serve large codebases. Cut out bloat and complex code first!
- Smarter as a means to allow more *dynamic patterns*. Keep things simple!
- A binary executable compiler. It takes in JavaScript (or a TypeScript or Ezno superset) and does similar processes to traditional compilers, but at the end emits JavaScript. However, in the future, it _could_ generate a lower level format using its event (side-effect) representation.
- A binary executable compiler. It takes in JavaScript (or a TypeScript or Ezno superset) and does similar processes to traditional compilers, but at the end emits JavaScript. However, in the future, it *could* generate a lower level format using its event (side-effect) representation.

Read more about Ezno (in chronological order)
- [Introducing Ezno](https://kaleidawave.github.io/posts/introducing-ezno/)
Expand All @@ -40,7 +40,6 @@ This project is a workspace consisting of a few crates:
<!-- | ezno-web-framework | ![](https://projects.kaleidawave.workers.dev/project/framework/badge) | Visitors and code generation for JSX and reactive expression transformations. | -->
<!-- | ezno-lsp | ![](https://projects.kaleidawave.workers.dev/project/framework/badge) | Visitors and code generation for JSX and reactive expression transformations. | -->


## Help contribute

Check out [good first issues]((https://github.com/kaleidawave/ezno/issues?q=is%3Aopen+label%3Agood-first-issue%2Cfeedback-needed)) and comment on discussions! Feel free to ask questions on parts of the code of the checking implementation.
Expand Down
4 changes: 3 additions & 1 deletion checker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,12 @@ tsify = "0.4.5"
# TODO needs unfixed change in source-map
wasm-bindgen = "=0.2.89"


[dependencies.parser]
path = "../parser"
optional = true
version = "0.1.5"
features = ["extras"]
package = "ezno-parser"

[dev-dependencies]
match_deref = "0.1.1"
Binary file modified checker/definitions/internal.ts.d.bin
Binary file not shown.
97 changes: 50 additions & 47 deletions checker/definitions/overrides.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
@Constant
declare function debug_type_independent(t: any): void;

// Eventually this will be merged with existing TS es5.d.ts files but for now is the standalone see #121

interface ImportEnv {
[key: string]: string | undefined;
[key: string]: string;
}

interface ImportMeta {
Expand All @@ -14,7 +11,7 @@ interface ImportMeta {
}

declare class Array<T> {
[index: number]: T | undefined;
[index: number]: T;

length: number;

Expand All @@ -33,8 +30,7 @@ declare class Array<T> {
return undefined
} else {
const value = this[--this.length];
// TODO this currently breaks value?
// delete this[this.length];
delete this[this.length];
return value
}
}
Expand Down Expand Up @@ -101,35 +97,6 @@ declare class Array<T> {
return false
}

// fill(value: T, start: number = 0, end = this.length): this {
// // TODO
// return this
// }

// reduce<U>(cb: (acc: U, t: T, i?: number) => U, initial?: U): U {
// const { length } = this;
// let acc = initial ?? this[0];
// let i: number = typeof initial === "undefined" ? 1 : 0;;
// while (i < length) {
// const value = this[i];
// acc = cb(acc, value, i++);
// }
// return acc;
// }

// includes(searchElement: T, fromIndex?: number): boolean {
// const { length } = this;
// // TODO this is currently broken
// let i: number = fromIndex ?? 0;
// while (i < length) {
// const value = this[i++];
// if (value === searchElement) {
// return true
// }
// }
// return false
// }

join(joiner: string = ","): string {
const { length } = this;
let i: number = 1;
Expand Down Expand Up @@ -173,22 +140,28 @@ declare class Math {
static sqrt(x: number): number;
@Constant
static cbrt(x: number): number;
@Constant
static log(x: number): number;

// TODO newer method
@Constant
static trunc(x: number): number;

static PI: 3.141592653589793
static E: 2.718281828459045

@InputOutput
static random(): number;
}

@Primitive("string")
declare class String {
[index: number]: string | undefined;
[index: number]: string;

@Constant
toUpperCase(): string;
toUpperCase(this: string): string;
@Constant
toLowerCase(): string;
toLowerCase(this: string): string;

get length(): number;

Expand Down Expand Up @@ -294,11 +267,11 @@ declare class SyntaxError extends Error {

declare class JSON {
// TODO any temp
@Constant("json:parse", SyntaxError)
@Constant("JSON:parse", SyntaxError)
static parse(input: string): any;

// TODO any temp
@Constant("json:stringify")
@Constant("JSON:stringify")
static stringify(input: any): string;
}

Expand All @@ -308,26 +281,46 @@ declare class Function {

declare class Symbols {
// TODO temp
iterator: 199
static iterator: unique symbol "iterator"
}

declare class Proxy {
@Constant("proxy:constructor")
constructor(obj: any, cb: any);
}

// Copied from `es5.d.ts`. Could this be an or
// TODO string keys temp because parser broke
interface PropertyDescriptor {
value?: any;
["get" ? (): any;
["set" ? (v: any): void;

writable?: boolean;
configurable?: boolean;
enumerable?: boolean;
}

declare class Object {
@Constant
static setPrototypeOf(on: object, to: object): object;

@Constant
static getPrototypeOf(on: object): object | null;

// static create(prototype: object): object {
// const n = {};
// Object.setProtoTypeOf(n, prototype);
// return n
// }
@Constant
static freeze(on: object): object;

@Constant
static isFrozen(on: object): boolean;

// TODO defineProperties via body (not constant)
@Constant
static defineProperty(on: object, property: string, discriminator: PropertyDescriptor): boolean;

// TODO getOwnPropertyDescriptors via body (not constant)
@Constant
static getOwnPropertyDescriptor(on: object, property: string): PropertyDescriptor;

static keys(on: { [s: string]: any }): Array<string> {
const keys: Array<string> = [];
Expand All @@ -353,6 +346,14 @@ declare class Object {
return entries
}

// TODO multiple arguments
static assign(target: object, source: object): object {
for (const key in source) {
target[key] = source[key]
}
return target
}

// static fromEntries(iterator: any): object {
// const obj = {};
// for (const item of iterator) {
Expand Down Expand Up @@ -415,6 +416,8 @@ declare function debug_context(): void;
declare function context_id(): void;
@Constant
declare function context_id_chain(): void;
@Constant
declare function debug_type_independent(t: any): void;

// A function, as it should be!
@Constant
Expand Down
Loading