Skip to content

Commit

Permalink
Few parser fixes (#158)
Browse files Browse the repository at this point in the history
- Fix capitalisation in `ForLoopStatementInitialiser`
- Fix for #154
- Renames and fix for #161
- Fix for code_blocks_to_script & performance action
- Add array pretty printing
- Fix spread being allowed not at the end of destructuring (required checker changes)
- Not sure why fuzzing broke?
- Add `LTSI::new_under` public method
- Change `cargo-fuzz` install to fix issue
  • Loading branch information
kaleidawave authored Jun 24, 2024
1 parent 5191329 commit 245d530
Show file tree
Hide file tree
Showing 41 changed files with 1,121 additions and 632 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/clippy-rustfmt-fix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Run automated fixes on current branch

on:
workflow_dispatch

env:
CACHE_PATHS: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: ${{ env.CACHE_PATHS }}
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

- name: Run automated fixes
run: |
cargo clippy --fix
cargo fmt
- name: Commit
run: |
git add .
git commit -m "Run clippy --fix & formatting"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git push
16 changes: 8 additions & 8 deletions .github/workflows/performance-and-size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,23 @@ jobs:
shell: bash
run: |
# Generate a file which contains everything that Ezno currently implements
cargo run -p ezno-parser --example code_blocks_to_script ./checker/specification/specification.md ./demo.ts
echo "::info::Finished file generation"
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.ts | jq ".[0].Code")
LINES_OF_CODE=$(scc -c --no-cocomo -f json demo.tsx | jq ".[0].Code")
echo "### Checking
\`\`\`shell
$(hyperfine -i './target/release/ezno check demo.ts')
$(hyperfine -i './target/release/ezno check demo.tsx')
\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "<details>
<summary>Input</summary>
\`\`\`ts
\`\`\`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.ts)
// 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
Expand All @@ -77,7 +77,7 @@ jobs:
<summary>Diagnostics</summary>
\`\`\`
$(./target/release/ezno check demo.ts --timings --max-diagnostics all 2>&1 || true)
$(./target/release/ezno check demo.tsx --timings --max-diagnostics all 2>&1 || true)
\`\`\`
</details>
" >> $GITHUB_STEP_SUMMARY
Expand Down
18 changes: 12 additions & 6 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -223,20 +223,26 @@ jobs:
rustup install nightly
rustup default nightly
- uses: brndnmtthws/rust-action-cargo-binstall@v1
# Current `cargo-fuzz` is broken: https://github.com/kaleidawave/ezno/pull/158#issuecomment-2171431210
# However `cargo install --git ...` does work below
# - uses: brndnmtthws/rust-action-cargo-binstall@v1
# if: steps.changes.outputs.parser == 'true'
# with:
# packages: cargo-fuzz

- name: Install cargo-fuzz
if: steps.changes.outputs.parser == 'true'
with:
packages: cargo-fuzz

run: cargo install --git https://github.com/rust-fuzz/cargo-fuzz.git

- name: Run fuzzing
env:
SHORT_CIRCUIT: true
if: steps.changes.outputs.parser == 'true'
run: |
if ${{ env.SHORT_CIRCUIT }}; then
cargo fuzz run -s none ${{ matrix.fuzz-target }} -- -timeout=10 -use_value_profile=1 -max_total_time=120
CARGO_TARGET_DIR=../../target cargo fuzz run -s none ${{ matrix.fuzz-target }} -- -timeout=10 -use_value_profile=1 -max_total_time=120
else
cargo fuzz run -s none ${{ matrix.fuzz-target }} -- -timeout=10 -use_value_profile=1 -max_total_time=300 -fork=1 -ignore_crashes=1
CARGO_TARGET_DIR=../../target cargo fuzz run -s none ${{ matrix.fuzz-target }} -- -timeout=10 -use_value_profile=1 -max_total_time=300 -fork=1 -ignore_crashes=1
if test -d fuzz/artifacts; then
find fuzz/artifacts -type f -print -exec xxd {} \; -exec cargo fuzz fmt -s none module_roundtrip_structured {} \;; false;
Expand Down
4 changes: 2 additions & 2 deletions checker/specification/specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ const b: string = a
```ts
let a = 2
a = "hello world"
let b: boolean = a
a satisfies number
```

- Type "hello world" is not assignable to type boolean
- Expected number, found "hello world"

#### Variable references does not exist

Expand Down
13 changes: 6 additions & 7 deletions checker/src/context/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ impl<'a> Environment<'a> {
}
}
}
Assignable::ObjectDestructuring(assignments) => {
Assignable::ObjectDestructuring(members, _spread) => {
debug_assert!(matches!(operator, AssignmentKind::Assign));

let rhs = A::synthesise_expression(
Expand All @@ -395,13 +395,13 @@ impl<'a> Environment<'a> {
);

self.assign_to_object_destructure_handle_errors(
assignments,
members,
rhs,
assignment_span,
checking_data,
)
}
Assignable::ArrayDestructuring(assignments) => {
Assignable::ArrayDestructuring(members, _spread) => {
debug_assert!(matches!(operator, AssignmentKind::Assign));

let rhs = A::synthesise_expression(
Expand All @@ -412,7 +412,7 @@ impl<'a> Environment<'a> {
);

self.assign_to_array_destructure_handle_errors(
assignments,
members,
rhs,
assignment_span,
checking_data,
Expand Down Expand Up @@ -463,14 +463,14 @@ impl<'a> Environment<'a> {
checking_data,
assignment_span,
),
Assignable::ObjectDestructuring(assignments) => self
Assignable::ObjectDestructuring(assignments, _spread) => self
.assign_to_object_destructure_handle_errors(
assignments,
rhs,
assignment_span,
checking_data,
),
Assignable::ArrayDestructuring(assignments) => self
Assignable::ArrayDestructuring(assignments, _spread) => self
.assign_to_array_destructure_handle_errors(
assignments,
rhs,
Expand Down Expand Up @@ -549,7 +549,6 @@ impl<'a> Environment<'a> {
checking_data,
);
}
AssignableObjectDestructuringField::Spread(_, _) => todo!(),
}
}

Expand Down
12 changes: 7 additions & 5 deletions checker/src/features/assignments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use super::operations::{LogicalOperator, MathematicalAndBitwise};
/// A single or multiple items to assign to
pub enum Assignable<A: crate::ASTImplementation> {
Reference(Reference),
ObjectDestructuring(Vec<AssignableObjectDestructuringField<A>>),
ArrayDestructuring(Vec<AssignableArrayDestructuringField<A>>),
ObjectDestructuring(Vec<AssignableObjectDestructuringField<A>>, Option<AssignableSpread<A>>),
ArrayDestructuring(Vec<AssignableArrayDestructuringField<A>>, Option<AssignableSpread<A>>),
}

/// TODO Can this use lifetimes?
Expand All @@ -29,12 +29,14 @@ pub enum AssignableObjectDestructuringField<A: crate::ASTImplementation> {
default_value: Option<Box<A::Expression<'static>>>,
position: SpanWithSource,
},
/// `{ ...x }`
Spread(Assignable<A>, SpanWithSource),
}

pub struct AssignableSpread<A: crate::ASTImplementation>(
pub Box<Assignable<A>>,
pub SpanWithSource,
);

pub enum AssignableArrayDestructuringField<A: crate::ASTImplementation> {
Spread(Assignable<A>, SpanWithSource),
Name(Assignable<A>, Option<Box<A::Expression<'static>>>),
Comment { content: String, is_multiline: bool, position: SpanWithSource },
None,
Expand Down
1 change: 1 addition & 0 deletions checker/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![doc = include_str!("../README.md")]
#![allow(deprecated, clippy::new_without_default, clippy::too_many_lines, clippy::result_unit_err)]
#![warn(clippy::must_use_candidate)]

pub mod context;
pub mod diagnostics;
Expand Down
60 changes: 31 additions & 29 deletions checker/src/synthesis/assignments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
context::Environment,
features::assignments::{
Assignable, AssignableArrayDestructuringField, AssignableObjectDestructuringField,
Reference,
AssignableSpread, Reference,
},
synthesis::expressions::synthesise_expression,
types::properties::{PropertyKey, Publicity},
Expand All @@ -35,11 +35,11 @@ impl SynthesiseToAssignable for LHSOfAssignment {
checking_data: &mut CheckingData<T, super::EznoParser>,
) -> Assignable<super::EznoParser> {
match self {
LHSOfAssignment::ObjectDestructuring(items, _) => {
synthesise_object_to_reference(items, environment, checking_data)
LHSOfAssignment::ObjectDestructuring { members, spread, position: _ } => {
synthesise_object_to_reference(members, spread, environment, checking_data)
}
LHSOfAssignment::ArrayDestructuring(items, _) => {
synthesise_array_to_reference(items, environment, checking_data)
LHSOfAssignment::ArrayDestructuring { members, spread, position: _ } => {
synthesise_array_to_reference(members, spread, environment, checking_data)
}
LHSOfAssignment::VariableOrPropertyAccess(access) => Assignable::Reference(
synthesise_access_to_reference(access, environment, checking_data),
Expand All @@ -55,11 +55,11 @@ impl SynthesiseToAssignable for VariableField {
checking_data: &mut CheckingData<T, super::EznoParser>,
) -> Assignable<super::EznoParser> {
match self {
VariableField::Object(items, _) => {
synthesise_object_to_reference(items, environment, checking_data)
VariableField::Object { members, spread, position: _ } => {
synthesise_object_to_reference(members, spread, environment, checking_data)
}
VariableField::Array(items, _) => {
synthesise_array_to_reference(items, environment, checking_data)
VariableField::Array { members, spread, position: _ } => {
synthesise_array_to_reference(members, spread, environment, checking_data)
}
VariableField::Name(ident) => Assignable::Reference(match ident {
VariableIdentifier::Standard(name, position) => Reference::Variable(
Expand All @@ -79,6 +79,7 @@ fn synthesise_object_to_reference<
U: SynthesiseToAssignable + parser::DestructuringFieldInto,
>(
items: &[parser::WithComment<parser::ObjectDestructuringField<U>>],
spread: &Option<parser::SpreadDestructuringField<U>>,
environment: &mut Environment,
checking_data: &mut CheckingData<T, super::EznoParser>,
) -> Assignable<super::EznoParser> {
Expand All @@ -98,16 +99,6 @@ fn synthesise_object_to_reference<
position: position.with_source(environment.get_source()),
}
}
parser::ObjectDestructuringField::Spread(name, position) => {
AssignableObjectDestructuringField::Spread(
SynthesiseToAssignable::synthesise_to_assignable(
name,
environment,
checking_data,
),
position.with_source(environment.get_source()),
)
}
parser::ObjectDestructuringField::Map {
from,
annotation: _,
Expand Down Expand Up @@ -135,6 +126,16 @@ fn synthesise_object_to_reference<
}
})
.collect(),
spread.as_ref().map(|spread| {
AssignableSpread(
Box::new(SynthesiseToAssignable::synthesise_to_assignable(
&*spread.0,
environment,
checking_data,
)),
spread.1.with_source(environment.get_source()),
)
}),
)
}

Expand All @@ -143,23 +144,14 @@ fn synthesise_array_to_reference<
U: SynthesiseToAssignable + parser::DestructuringFieldInto,
>(
items: &[parser::WithComment<parser::ArrayDestructuringField<U>>],
spread: &Option<parser::SpreadDestructuringField<U>>,
environment: &mut Environment,
checking_data: &mut CheckingData<T, super::EznoParser>,
) -> Assignable<super::EznoParser> {
Assignable::ArrayDestructuring(
items
.iter()
.map(|item| match item.get_ast_ref() {
parser::ArrayDestructuringField::Spread(name, position) => {
AssignableArrayDestructuringField::Spread(
SynthesiseToAssignable::synthesise_to_assignable(
name,
environment,
checking_data,
),
position.with_source(environment.get_source()),
)
}
parser::ArrayDestructuringField::Name(name, _, default_value) => {
AssignableArrayDestructuringField::Name(
SynthesiseToAssignable::synthesise_to_assignable(
Expand All @@ -180,6 +172,16 @@ fn synthesise_array_to_reference<
parser::ArrayDestructuringField::None => AssignableArrayDestructuringField::None,
})
.collect(),
spread.as_ref().map(|spread| {
AssignableSpread(
Box::new(SynthesiseToAssignable::synthesise_to_assignable(
&*spread.0,
environment,
checking_data,
)),
spread.1.with_source(environment.get_source()),
)
}),
)
}

Expand Down
12 changes: 6 additions & 6 deletions checker/src/synthesis/classes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ pub(super) fn synthesise_class_declaration<
match &member.on {
ClassMember::Method(false, method) => {
let publicity = match method.name.get_ast_ref() {
ParserPropertyKey::Ident(
ParserPropertyKey::Identifier(
_,
_,
parser::property_key::PublicOrPrivate::Private,
Expand All @@ -133,7 +133,7 @@ pub(super) fn synthesise_class_declaration<
}
};

let internal_marker = if let (true, ParserPropertyKey::Ident(name, _, _)) =
let internal_marker = if let (true, ParserPropertyKey::Identifier(name, _, _)) =
(is_declare, method.name.get_ast_ref())
{
get_internal_function_effect_from_decorators(
Expand Down Expand Up @@ -179,7 +179,7 @@ pub(super) fn synthesise_class_declaration<
}
ClassMember::Property(false, property) => {
let publicity = match property.key.get_ast_ref() {
ParserPropertyKey::Ident(
ParserPropertyKey::Identifier(
_,
_,
parser::property_key::PublicOrPrivate::Private,
Expand Down Expand Up @@ -256,15 +256,15 @@ pub(super) fn synthesise_class_declaration<
match &member.on {
ClassMember::Method(true, method) => {
let publicity_kind = match method.name.get_ast_ref() {
ParserPropertyKey::Ident(
ParserPropertyKey::Identifier(
_,
_,
parser::property_key::PublicOrPrivate::Private,
) => Publicity::Private,
_ => Publicity::Public,
};

let internal_marker = if let (true, ParserPropertyKey::Ident(name, _, _)) =
let internal_marker = if let (true, ParserPropertyKey::Identifier(name, _, _)) =
(is_declare, method.name.get_ast_ref())
{
get_internal_function_effect_from_decorators(
Expand Down Expand Up @@ -321,7 +321,7 @@ pub(super) fn synthesise_class_declaration<
}
ClassMember::Property(true, property) => {
let publicity_kind = match property.key.get_ast_ref() {
ParserPropertyKey::Ident(
ParserPropertyKey::Identifier(
_,
_,
parser::property_key::PublicOrPrivate::Private,
Expand Down
Loading

0 comments on commit 245d530

Please sign in to comment.