Skip to content

Commit

Permalink
Add basic narrowing #122
Browse files Browse the repository at this point in the history
- Currently basic equality
  • Loading branch information
kaleidawave committed Jun 3, 2024
1 parent bdac106 commit 0ee0792
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 43 deletions.
40 changes: 40 additions & 0 deletions checker/specification/staging.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,43 @@
Currently implementing:

> This file is for work-in-progress and can help separating features that are being implemented to regressions
### Narrowing

#### Equality

```ts
declare let a: string;
if (a === "hi") {
a satisfies "hello"
}
```

- Expected "hello", found "hi"

#### Condition as a function

```ts
declare let a: string;

const equalsHi = (p: string) => p === "hi";

if (equalsHi(a)) {
a satisfies "hello"
}
```

- Expected "hello", found "hi"

#### Passed around

```ts
declare let a: string;

const b = a;
if (b === "hi") {
a satisfies "hello"
}
```

- Expected "hello", found "hi"
4 changes: 2 additions & 2 deletions checker/specification/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ mod specification {
// }

// TODO under cfg
// const SIMPLE_DTS: Option<&str> = Some(include_str!("../definitions/simple.d.ts"));
const SIMPLE_DTS: Option<&str> = None;
const SIMPLE_DTS: Option<&str> = Some(include_str!("../definitions/simple.d.ts"));
// const SIMPLE_DTS: Option<&str> = None;

/// Called by each test
fn check_errors(
Expand Down
38 changes: 0 additions & 38 deletions checker/specification/to_implement.md
Original file line number Diff line number Diff line change
Expand Up @@ -633,44 +633,6 @@ function optionalNumber(n: number | undefined): string {

- Cannot return string, found number | 2

#### Equality

```ts
declare let a: string;
if (a === "hi") {
a satisfies "hello"
}
```

- Expected "hello", found "hi"

#### Condition as a function

```ts
declare let a: string;

const equalsHi = (p: string) => p === "hi";

if (equalsHi(a)) {
a satisfies "hello"
}
```

- Expected "hello", found "hi"

#### Passed around

```ts
declare let a: string;

const b = a;
if (b === "hi") {
a satisfies "hello"
}
```

- Expected "hello", found "hi"

### Mapped types

#### Specialisation
Expand Down
4 changes: 4 additions & 0 deletions checker/src/context/information.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ pub struct LocalInformation {
/// *not quite the best place, but used in [`InformationChain`]*
pub(crate) object_constraints: HashMap<TypeId, TypeId>,

/// WIP narrowing
/// TODO how will chaining but not cycles work
pub(crate) narrowed_values: HashMap<TypeId, TypeId>,

/// For super calls etc
///
/// TODO not great that this has to be Option to satisfy Default
Expand Down
7 changes: 4 additions & 3 deletions checker/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1183,11 +1183,12 @@ pub(crate) fn get_value_of_variable(

let res = res.or_else(|| fact.variable_current_value.get(&on).copied());

// TODO WIP narrowing

// TODO in remaining info, don't loop again
if let Some(res) = res {
return Some(res);
let narrowed_value =
info.get_chain_of_info().find_map(|info| info.narrowed_values.get(&res).copied());

return Some(narrowed_value.unwrap_or(res));
}
}
None
Expand Down
6 changes: 6 additions & 0 deletions checker/src/features/conditional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ where
let mut truthy_environment = environment
.new_lexical_environment(Scope::Conditional { antecedent: condition, is_switch: None });

super::narrowing::narrow_based_on_expression(
condition,
&mut truthy_environment.info,
&checking_data.types,
);

let result = then_evaluate(&mut truthy_environment, checking_data);

let Context {
Expand Down
1 change: 1 addition & 0 deletions checker/src/features/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub mod exceptions;
pub mod functions;
pub mod iteration;
pub mod modules;
pub mod narrowing;
pub mod objects;
pub mod operations;
pub mod template_literal;
Expand Down
29 changes: 29 additions & 0 deletions checker/src/features/narrowing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use crate::{
features::operations::CanonicalEqualityAndInequality,
types::{Constructor, PolyNature, TypeStore},
LocalInformation, Type, TypeId,
};

/// TODO
/// - Ors and ands
/// - Restrictions
pub fn narrow_based_on_expression(
condition: TypeId,
into: &mut LocalInformation,
types: &TypeStore,
) {
let r#type = types.get_type_by_id(condition);
if let Type::Constructor(Constructor::CanonicalRelationOperator {
lhs,
operator: CanonicalEqualityAndInequality::StrictEqual,
rhs,
}) = r#type
{
if let Type::RootPolyType(PolyNature::Parameter { .. }) = types.get_type_by_id(*lhs) {
crate::utilities::notify!("lhs is {:?} with {:?}", lhs, types.get_type_by_id(*rhs));
}

// TODO reflexive ?
into.narrowed_values.insert(*lhs, *rhs);
}
}

0 comments on commit 0ee0792

Please sign in to comment.