Skip to content

Nested private and protected class members #7123

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 5 commits into from
Mar 24, 2016

Conversation

AbubakerB
Copy link
Contributor

Fixes #7058

Allows classes to access private and protected member of parent (enclosed) classes.

@msftclas
Copy link

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;

if (!enclosingClass || !hasBaseType(enclosingClass, declaringClass)) {
error(node, Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, symbolToString(prop), typeToString(declaringClass));
return false;
if (!isNodeWithinClass(node, typeClassDeclaration)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

i think this should be a loop walking up and repeate the check for each enclosing class.

I would consider adding a function like forEachEnclosingClass and wrapp the exisitng consitions to the call to of that function:

e.g.: if (!enclosingClass || ! forEachEnclosingClass(node, enclosingClass=> hasBaseType(enclosingClass, declaringClass))) {

where forEachEnclosingClass is defined as:

    function forEachEnclosingClass<T>(node:Node, callback: (node:Node) => T):T {
        let result: T;

        while (true) {
            node = getContainingClass(node);
            if (!node) break;
            if (result = callback(node)) break;
        }

        return result;
    }

and isNodeWithinClass can be defined as:

    function isNodeWithinClass(node: Node, classDeclaration: ClassLikeDeclaration) {
        return !!forEachEnclosingClass(node, n => n === classDeclaration);
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But in the case of

class Base {
    protected x: string;
    method() {
        var b: Base;
    }
}

class Derived1 extends Base {
    method1() {
        var b: Base;
        var d1: Derived1;

        b.x;            // Currently an Error
        d1.x;           // Currently OK
    }
}

b.x won't be an error anymore, right? Now that the
declared class = Base
Enclosed class = Derived1
Derived1 has base Base - so b.x won't be an error anymore.

Or did i misunderstand you?

Copy link
Contributor

Choose a reason for hiding this comment

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

that should not change. it should be 1. accessed in a protected class, and 2. through an instance of the protected class. the change is only about the first condition, not the second.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, yes, I see, my bad.

One last comment. Should I rewrite isNodeWithinClass to be Type oriented instead of ClassLikeDeclaration oriented?

hasBaseType() takes InterfaceType, and most other places that call isNodeWithinClass gets the Type's ClassLikeDeclaration (which could be skipped if it was Type oriented).
If we make
isNodeWithinClass(node: Node, classDeclaration: ClassLikeDeclaration) into isNodeWithinType(node: Node, type: Type) (or maybe a better name),
and convert the getContainingClass to a Type within forEachEnclosingClass<T>()

Or should we keep it as-is and convert the ClassLikeDeclaration to a Type within the callback of forEachEnclosingClass<T>()?

Copy link
Contributor

Choose a reason for hiding this comment

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

keeping it as a ClassLikeDeclarations seems appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry been quite busy lately.
Done :)

@AbubakerB
Copy link
Contributor Author

@mhegazy are there anymore comments on this?

@AbubakerB AbubakerB closed this Mar 22, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Mar 22, 2016

ooh, sorry for the delay. this fell off my radar. i can update it and merge it manually.

@mhegazy
Copy link
Contributor

mhegazy commented Mar 24, 2016

Thanks again for the PR, and sorry for the delay.

@mhegazy mhegazy merged commit e1be0ff into microsoft:master Mar 24, 2016
@AbubakerB
Copy link
Contributor Author

No problem. I thought it was a bit stale so I closed it... my bad.

And thanks! ⛄

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
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.

Private/Protected class members not accessible in nested classes
3 participants