Skip to content

Implement calls to 'super()' #445

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

Merged
merged 12 commits into from
Jan 31, 2019
Merged

Implement calls to 'super()' #445

merged 12 commits into from
Jan 31, 2019

Conversation

dcodeIO
Copy link
Member

@dcodeIO dcodeIO commented Jan 30, 2019

Passes a simple test and implements quite a few related checks. Still possible that not every single edge case is covered, but having this now and fixing any bugs as we go appears reasonable, considering that class support is still in the works anyway.

@MaxGraey
Copy link
Member

It seems this fixing also #375, #245, #199 and #187.

@MaxGraey
Copy link
Member

MaxGraey commented Jan 30, 2019

Hmm, I'm not sure about first statement call rule. It make sense only if this or super keyword using before super call. But should be valid for this case:

constructor(a: i32) {
   var arg = a + 1;
   super(arg);
}

@dcodeIO
Copy link
Member Author

dcodeIO commented Jan 30, 2019

Yeah, there are the ALLOCATES and CONDITIONALLY_ALLOCATES flags in flows for that. Will probably need a CALLS_SUPER one as well then to do it this way. TS also has

    "A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties.": {
        "category": "Error",
        "code": 2376
    },

Maybe we could use

    "'super' must be called before accessing 'this' in the constructor of a derived class.": {
        "category": "Error",
        "code": 17009
    },

@MaxGraey
Copy link
Member

MaxGraey commented Jan 30, 2019

Maybe we could use

Yeah

@dcodeIO
Copy link
Member Author

dcodeIO commented Jan 30, 2019

Seems

constructor(a: i32) {
   var arg = a + 1;
   super(arg);
}

is rejected by TS, but now legalized in AS with the flow changes above. Still needs a check when doing super.something that super has already been called.

@MaxGraey
Copy link
Member

Hmm, really? That's interesting...

@MaxGraey
Copy link
Member

Yeah, but PR for fixing this in TS already exists: microsoft/TypeScript#29374

@dcodeIO
Copy link
Member Author

dcodeIO commented Jan 30, 2019

Yeah, I remember that this limitation annoyed me in the past. Especially given the dynamic nature of JavaScript this seems like an arbitrary restriction (not directly related to AS, where such a restriction might actually make sense).

@MaxGraey
Copy link
Member

MaxGraey commented Jan 30, 2019

As I know this legal in any OOP typed languages may be except C#. It seems typescript just missing this ability. But this should be fix soon

@dcodeIO
Copy link
Member Author

dcodeIO commented Jan 30, 2019

One thing that's still particularly off is that derived classes currently inherit their super class's fields, and thus initialize super fields in each derived constructor, which is odd. Instead, each constructor should initialize its own class's fields right after bubbling up the entire prototype chain, calling all the overloaded constructors sequentially. One reason why this doesn't yet work is that classes that don't have an explicit constructor also don't have a wasm function for it (their field initialization is instead inlined), which we should change by generating actual constructor functions for them that we can call.

@MaxGraey
Copy link
Member

Makes sense. But it look like not simple. May be better leave this for other PR?

@dcodeIO
Copy link
Member Author

dcodeIO commented Jan 31, 2019

Sure, makes sense to leave that for a separate PR. One example what's not possible until then:

class A {
  a: i32 = 1;
  constructor() {
    assert(this.a == 1); // == 0, is uninitialized, and remains so
  }
}

class B extends A {
  a: i32 = 3;
  constructor() {
    super();
  }
}

new B();

This is currently prevented by rejecting duplicate field names.

@dcodeIO
Copy link
Member Author

dcodeIO commented Jan 31, 2019

Similarly:

class A {
  a: i32 = 1;
  constructor() {}
}

class B extends A {
  b: i32 = 2;
}

var b = new B();
assert(b.b == 2); // == 0, uninitialized due to A#constructor being used, with no B#constructor

Not directly related to super(), but part of the same problem.

@dcodeIO
Copy link
Member Author

dcodeIO commented Jan 31, 2019

Merging, continuing in a separate PR.

@dcodeIO dcodeIO merged commit 75328f3 into master Jan 31, 2019
@robrohan
Copy link

robrohan commented Feb 5, 2019

New to the assemblyscript project, and coming here because I hit this bug: #245 Does this mean that OO stuff in general isn't supported by assembly script at the moment?

@MaxGraey
Copy link
Member

MaxGraey commented Feb 5, 2019

@robrohan Basic OO supports except virtual methods. Issue which you mentioned is not yet fixed. If you add some params to basic constructor it would work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants