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

Excluded the default library from rename service. #17415

Merged
merged 6 commits into from
Sep 14, 2017

Conversation

armanio123
Copy link
Member

Excludes the default library when renaming tokens.

@msftclas
Copy link

@armanio123,
Thanks for your contribution as a Microsoft full-time employee or intern. You do not need to sign a CLA.
Thanks,
Microsoft Pull Request Bot

@@ -725,7 +725,7 @@ namespace ts {

class SourceMapSourceObject implements SourceMapSource {
lineMap: number[];
constructor (public fileName: string, public text: string, public skipTrivia?: (pos: number) => number) {}
constructor(public fileName: string, public text: string, public skipTrivia?: (pos: number) => number) { }
Copy link
Member

Choose a reason for hiding this comment

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

All these white-space changes are interesting. Is it passing the linter? (Was it before?)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes it is passing linter (before and after). This was done by VS Code formatting, I thought it should be pushed.

@@ -921,6 +922,10 @@ namespace ts {
return sourceFilesFoundSearchingNodeModules.get(file.path);
}

function isSourceFileDefaultLibrary(file: SourceFile): boolean {
return file.fileName === host.getDefaultLibFileName(options);
Copy link
Member

Choose a reason for hiding this comment

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

I thought @rbuckton was factoring the core libraries into a set of smaller files that get added. If that's the case, I'm not sure this would work (as there wouldn't be just one default lib filename).

Copy link
Member Author

@armanio123 armanio123 Jul 25, 2017

Choose a reason for hiding this comment

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

If that the case, we might want to change this method to check for all of the different files. I'll talk to @rbuckton and get his input.

Copy link
Member Author

Choose a reason for hiding this comment

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

Based on what I have discussed with @rbuckton the better way of doing this it to check for GetDefaultLibDirectory. Every file that is there is going to be considered core library.

Copy link
Member

Choose a reason for hiding this comment

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

Perhaps this should be named isSourceFileReadonly or isSourceFileLockedForEdits so that we can later use the same functionality to prevent renames in declarations pulled in from node_modules or other "typeRoots" locations.

let sourceFiles: SourceFile[] = [];
if (options.isForRename) {
for (let sourceFile of program.getSourceFiles()) {
if (!program.isSourceFileDefaultLibrary(sourceFile)) {
Copy link
Member

Choose a reason for hiding this comment

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

So previously if you tried to rename something that was defined in the core library (e.g. a JavaScript API such as Array.map, or a DOM API such as window.addEventListener), it would error because you can't rename something in the core library. With this change, will that rename now proceed, but only for all your program files (i.e. leaving you in an error state)? I'm not sure that's a better behavior.

Copy link
Member Author

Choose a reason for hiding this comment

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

That functionality will remain the same. That happens on the function getRenameInfo.
This piece of code specifically checks for the locations of the tokens (not the token type). It will only exclude the default library from being referenced when searching for the token to be renamed.

Copy link
Member

@billti billti left a comment

Choose a reason for hiding this comment

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

I'd follow up with Ron on the core library not being one file piece, and Ryan on the behavior when renaming a core API now - but if they're happy, then looks good to me.

@@ -1506,7 +1506,21 @@ namespace ts {

function getReferences(fileName: string, position: number, options?: FindAllReferences.Options) {
synchronizeHostData();
return FindAllReferences.findReferencedEntries(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position, options);

// Exclude default library when renaming as commonly user don't want to change that file.
Copy link
Member

Choose a reason for hiding this comment

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

Will this block renaming a symbol declared in a default library? I would think that if a symbol is declared in a default library then we shouldn't allow the rename to proceed at all, rather than renaming it in a user's source files and resulting in possible compile time errors.

Copy link
Member Author

Choose a reason for hiding this comment

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

There's already a feature for that. This will avoid renaming anything on the default library, like comments or strings.

@@ -921,6 +922,10 @@ namespace ts {
return sourceFilesFoundSearchingNodeModules.get(file.path);
}

function isSourceFileDefaultLibrary(file: SourceFile): boolean {
return file.fileName === host.getDefaultLibFileName(options);
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps this should be named isSourceFileReadonly or isSourceFileLockedForEdits so that we can later use the same functionality to prevent renames in declarations pulled in from node_modules or other "typeRoots" locations.

@armanio123 armanio123 force-pushed the FixRenameInDefaultLibrary branch from 6cc5710 to 675b6fb Compare August 15, 2017 00:59
return true;
}

if (defaultLibraryPath !== undefined && defaultLibraryPath.length !== 0) {
Copy link
Member

Choose a reason for hiding this comment

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

This can be simplified: if (defaultLibraryPath)

}

if (defaultLibraryPath !== undefined && defaultLibraryPath.length !== 0) {
return comparePaths(defaultLibraryPath, file.path, currentDirectory, /*ignoreCase*/ true) === Comparison.EqualTo;
Copy link
Member

Choose a reason for hiding this comment

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

Do not unconditionally pass true for ignoreCase, instead use !host.useCaseInsensitiveFileNames().

Copy link
Member

Choose a reason for hiding this comment

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

I don't think comparePaths is the one you want to call. I think you meant to call containsPath here.

return comparePaths(defaultLibraryPath, file.path, currentDirectory, /*ignoreCase*/ true) === Comparison.EqualTo;
}

return compareStrings(file.fileName, host.getDefaultLibFileName(options), /*ignoreCase*/ true) === Comparison.EqualTo;
Copy link
Member

Choose a reason for hiding this comment

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

Do not unconditionally pass true for ignoreCase, instead use !host.useCaseInsensitiveFileNames().

@@ -436,6 +436,7 @@ namespace ts {
host = host || createCompilerHost(options);

let skipDefaultLib = options.noLib;
const defaultLibraryPath = host.getDefaultLibLocation ? host.getDefaultLibLocation() : getDirectoryPath(host.getDefaultLibFileName(options));
Copy link
Member

Choose a reason for hiding this comment

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

There is also a libDirectory variable in this function that does the same thing. Consider combining the two and possibly storing the result of host.getDefaultLibFileName(options) in a variable rather than requery it each time.

Copy link
Member

@rbuckton rbuckton left a comment

Choose a reason for hiding this comment

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

Approved, with a minor comment.

@@ -436,6 +436,8 @@ namespace ts {
host = host || createCompilerHost(options);

let skipDefaultLib = options.noLib;
const getDefaultLibraryFileName = memoize(() => host.getDefaultLibFileName(options));
Copy link
Member

Choose a reason for hiding this comment

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

Why bother with memoize and not just have const defaultLibraryFileName = host.getDefaultLibraryFileName(options)?

Copy link
Member Author

Choose a reason for hiding this comment

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

Depending on the options and some logic, the variable might end up not being needed. This was done for lazy evaluation.

@armanio123 armanio123 merged commit 21bbdd3 into microsoft:master Sep 14, 2017
@armanio123 armanio123 deleted the FixRenameInDefaultLibrary branch September 14, 2017 21:04
@mhegazy
Copy link
Contributor

mhegazy commented Sep 18, 2017

I do not think this is the best solution here. the default libraries are not any special. users can replace them. and the same issue persists if some one say renamed div in a JSX tag.

A better solution is to block rename for symbols coming from a .d.ts file unless the source of the rename operation is that file. see #8227

@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.

5 participants