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

Make getNameOfDeclaration public #15958

Merged
merged 5 commits into from
May 22, 2017
Merged

Conversation

sandersn
Copy link
Member

Move getNameOfDeclaration to the non-internal namespace in utilities.

@sandersn sandersn requested review from mhegazy and a user May 19, 2017 20:25

export function getNameOfDeclaration(declaration: Declaration): DeclarationName {
if (!declaration) {
return undefined;
Copy link

Choose a reason for hiding this comment

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

Mark return type as DeclarationName | undefined.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

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

How does getNameOfDeclaration differ from getDeclarationName? When should you prefer one over the other?

return undefined;
case SpecialPropertyAssignmentKind.ExportsProperty:
if (lhs.kind === SyntaxKind.Identifier) {
return (lhs as PropertyAccessExpression).name;
Copy link

Choose a reason for hiding this comment

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

lhs as Identifier

Copy link
Member Author

Choose a reason for hiding this comment

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

The answer to both your comments is that this code is closely couple to the result of getSpecialPropertyAssignmentKind, which returns ExportsProperty in two cases.

In this case, the code is wrong and should be checking lhs.expression.kind. I will fix it.

return (lhs as PropertyAccessExpression).name;
}
else {
return ((lhs as PropertyAccessExpression).expression as PropertyAccessExpression).name;
Copy link

Choose a reason for hiding this comment

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

How do you know lhs.expression is itself a PropertyAccessExpression?

Copy link
Member Author

Choose a reason for hiding this comment

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

If the special property assignment kind is ExportsProperty, lhs is known to be a PropertyAccessExpression and lhs.expression is either an Identifier or PropertyAccessExpression.

Copy link
Member Author

Choose a reason for hiding this comment

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

Furthermore, in the case that lhs.expression is Identifier, lhs.expression is "exports" and the name is lhs.name (from exports.blah = ...). If it's a property access expression, then lhs.expression.expression is "module", lhs.expression.name is "exports", and lhs.name is the name we're interested in (from module.exports.blah = ...).

So actually this code is wrong too. Changing it doesn't break any tests either, which is very suspicious. I don't think our checkJs coverage is very good.

@sandersn
Copy link
Member Author

getDeclarationName is only used in transforms, and in fact delegates to getNameOfDeclaration.

Other differences:
getDeclarationName always generates a name; a new one if none exists. If one already exists, it clones it and sets some EmitFlags.

getDeclarationName should really only be accessible to transforms, but it's actually available to anything in the entire ts namespace. I'm not what is the best way to indicate that getNameOfDeclaration is the simpler function to be used most of the time.

@ghost
Copy link

ghost commented May 19, 2017

There are actually 2 getDeclarationName functions, I was looking at the one in binder.ts.
😱

@sandersn
Copy link
Member Author

That one also delegates to getNameOfDeclaration and also always returns a name, but instead of generating a name for unnamed things, asserts that computed property names are constant (or well-known) and returns well known names for everything else (eg "exports=").

@ghost
Copy link

ghost commented May 19, 2017

Seems like the one in factory.ts is the wrongly named one since it always creates a new node rather than merely getting one. But that one's public too so it would be a breaking change to rename.

@sandersn
Copy link
Member Author

OK, your comments resulted in a considerably cleaned up and fixed getNameOfDeclaration. Unfortunately, they also expose the fact that we have almost no code coverage for special assignment kinds.

`getNameOfDeclaration` now handles a lot of the special property
assignment kinds in `getDeclarationName`
@sandersn
Copy link
Member Author

I think this is ready to go in. getNameOfDeclaration actually handles more cases than it ever will see, because the binder has special code paths for prototype property assignments and exports property assignments that end up delegating to normal property assignments. But since it's publicly accessible now, I think that it should correctly retrieve the name for all kinds of special property assignments.

I did get rid of some now-dead special-case code in the binder.

@sandersn sandersn merged commit 515a0e8 into master May 22, 2017
@sandersn sandersn deleted the make-getNameOfDeclaration-public branch May 22, 2017 17:32
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 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.

2 participants