Skip to content

Implement Missing Property of Type this #14140

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 15 commits into from
Mar 2, 2017

Conversation

aozgaa
Copy link
Contributor

@aozgaa aozgaa commented Feb 17, 2017

Fixes #14104

@DanielRosenwasser
Copy link
Member

Is this a work in progress? I don't see a test for the original case that I posted.

@aozgaa
Copy link
Contributor Author

aozgaa commented Feb 23, 2017

Can you take a look, @mhegazy, @DanielRosenwasser ?

return getTypeFromTypeNode(<TypeNode>node);
let typeFromTypeNode = getTypeFromTypeNode(<TypeNode>node);

if (typeFromTypeNode && isExpressionWithTypeArgumentsInClassImplementsClause(node)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this the right thing to check for to find out if we are in an implements clause?

return getTypeFromTypeNode(<TypeNode>node);
let typeFromTypeNode = getTypeFromTypeNode(<TypeNode>node);

if (typeFromTypeNode && isExpressionWithTypeArgumentsInClassImplementsClause(node)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this the right place to do the this instantiation or should I moce this logic into getTypeFromTypeNode?

I created a circularity (ie: stack overflow) when I moved it even further into the checker (namely by doing the instantiation at getTypeFromTypeReference).

Copy link
Contributor

Choose a reason for hiding this comment

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

you can use isHeritageClauseElementIdentifier

if (typeFromTypeNode && isExpressionWithTypeArgumentsInClassImplementsClause(node)) {
const containingClass = getContainingClass(node);
const classType = getTypeOfNode(containingClass) as InterfaceType;
typeFromTypeNode = getTypeWithThisArgument(typeFromTypeNode, classType.thisType);
Copy link
Contributor

Choose a reason for hiding this comment

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

consider refactoring to have one check higher up, and then handle extends/implements accordinglly

@mhegazy
Copy link
Contributor

mhegazy commented Mar 1, 2017

            if (isHeritageClauseElementIdentifier(node)) {
                const expressionWithTypearguments = <ExpressionWithTypeArguments>getAncestor(node, SyntaxKind.ExpressionWithTypeArguments);
                const classDeclaration = tryGetClassExtendingExpressionWithTypeArguments(expressionWithTypearguments);
                if (classDeclaration) {
                    // A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the
                    // extends clause of a class. We handle that case here.
                    return getBaseTypes(<InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(classDeclaration)))[0];
                }
                else {
                    return getTypeFromTypeNode(<TypeNode>node);
                }
            }

@aozgaa
Copy link
Contributor Author

aozgaa commented Mar 2, 2017

It doesn't look like we can consolidates the checks as we discussed offline because the call to isPartOfExpression (between the original isPartOfTypeNode and isExpressionWithTypeArgumentsInClassExtendsClause calls) captures the case where the node is the LHS expression of of an ExpressionWithTypeArguments.*
Is this the desired behavior?

If so, we can't do the isHeritageClauseElementIdentifier check too early.

* One test case that failed is when we have class C extends null {...} because with the change the type we get for null is undefined whereas before it was the null type.

In general, if we have class D extends A.B.C<T> {...}, if the node we are given is

  1. A,
  2. B,
  3. C,
  4. A.B,
  5. A.B.C,
  6. A.B.C<T>,

in which cases do we want to instantiate the this type? My intuition is that we should only do it in case (6) and possibly also (3) and/or (5).

EDIT: clarification

@aozgaa aozgaa merged commit e9fd831 into microsoft:master Mar 2, 2017
@aozgaa aozgaa deleted the ImplementMissingThis branch March 3, 2017 00:48
@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.

7 participants