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

Constructor Visibility #6885

Merged
merged 18 commits into from
Feb 17, 2016
Merged

Conversation

AbubakerB
Copy link
Contributor

Constructor Visibility

(This is a updated PR from #4174)

There wasn't any detailed proposal, so I'm just going to list what this PR implements.

1) Constructor Visibility

  1. A constructor can now have the private or protected keyword on its signature.
  2. All constructor overloads must be of the same visibility (i.e. all private, protected, or public)

2) Private Constructors

A class with a private constructor:

  1. Can only be instantiated within it's own class.
  2. Can only be extended within it's own class.

3) Protected Constructors

A class with a protected constructor:

  1. Can only be instantiated within it's own class.
  2. Can be extended.

4) Signature Assignability

  • A public, protected and private signature is assignable to a private signature.
  • A public and protected signature is assignable to a protected signature.
  • A public signature is assignable to public signature.

@msftclas
Copy link

msftclas commented Feb 3, 2016

Hi @AbubakerB, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!
You've already signed the contribution license agreement. Thanks!

The agreement was validated by Microsoft and real humans are currently evaluating your PR.

TTYL, MSBOT;

tests/cases/conformance/classes/constructorDeclarations/classConstructorAccessibility3.ts(26,1): error TS2322: Type 'typeof Foo' is not assignable to type 'typeof Baz'.
Cannot assign a 'public' constructor type to a 'protected' constructor type.
tests/cases/conformance/classes/constructorDeclarations/classConstructorAccessibility3.ts(27,1): error TS2322: Type 'typeof Bar' is not assignable to type 'typeof Baz'.
Cannot assign a 'public' constructor type to a 'protected' constructor type.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a one-directional relationship: public is assignable to protected and private, and protected is assignable to private (but none of the reverse)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

"category": "Error",
"code": 2674
},
"Cannot extend private class '{0}'.": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about:
Cannot extend a class '{0}'. Class constructor is marked as private.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}
return Ternary.False;
}
if (!constructorRelatedTo(sourceSignatures[0], targetSignatures[0], reportErrors)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it just comparing the first of each? Why was this change made?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only the first has to be checked because the rest must have identical visibility (it's an error for this not to be the case)

@AbubakerB
Copy link
Contributor Author

Is there anything left for me to do on this?

@RyanCavanaugh
Copy link
Member

@ahejlsberg - take a look?

@mhegazy
Copy link
Contributor

mhegazy commented Feb 11, 2016

Sorry for the delay, we will be discussing this in the TS design meeting tomorrow. should get back to you shortly after.

@mhegazy
Copy link
Contributor

mhegazy commented Feb 12, 2016

@AbubakerB, we have no more comments on the design. Please update for merge conflicts.

Just one comment a private constrictor should be visible within nested classes, we do not handle this for private and protected members today (see #7058).

const enclosingClass = enclosingClassDeclaration ? <InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingClassDeclaration)) : undefined;

// A private or protected constructor can only be instantiated within it's own class
if (declaringClass !== enclosingClass) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as noted in , we #7059, if here is not sufficient, it should be a while loop walking up, looking at all enclosing classes, so that something like this should be legal:

class B {
    private constructor() { }

    method() {
        class C {
            method() {
                new B(); // should be fine
            }
        }
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@AbubakerB
Copy link
Contributor Author

So now, a private and protected constructor can be instantiated and extended (already the case for protected) within the scope of its own class.

I also, hopefully, implemented it such that it'll be easy for #7058 😃

@AbubakerB
Copy link
Contributor Author

Build is failing due to gitignore ignoring the tests/**/*.js.
There's an open PR to fix this - awaiting it's merge.

@RyanCavanaugh
Copy link
Member

@AbubakerB thanks! This was a three-day weekend but we're back on Tuesday and should be able to take a last look.

@mhegazy
Copy link
Contributor

mhegazy commented Feb 16, 2016

@AbubakerB, one last merge conflict. but we should be good to go after that.

Conflicts:
	src/compiler/checker.ts
@AbubakerB
Copy link
Contributor Author

Sure :)

@mhegazy
Copy link
Contributor

mhegazy commented Feb 17, 2016

thanks!

mhegazy added a commit that referenced this pull request Feb 17, 2016
@mhegazy mhegazy merged commit bde20c4 into microsoft:master Feb 17, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Feb 17, 2016

#7058 should be a 1-line fix as well if you are interested.

@mhegazy
Copy link
Contributor

mhegazy commented Feb 17, 2016

@AbubakerB, Since you implemented this feature, do you mind adding some documentation at https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Classes.md?

@AbubakerB
Copy link
Contributor Author

Thanks guys ⛄ !

Sure, no problem

@myitcv
Copy link

myitcv commented Feb 17, 2016

This is a great change, thanks very much @AbubakerB and all involved

@wiredprairie
Copy link

Was point 4 regarding signature assignability completed as part of this PR? If so, is there documentation with an example? I couldn't find anything that seemed connected or related in the TypeScript Handbook.

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

Successfully merging this pull request may close these issues.

7 participants