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

Feat#Provide a quickfix for non-exported types #37980

Closed
wants to merge 22 commits into from

Conversation

Qiyu8
Copy link

@Qiyu8 Qiyu8 commented Apr 15, 2020

Fixes #37440

  • if the locals originate from a .d.ts file, do nothing.

  • No export found in the file:

  1. The declaration contains multiple variables, creating export {...}
  2. The declaration is a single function or variable: add export
  • more than one export {...} found in the file:
  1. The declaration contains multiple variables or The declaration is a single variable, add the declaration to the last export {...}
  2. The declaration is a single function: add export

Copy link
Member

@DanielRosenwasser DanielRosenwasser left a comment

Choose a reason for hiding this comment

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

Very good start! I would also like to see the case where the locals originate from a .d.ts file. We shouldn't provide a quick fix in that case.

src/compiler/diagnosticMessages.json Outdated Show resolved Hide resolved
src/services/codefixes/fixImportNonExportedMember.ts Outdated Show resolved Hide resolved
@Qiyu8 Qiyu8 requested a review from DanielRosenwasser April 22, 2020 06:20
@Qiyu8 Qiyu8 marked this pull request as draft April 27, 2020 06:11
@Qiyu8 Qiyu8 marked this pull request as ready for review April 28, 2020 07:26
@Qiyu8
Copy link
Author

Qiyu8 commented Apr 28, 2020

@DanielRosenwasser Feel free to review if you have time

@sandersn sandersn added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label May 5, 2020
Qiyu8 and others added 3 commits May 6, 2020 10:50
Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>
Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

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

I agree that the message needs to change. I think fixing getAllCodeActions is difficult and probably less likely to be used than the individual fix anyway.

src/compiler/diagnosticMessages.json Outdated Show resolved Hide resolved
@sandersn
Copy link
Member

@Qiyu8 do you want to keep working on this? I think the main thing left to fix is the fix-all message.

@Qiyu8
Copy link
Author

Qiyu8 commented May 22, 2020

@sandersn Please feel free to merge right now ,write a custom getAllCodeActions handler is a little diffcult for me.

@Qiyu8 Qiyu8 requested a review from sandersn May 25, 2020 01:30
@Qiyu8
Copy link
Author

Qiyu8 commented May 30, 2020

@sandersn @DanielRosenwasser Is there anything I can do?

Qiyu8 and others added 6 commits July 1, 2020 11:37
Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>
Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>
Merge branch 'master' of github.com:microsoft/TypeScript into quickfix_non_exported
@Qiyu8
Copy link
Author

Qiyu8 commented Aug 4, 2020

Sorry for the delay, I spent a lot of time in rebase + squash and finally all of the errors and requirements has fulfilled, @elibarzilay @DanielRosenwasser , Please feel free to review.

Copy link
Member

@DanielRosenwasser DanielRosenwasser left a comment

Choose a reason for hiding this comment

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

This looks like it's getting very close to merging!

