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

Proxy support #33

Open
kaleidawave opened this issue Jun 16, 2023 · 4 comments
Open

Proxy support #33

kaleidawave opened this issue Jun 16, 2023 · 4 comments
Labels
checking Issues around checking good-second-issue Moderately difficult issue

Comments

@kaleidawave
Copy link
Owner

As much as want it not to exist. I guess it needs to be supported.

Steps

  • Add a variant to ObjectNature which is Proxy { trap: TypeId }
  • Modify get_property and set_property to call a function if on has this structure

TODO

  • Way to annotate something that creates a proxy...
@kaleidawave kaleidawave added good-second-issue Moderately difficult issue checking Issues around checking labels Jun 16, 2023
@PatrickLaflamme
Copy link
Contributor

The more I investigate implementing this, the more it grows in scope.

Are we interested in ensuring that the Proxy handler returns values that respect the type definition of the proxied type? For example, we could implement a Proxy like the following:

type SomeType = {
    a: number
}

const handler = {
    get(_target: SomeClass, _propKey: keyof SomeType) {
        return "invalid"
    }
}

const proxiedType = new Proxy<SomeType>({ a: 4 }, handler) 

const b: number = proxiedType.a

The above proxy is invalid because the get method always returns a string, but the proxied type has only one property which is a number. However, even the typescript type checking as it exists today doesn't fail at compilation. From what I can tell, we could do something similar to what we did in #138 and run the handler methods where invoked to make sure it returns the type we think it will. It's also worth noting that there are many traps in the Proxy type that can intercept just about any usage of the proxied type (eg. get, set, in, new, construct etc.)

@kaleidawave
Copy link
Owner Author

Hmm yes looking at this there is quite a lot to cover. I think the first step would to be get

const p = new Proxy({}, { get(target, key) { return key });
print_type(p.something)

to print "Something". Then from there setters and calling should be good for a MVP.

I think the last time I attempted it there were some pieces missing in the checker and I couldn't create a SpecialObject::Proxy type never mind start using it.

Will have another look today, I think it might be possible now. I will try and get the foundation wired up, so others can tie up and test the trap logic.


Type checking is harder: how can we know that p satisfies { a: "a", b: "b" }? Subtyping doesn't run side effects and constant logic, so it might be more strict about what can be passed (aka disallow some some proxies that are technically valid at runtime).

@kaleidawave
Copy link
Owner Author

Hey @PatrickLaflamme, I have added some of the Proxy constructor stuff for #146 so this looks good to start on if you want to give it a crack.

Firstly Type::SpecialObject(SpecialObject::Proxy(..)) is being created successfully by the constructor

image

So for the parts left to implement:

I have created a branch for the property access logic here

crate::context::MissingOrToCalculate::Proxy(Proxy { .. }) => {
todo!(); // #33
// TODO pass down
}

You basically want to get the trap type of handler and then call it with all the relevant information. As you implemented setters in #138 you should be proficient.

Once you can get the example above working in a PR

const p = new Proxy({}, { get(target, key) { return key });
print_type(p.something)

then setting and calling should be okay.

Can ignore other traps for the first iteration.

I have some ideas for subtyping but they can also be worked out later.

@kaleidawave
Copy link
Owner Author

75% done in #157

See new tests: https://github.com/kaleidawave/ezno/blob/main/checker/specification/specification.md#proxy

There are still some "traps" that are not implemented. Only get and set are done for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
checking Issues around checking good-second-issue Moderately difficult issue
Projects
None yet
Development

No branches or pull requests

2 participants