winglang / wing

A programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡
https://winglang.io
Other
4.95k stars 194 forks source link

Cannot instantiate classes from preflight static methods #2583

Closed Chriscbr closed 10 months ago

Chriscbr commented 1 year ago

I tried this:

bring cloud;

class Foo {
  static makeFunc(): cloud.Function {
    return new cloud.Function(inflight (s: str): str => {
      return "hello world!";
    });
  }
}

let bar = Foo.makeFunc();

test "it works" {
  let result = bar.invoke("");
  assert(result == "hello world!");
}

This happened:

$ wing compile -t sim statics.w       
Cannot read properties of undefined (reading 'root')

I expected this:

It compiles and the test passes

Is there a workaround?

Change the method from a static method to a regular method

Component

Compiler

Wing Version

0.17.7

Wing Console Version

No response

Node.js Version

18.14.1

Platform(s)

MacOS

Anything else?

No response

Community Notes

Chriscbr commented 1 year ago

I think there are two problems here, one is the mechanical issue (creating a new class is translated into this.node.root.newAbstract(...), and "this" isn't available in static contexts), and the other is a design issue (if you create a preflight class in a static method, what scope does it get added to? do we need static methods to have an implicit "scope" parameter under the hood, a la #287?)

My guess is this is probably not P1 for beta

github-actions[bot] commented 1 year ago

Hi,

This issue hasn't seen activity in 60 days. Therefore, we are marking this issue as stale for now. It will be closed after 7 days. Feel free to re-open this issue when there's an update or relevant information to be added. Thanks!

github-actions[bot] commented 11 months ago

Hi,

This issue hasn't seen activity in 60 days. Therefore, we are marking this issue as stale for now. It will be closed after 7 days. Feel free to re-open this issue when there's an update or relevant information to be added. Thanks!

Chriscbr commented 10 months ago

@skyrpex mentions he would like this capability for creating static factories:

pub class ContainersFactory {
    pub static create(): types.IContainers {
        let driver = util.tryEnv("CONTAINERS_DRIVER") ?? "docker";
        if driver == "docker" {
            return new docker.DockerContainers();
        } elif driver == "fly" {
            return new fly.FlyContainers(
                token: util.env("CONTAINERS_FLY_TOKEN"),
                orgSlug: util.env("CONTAINERS_FLY_ORG_SLUG"),
                region: util.tryEnv("CONTAINERS_FLY_REGION"),
            );
        } else {
            throw "Unknown CONTAINERS_DRIVER: ${driver}";
        }
    }
}
skyrpex commented 10 months ago

From the example above, I'd expect docker.DockerContainers or fly.FlyContainers to inherit the scope where ContainersFactory.create() was called from.

skorfmann commented 10 months ago

was trying something similar

    pub static add(name: str, value: str) {
        new aws.ssmParameter.SsmParameter(
            name: Util.key(name),
            type: "String",
            value: value,
        ) as Util.key(name);
    }
monadabot commented 10 months ago

Congrats! :rocket: This was released in Wing 0.48.12.