src/services/codefixes/fixImportNonExportedMember.ts Outdated Show resolved Hide resolved
src/services/codefixes/fixImportNonExportedMember.ts Outdated Show resolved Hide resolved
const statements = sourceFile.statements.filter(isExportDeclaration);
for (const statement of statements) {
if (statement.exportClause && isNamedExports(statement.exportClause)) {
namedExport = statement;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
namedExport = statement;
return statement;

Copy link
Author

Choose a reason for hiding this comment

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

I want to get the last export { } and add the missing export there, so I can't return immediately.

Comment on lines 67 to 68
return compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name) ||
compareIdentifiers(s1.name, s2.name);
Copy link
Member

Choose a reason for hiding this comment

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

Why do you need to have the fallback here? Why can't this just be the following?

Suggested change
return compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name) ||
compareIdentifiers(s1.name, s2.name);
return compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name);

}
if (isFunctionSymbol(localSymbol)) {
const start = localSymbol.valueDeclaration.pos;
changes.insertExportModifierAt(sourceFile, start ? start + 1 : 0);
Copy link
Member

Choose a reason for hiding this comment

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

What exactly is with the start + 1? I don't understand.

Copy link
Author

Choose a reason for hiding this comment

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

I want to add an export identifier in front of non-exported type, you can see the codeFixImportNonExportedMember1.ts, an export added before function bar(), the start there is the position of line break, so need to +1 for start.

Copy link
Member

Choose a reason for hiding this comment

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

The problem you are running into is more about using the pos (a.k.a. the "full start") instead of the start after the trivia (what you'd get when you call getStart(sourceFile)).

As far as I can tell, a test like

/**
 * hello
 */
function bar() {
}

will likely end up with the export inside of the comment..

What happens when you just use insertExportModifier instead of insertExportModifierAt?

return;
}
if (isFunctionSymbol(localSymbol)) {
const start = localSymbol.valueDeclaration.pos;
Copy link
Member

Choose a reason for hiding this comment

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

If you're suing pos, that means you're including leading trivia.

this.insertExportModifierAt(sourceFile, node.getStart(sourceFile));
}

public insertExportModifierAt(sourceFile: SourceFile, position: number): void {
Copy link
Member

Choose a reason for hiding this comment

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

I just don't quite know if you need this, but I don't understand the start + 1 thing yet.

Copy link
Author

Choose a reason for hiding this comment

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

I want to add an export identifier in front of non-exported type, you can see the codeFixImportNonExportedMember1.ts, an export added before function bar(), the start there is the position of line break, so need to +1 for start.

@Qiyu8 Qiyu8 requested a review from DanielRosenwasser August 6, 2020 12:22
@DanielRosenwasser
Copy link
Member

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 15, 2020

Heya @DanielRosenwasser, I've started to run the tarball bundle task on this PR at 85d5b4a. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

Hey @DanielRosenwasser, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/82348/artifacts?artifactName=tgz&fileId=C75D4A6B47D650F118247EF885FAA78EC5E08E5280AA0943834AB65938014A6002&fileName=/typescript-4.1.0-insiders.20200815.tgz"
    }
}

and then running npm install.

@Qiyu8
Copy link
Author

Qiyu8 commented Aug 21, 2020

@DanielRosenwasser I think this PR is ready for merge, What else do I need to do?

@DanielRosenwasser
Copy link
Member

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 21, 2020

Heya @DanielRosenwasser, I've started to run the tarball bundle task on this PR at 85d5b4a. You can monitor the build here.

@DanielRosenwasser
Copy link
Member

@DanielRosenwasser I think this PR is ready for merge, What else do I need to do?

#37980 (comment) is still something I am wondering about. I'm not seeing why the existing method didn't suffice here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 21, 2020

Hey @DanielRosenwasser, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/82931/artifacts?artifactName=tgz&fileId=10316357496660C77808C8DB7BEDFBBBA34AE694AE155125DAEC98B186C3F22A02&fileName=/typescript-4.1.0-insiders.20200821.tgz"
    }
}

and then running npm install.


There is also a playground for this build.

Copy link
Member

@DanielRosenwasser DanielRosenwasser left a comment

Choose a reason for hiding this comment

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

This is the current behavior I see. Please add a relevant test to ensure the export keyword doesn't get placed before the comment. I've already left some feedback on how you can achieve that behavior.

addExportKeyword

@sandersn
Copy link
Member

@Qiyu8 do you want to keep working on this?

@Qiyu8
Copy link
Author

Qiyu8 commented Oct 30, 2020

@sandersn Thanks for your caring, I think the only problem is to ensure the export keyword doesn't get placed before the comment as @DanielRosenwasser pointed out, But I didn't find a solution to do that.

@sandersn
Copy link
Member

@Qiyu8 I haven't had good experience with comment trivia myself, so maybe you can look at similar codefixes or refactors and then try @DanielRosenwasser 's suggestions?

@Qiyu8
Copy link
Author

Qiyu8 commented Nov 2, 2020

@DanielRosenwasser How to get the DeclarationStatement of a FunctionSymbol?

if (isFunctionSymbol(localSymbol) && isDeclarationStatement(current.?)) {
            changes.insertExportModifier(sourceFile, current.?);
            return;
        }

I want to add export in front of a function.

@sandersn
Copy link
Member

@Qiyu8 Sorry for dropping this for so long. I understand if you don't want to work on this anymore.

To answer your latest question: s.valueDeclaration is the value declaration of the symbol, which is the one you want for a function (since a function is a value, not a type.)

@sandersn
Copy link
Member

This PR hasn't seen any activity for quite a while, so I'm going to close it to keep the number of open PRs manageable. Please let me know if you want to keep working on it and if you need more help to find the declaration of a function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Provide a quick-fix for non-exported types
5 participants