Skip to content

Commit

Permalink
Implement support for setters (#138)
Browse files Browse the repository at this point in the history
Implements #39
  • Loading branch information
PatrickLaflamme authored May 17, 2024
1 parent 24fb424 commit 18564ca
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 3 deletions.
34 changes: 34 additions & 0 deletions checker/specification/specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -2894,3 +2894,37 @@ register(document.title)
```

- Argument of type string is not assignable to parameter of type Literal\<string\>

### Setters

#### Setters invocation invalid assignment

```ts
let a = 2;
const obj = {
set value(v) {
a = v;
}
}

let b: 80 = (obj.value = "some value");
let c: 80 = a;
```

- Type "some value" is not assignable to type 80
- Type "some value" is not assignable to type 80

#### Setters

```ts
let a = 2;
const obj = {
set value(v) {
a = v;
}
}

let b: 80 = (obj.value = 80);
let c: 80 = a;
```

4 changes: 3 additions & 1 deletion checker/src/context/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,9 @@ impl<'a> Environment<'a> {
Ok(match kind {
PropertyKind::Getter => Instance::GValue(result),
// TODO instance.property...?
PropertyKind::Generic | PropertyKind::Direct => Instance::RValue(result),
PropertyKind::Generic | PropertyKind::Direct | PropertyKind::Setter => {
Instance::RValue(result)
}
})
} else {
checking_data.diagnostics_container.add_error(TypeCheckError::PropertyDoesNotExist {
Expand Down
32 changes: 30 additions & 2 deletions checker/src/types/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
types::{
generics::generic_type_arguments::StructureGenericArguments, get_constraint, substitute,
FunctionType, GenericChain, GenericChainLink, ObjectNature, StructureGenerics,
SynthesisedArgument,
},
Constant, Environment, TypeId,
};
Expand All @@ -23,6 +24,7 @@ use super::{calling::CalledWithNew, Constructor, Type, TypeStore};
pub enum PropertyKind {
Direct,
Getter,
Setter,
/// TODO unsure
Generic,
}
Expand Down Expand Up @@ -704,6 +706,7 @@ pub(crate) fn set_property<E: CallCheckingBehavior>(
publicity,
under,
new,
types,
setter_position,
),
Logical::Or { .. } => todo!(),
Expand Down Expand Up @@ -750,6 +753,7 @@ fn run_setter_on_object<E: CallCheckingBehavior>(
publicity: Publicity,
under: &PropertyKey<'_>,
new: PropertyValue,
types: &mut TypeStore,
setter_position: Option<SpanWithSource>,
) {
match og {
Expand All @@ -770,8 +774,32 @@ fn run_setter_on_object<E: CallCheckingBehavior>(
});
}
PropertyValue::Getter(_) => todo!(),
PropertyValue::Setter(_setter) => {
todo!()
PropertyValue::Setter(setter) => {
// TODO: FunctionType.Call requires a SpanWithSource but here we have an
// Option<SpanWithSource>. However, updating this function to require a SpanWithSource
// would mean fairly broad changes.
let some_setter_position = setter_position.expect("Setter position is required!");
let arg = SynthesisedArgument {
position: some_setter_position,
spread: false,
value: match new {
PropertyValue::Value(type_id) => type_id,
_ => todo!(),
},
};
let _ = setter.call(
CalledWithNew::None,
ThisValue::Passed(on),
some_setter_position,
&[arg],
None,
// TODO structure generics
None,
environment,
behavior,
types,
false,
);
}
PropertyValue::Dependent { .. } => todo!(),
}
Expand Down

0 comments on commit 18564ca

Please sign in to comment.