Skip to content

Class-body directive prologue is incompatible with class fields #21

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

Closed
domenic opened this issue Mar 27, 2019 · 18 comments
Closed

Class-body directive prologue is incompatible with class fields #21

domenic opened this issue Mar 27, 2019 · 18 comments

Comments

@domenic
Copy link
Member

domenic commented Mar 27, 2019

Discovered in TC39 today.

class Foo {
  "hide implementation";

   constructor() { }
   bar() { }
}

declares a public field named "hide implementation". Whee!

Solutions

Omit directive prologue in class bodies

We could just omit this capability. Then developers would have several more-awkward options, such as:

"hide implementation";

class Foo {
   constructor() { }
   bar() { }
}

// Anything else in the source file also gets implementation-hidden, which might be bad.

or

let Foo = (() => {
  "hide implementation";
  return class Foo {
     constructor() { }
     bar() { }
  };
})();

or

class Foo {
   constructor() {
     "hide implementation";
   }
   bar() {
     "hide implementation";
   }

   // repeat as needed
}

Don't use directive prologues

Basically #13.

Something else clever

TBD.

@ljharb

This comment has been minimized.

@nicolo-ribaudo
Copy link
Member

class Foo extends Bar ("hide implementation") {
}

That is a function call

@ljharb
Copy link
Member

ljharb commented Mar 27, 2019

lol oops, not so clever after all

@domenic
Copy link
Member Author

domenic commented Mar 27, 2019

In particular, if we're going to add any new syntax, I think it should be either:

@ljharb

This comment has been minimized.

@domenic

This comment has been minimized.

@ljharb

This comment has been minimized.

@rbuckton
Copy link

rbuckton commented Apr 4, 2019

What about a different prologue for hiding class implementations, specified in the constructor:

class Foo {
  constructor() {
    "hide class implementation";
  }
}

@ljharb
Copy link
Member

ljharb commented Apr 5, 2019

I like that - considering the constructor function is what class actually produces, this seems like a neat solution to the problem (and answers the question of what would happen if i put the pragma in the constructor with the current proposal)

@rbuckton
Copy link

rbuckton commented Apr 5, 2019

I would imagine "hide implementation"; in the constructor would only hide the body of the constructor itself, while "hide class implementation"; would hide the body of the entire class.

@ljharb
Copy link
Member

ljharb commented Apr 5, 2019

Although now that i think about it, it’d be weird if the constructor pragma impacted static methods :-/

@michaelficarra
Copy link
Member

@rbuckton The constructor does not always appear first (or even early) in the class body. I wouldn't want to be unable to tell that we're in a special kind of context until the whole class body is read.

@rbuckton
Copy link

rbuckton commented Apr 5, 2019

@ljharb: Possibly sounds like https://github.com/tc39/proposal-class-static-block#readme could be an option:

class Foo {
  static {
    "hide implementation";
  }
}

@michaelficarra: True, but there's still value in the simple solution.

@rbuckton
Copy link

rbuckton commented Apr 5, 2019

Another option could be this:

class Foo {
  ("hide implementation");
}

This keeps the pragma at the top of the class and doesn't conflict with public fields, for the added cost of two characters.

@michaelficarra
Copy link
Member

We're no longer interested in adding new directive placements.

@ljharb
Copy link
Member

ljharb commented Oct 10, 2019

@michaelficarra so what's the plan for hiding the implementation of the constructor/class body? a pragma inside the constructor?

@michaelficarra
Copy link
Member

@ljharb If you want to affect only the constructor, put it in the constructor. If you want it to apply to all of the methods of the class, wrap the class in an IIFE or just put the directive in the enclosing scope if you don't mind the over-application.

@ljharb
Copy link
Member

ljharb commented Oct 10, 2019

Gotcha - i ask because the constructor’s implementation is the entire class body, so hiding it is hiding the class (altho not necessarily all its methods)

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

No branches or pull requests

5 participants