Skip to content

Commit

Permalink
Removed some #[allow(...)] s (#97)
Browse files Browse the repository at this point in the history
* Also updated README and others
  • Loading branch information
kaleidawave committed Dec 19, 2023
1 parent 0881454 commit baa3a79
Show file tree
Hide file tree
Showing 60 changed files with 571 additions and 853 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/github-release.yml
Expand Up @@ -83,7 +83,7 @@ jobs:
mkdir artifacts
mv target/release/ezno${{ matrix.executable-extension }} artifacts/ezno-${{ needs.get-build-info.outputs.new-ezno-version }}-${{ matrix.platform_name }}${{ matrix.executable-extension }}
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: artifacts/*
Expand Down
5 changes: 3 additions & 2 deletions CONTRIBUTING.md
Expand Up @@ -48,15 +48,16 @@ cargo run -p ezno-parser --example lex path/to/file.ts
- Check source is valid with `cargo check --workspace`
- Check that code is formatted in accordance with the specification with `cargo fmt --all --check`
- Run all tests `cargo test --workspace --verbose`
- Use `cargo clippy -- --allow warnings` to find blocking lints

### The notify! macro

The checker crate has the `crate::utils::notify!` macro, which can be used to trace information when the `EZNO_DEBUG` environment variable is set.

## *Rules* for contributions

- Won't merge PRs that introduce new errors. However will merge PRs which pick up or find existing issues
- Code **must** be formatted with `cargo format` inline with the current format configuration
- Use `cargo clippy` as guidance for design but warning lints are not a blocker
- It **must** pass `cargo clippy -- --allow warnings`. In many cases adding `allow` to items is fine

## Oxc

Expand Down
38 changes: 17 additions & 21 deletions README.md
@@ -1,34 +1,30 @@
A JavaScript compiler and TypeScript checker written in Rust with a focus on static analysis and runtime performance.

You can *try* what it current [supports today](./checker/specification/specification.md) with `npx`
> [!IMPORTANT]
> Ezno is in active development and **currently does not support enough features to check existing projects**. Check out the [getting started guide](./checker/docs/getting-started.md) for experimenting with what it current [supports today](./checker/specification/specification.md).
```shell
npx ezno check file.ts
```

Or download the binary with `npm install ezno`, `cargo install ezno` or on [GitHub releases](https://github.com/kaleidawave/ezno/releases). [Or try it in Oxc](https://gist.github.com/kaleidawave/5dcb9ec03deef1161ebf0c9d6e4b88d8)!
Read about Ezno
- [Introducing Ezno](https://kaleidawave.github.io/posts/introducing-ezno/)
- [Ezno in '23](https://kaleidawave.github.io/posts/ezno-23/)
- [A preview of the checker](https://kaleidawave.github.io/posts/a-preview-of-the-checker/)

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

What Ezno is
- A type checker for JavaScript, usable as a library or with *optional* compiler infrastructure (parser, CLI, LSP, etc)
- Fully typed programs, guaranteeing type safety (as long as definitions are sound)
- Fully typed programs with guaranteed type safety (as long as definitions are sound)
- Types aimed at soundness and tracing for better static analysis
- A *imperative* type system, with event tracing and evaluating function side effects. Equivalent to an interpreter, but with types rather than values
- A collection of experiments of types. Some features work well, others are in the prototype stage. Some are specific to JavaScript, others could be applied to other dynamic languages
- A challenge to the status quo of DCE, type checking and compilation through deeper static analysis beyond syntax analysis
- A *imperative* type system that tracks and evaluates the side effects of functions and control flow structures. It is similar to an interpreter, but acts with types instead of *values*
- A collection of experiments of types. Many are being worked out and are in the prototype stage. Some of the new behaviors benefit JavaScript specifically and others could be applied to other languages
- A challenge to the status quo of type checking, optimisations and compilation through deeper static analysis beyond syntax analysis
- [A high level library](https://docs.rs/ezno-checker/latest/ezno_checker/) that allows [type checking to be added to other tools!](https://github.com/web-infra-dev/oxc/tree/main/crates/oxc_type_synthesis)
- Written in Rust
- [**Efficient**](https://kaleidawave.github.io/posts/a-preview-of-the-checker/#checking-performance)

What Ezno is not
- **eNZo, Z goes before the N** (pronounce as 'Fresno' without the 'fr') 😀
- 1:1 / parity with TSC, it has different behaviors **but** should work in existing projects using TSC (check out [stc](https://github.com/dudykr/stc) that is aimed at 1:1)
- A binary executable generator. It takes in JavaScript (or TS/Ezno superset) and does similar methods to traditional compilers, but at the end emits JavaScript. However the event intermediate representation could be used in the future to generate a lower level format
- Usable, [still a way to go until it can check actual programs](https://github.com/kaleidawave/ezno/milestone/1). See the [specification](./checker/specification/specification.md) for what is currently implemented in the checker

Read some more detailed posts
- [Introducing Ezno](https://kaleidawave.github.io/posts/introducing-ezno/)
- [Ezno '23](https://kaleidawave.github.io/posts/ezno-23/)
- [A preview of the checker](https://kaleidawave.github.io/posts/a-preview-of-the-checker/)
- **eNZo, the Z is in front of the N** (pronounce as 'Fresno' without the 'fr') 😀
- Be on parity with TSC or 1:1, it has some different behaviors **but** should work in existing projects using TSC (check out [stc](https://github.com/dudykr/stc) that is written in Rust and is aimed at replicating TSC)
- A binary executable generator. 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 representation

---

Expand All @@ -41,7 +37,7 @@ 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. | -->

Also checkout [oxc_type_synthesis](https://github.com/web-infra-dev/oxc/tree/main/crates/oxc_type_synthesis), a crate which allows using the type checker through [oxc](https://github.com/web-infra-dev/oxc/tree/main)!
Also checkout [oxc_type_synthesis](https://github.com/web-infra-dev/oxc/tree/main/crates/oxc_type_synthesis), a crate which allows using the type checker inside [oxc](https://github.com/web-infra-dev/oxc/tree/main)!

## Help contribute

Expand Down
18 changes: 18 additions & 0 deletions checker/docs/getting-started.md
@@ -0,0 +1,18 @@
Ezno is work in progress. It doesn't currently support all the features of JavaScript and TypeScript **but** it has a fairly large [specification of features that it supports today](../specification/specification.md). While it isn't worth it trying it on existing codebases ATM as it likely will blow up. You can try out the snippets in the specification and other small pieces of code today.

You can try the `check` command of ezno using `npx`

```shell
npx ezno check file.ts
```

Or download the binary with `npm install ezno`, `cargo install ezno` or on [GitHub releases](https://github.com/kaleidawave/ezno/releases).

You can use the `print_type` function to see the type of expressions.

```tsx
const x = 6;
print_type(x + 8)
```

If you find any unexpected exceptions, please leave an issue 😁
2 changes: 1 addition & 1 deletion checker/specification/specification.md
@@ -1,6 +1,6 @@
## Specification

See [./README.md](README.md) for details
See [./README.md](README.md) for details about how `specification.md` works

### Variables

Expand Down
6 changes: 2 additions & 4 deletions checker/src/behavior/assignments.rs
@@ -1,8 +1,6 @@
use source_map::{Span, SpanWithSource};
use source_map::SpanWithSource;

use crate::{
context::facts::Publicity, types::properties::PropertyKey, CheckingData, Environment, TypeId,
};
use crate::{context::facts::Publicity, types::properties::PropertyKey, TypeId};

use super::operations::{Logical, MathematicalAndBitwise};

Expand Down
11 changes: 4 additions & 7 deletions checker/src/behavior/constant_functions.rs
@@ -1,13 +1,10 @@
use source_map::{Span, SpanWithSource};
use source_map::SpanWithSource;

use crate::{
context::get_on_ctx,
subtyping::check_satisfies,
types::{
functions::SynthesisedArgument, poly_types::generic_type_arguments::TypeArgumentStore,
printing::debug_effects,
},
types::{poly_types::FunctionTypeArguments, printing::print_type, Type, TypeStore},
types::{functions::SynthesisedArgument, printing::debug_effects},
types::{printing::print_type, Type, TypeStore},
Constant, Environment, TypeId,
};

Expand Down Expand Up @@ -181,7 +178,7 @@ pub(crate) fn call_constant_function(
}
"set_prototype" => {
if let [first, second] = arguments {
let prototype = environment
let _prototype = environment
.facts
.prototypes
.insert(first.to_type().unwrap(), second.to_type().unwrap());
Expand Down
58 changes: 22 additions & 36 deletions checker/src/behavior/functions.rs
Expand Up @@ -4,16 +4,14 @@ use std::{
mem,
};

use source_map::{SourceId, Span, SpanWithSource};
use source_map::{SourceId, SpanWithSource};

use super::variables::VariableMutability;
use crate::{
context::{
environment::FunctionScope,
facts::{Facts, Publicity},
get_value_of_variable, CanReferenceThis, Context, ContextType, Syntax,
environment::FunctionScope, facts::Facts, get_value_of_variable, CanReferenceThis,
ContextType, Syntax,
},
events::{Event, RootReference},
events::RootReference,
types::{
self,
classes::ClassValue,
Expand All @@ -22,8 +20,7 @@ use crate::{
properties::{PropertyKey, PropertyValue},
Constructor, FunctionType, PolyNature, TypeStore,
},
ASTImplementation, CheckingData, Environment, FunctionId, ReadFromFS, Scope, Type, TypeId,
VariableId,
CheckingData, Environment, FunctionId, ReadFromFS, Scope, Type, TypeId, VariableId,
};

#[derive(Clone, Copy, Debug, Default, binary_serialize_derive::BinarySerializable)]
Expand Down Expand Up @@ -307,10 +304,10 @@ where
A: crate::ASTImplementation,
F: SynthesisableFunction<A>,
{
let is_async = behavior.is_async();
let is_generator = behavior.is_generator();
let _is_async = behavior.is_async();
let _is_generator = behavior.is_generator();

let (mut behavior, scope, constructor, location, expected_parameters, expected_return) =
let (mut behavior, scope, constructor, location, expected_parameters, _expected_return) =
match behavior {
FunctionRegisterBehavior::Constructor { super_type, prototype, properties } => (
FunctionBehavior::Constructor {
Expand Down Expand Up @@ -350,7 +347,7 @@ where
)
}
FunctionRegisterBehavior::ExpressionFunction {
expecting,
expecting: _,
is_async,
is_generator,
location,
Expand All @@ -373,7 +370,7 @@ where
None,
),
FunctionRegisterBehavior::StatementFunction {
hoisted,
hoisted: _,
is_async,
is_generator,
location,
Expand All @@ -394,23 +391,8 @@ where
None,
None,
),
FunctionRegisterBehavior::ObjectMethod { is_async, is_generator } => (
FunctionBehavior::Method {
is_async,
is_generator,
free_this_id: TypeId::ERROR_TYPE,
},
FunctionScope::MethodFunction {
free_this_type: TypeId::ERROR_TYPE,
is_async,
is_generator,
},
None,
None,
None,
None,
),
FunctionRegisterBehavior::ClassMethod { is_async, is_generator, super_type } => (
FunctionRegisterBehavior::ClassMethod { is_async, is_generator, super_type: _ }
| FunctionRegisterBehavior::ObjectMethod { is_async, is_generator } => (
FunctionBehavior::Method {
is_async,
is_generator,
Expand Down Expand Up @@ -510,7 +492,11 @@ where
// TODO what is the union, shouldn't it be the this_constraint?
*this_type = new_conditional_type;
}
FunctionScope::Constructor { extends, type_of_super, ref mut this_object_type } => {
FunctionScope::Constructor {
extends: _,
type_of_super: _,
ref mut this_object_type,
} => {
crate::utils::notify!("Setting 'this' type here");
if let Some((prototype, properties)) = constructor {
let new_this_object_type = types::create_this_before_function_synthesis(
Expand Down Expand Up @@ -558,7 +544,7 @@ where
let returned = if function.has_body() {
function.body(&mut function_environment, checking_data);
// Temporary move events to satisfy borrow checker
let mut events = mem::take(&mut function_environment.facts.events);
let events = mem::take(&mut function_environment.facts.events);

let returned = crate::events::helpers::get_return_from_events(
&mut events.iter(),
Expand Down Expand Up @@ -612,18 +598,18 @@ where
context.variable_names.extend(function_environment.variable_names);

// TODO temp ...
for (on, mut properties) in facts.current_properties {
for (on, properties) in facts.current_properties {
match context.facts.current_properties.entry(on) {
Entry::Occupied(mut occupied) => {}
Entry::Occupied(_occupied) => {}
Entry::Vacant(vacant) => {
vacant.insert(properties);
}
}
}

for (on, mut properties) in facts.closure_current_values {
for (on, properties) in facts.closure_current_values {
match context.facts.closure_current_values.entry(on) {
Entry::Occupied(mut occupied) => {}
Entry::Occupied(_occupied) => {}
Entry::Vacant(vacant) => {
vacant.insert(properties);
}
Expand Down

0 comments on commit baa3a79

Please sign in to comment.