Skip to content

Handle different default export forms the same way in import code fixes - #21014

Merged
Andrew Casey (amcasey) merged 8 commits into
microsoft:masterfrom
amcasey:GH19115
Jan 9, 2018
Merged

Handle different default export forms the same way in import code fixes#21014
Andrew Casey (amcasey) merged 8 commits into
microsoft:masterfrom
amcasey:GH19115

Conversation

@amcasey

Copy link
Copy Markdown
Member

export default C and export { C as default } should be handled the same as export default class C { }.

Fixes #19115

`export default C` and `export { C as default }` should be handled the
same as `export default class C { }`.

Fixes microsoft#19115
The regular displayName had special handling for `as` clauses in imports
and exports but the fullDisplayName did not.  They should be consistent.

(The impact of this change is very minor - it only affects the root node
of the tree control in the rename preview, which is off by default.)

Bonus: Eliminate `getDeclaredName` which is only called by rename.

Note: Special handling of default exports was not preserved since
`default` cannot be renamed.
Comment thread src/services/rename.ts
const displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node));
const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node);
return kind ? getRenameInfoSuccess(displayName, typeChecker.getFullyQualifiedName(symbol), kind, SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile) : undefined;
if (!kind) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This change could use a test.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We don't have a good way to test that it shows up in the right place in the UI, but I can try to add a lower-level test of the rename info.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Just to clarify, what is the expected change to rename behavior due to this PR?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Different strings are displayed in VS dialogs. No impact on renaming.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

There must be some function that returns a different value than before in some situation?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, of course. And I believe I've found a fourslash helper for testing it. I just meant that the same user actions would result in the same result (i.e. renaming) after the change.

@@ -0,0 +1,21 @@
/// <reference path="fourslash.ts" />

// @allowJs: true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is it necessary that this test be JS? Should work exactly the same in TS?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This test matches the repro steps in the bug. If a TS test would be preferable, I can change it (it should be equivalent).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If it's exactly the same with these lines removed I would do that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Assuming you also meant to update the file extensions (so that diagnostics are produced at all), it would still not be exactly the same since the suppression fixes would not be offered (though that distinction is not important to the test/change).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Yeah, I agree it's OK to remove the JS-specific suppression codefixes from this test since that's not what the point of the test is.

Comment thread src/services/findAllReferences.ts Outdated
createSearch(location: Node, symbol: Symbol, comingFrom: ImportExport | undefined, searchOptions: { text?: string, allSearchSymbols?: Symbol[] } = {}): Search {
// Note: if this is an external module symbol, the name doesn't include quotes.
// Note: getLocalSymbolForExportDefault handles `export default class C {}`, but not `export default C` or `export { C as default }`.
// The other two forms seem to be handled downstream (i.e. special-casing the first form here appears to be intentional).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This may be because we don't get a default export alias symbol here. See for example skipPastExportOrImportSpecifier.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Supplemented the comment with that information.

Comment thread src/services/codefixes/importFixes.ts Outdated

function getEscapedNameForExportDefault(symbol: Symbol): __String | undefined {
const declarations = symbol.declarations;
if (length(declarations) > 0) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Might was well return firstDefined(symbol.declarations, declaration => ...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

That's not equivalent, is it? It'll check subsequent declarations if the lambda returns undefined for the first one?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You're right, it's not exactly equivalent, but I don't think it hurts to loop through declarations (and there is usually only one).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

And the advantage is removing one bounds check?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If you like it this way that's fine, I just find it suspicious when we depend on declarations[0] being something particular, although that should be work in this case since the symbol for an export assignment or export specifier should always have exactly one declaration.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I can check that the length is one if that would be more robust.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I don't think that's necessary, it shouldn't really matter whether it has other declarations or not.

@@ -0,0 +1,21 @@
/// <reference path="fourslash.ts" />

// @allowJs: true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This doesn't really need to be a JS test, right?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

While I can no longer recall my original motivation, it appears to be a JS version of the TS test in importNameCodeFixDefaultExport2.ts.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Well, I don't think we need the same test twice -- the same services code will be tested either way.

@amcasey
Andrew Casey (amcasey) merged commit ef5a289 into microsoft:master Jan 9, 2018
@amcasey
Andrew Casey (amcasey) deleted the GH19115 branch January 9, 2018 03:07
@microsoft Microsoft (microsoft) locked and limited conversation to collaborators Jul 3, 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