-
Notifications
You must be signed in to change notification settings - Fork 14
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
fix: handle deeply nested whole exports #111
fix: handle deeply nested whole exports #111
Conversation
lib/util/edit.ts
Outdated
@@ -92,7 +93,7 @@ const createLanguageService = ({ | |||
projectRoot: string; | |||
fileService: FileService; | |||
}) => { | |||
const languageService = ts.createLanguageService({ | |||
return ts.createLanguageService({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tell me if you want me to revert these kind of changes, I've got some OCDs about this kind of stuffs 😬
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverted
lib/util/edit.ts
Outdated
@@ -12,6 +12,7 @@ import { MemoryFileService } from './MemoryFileService.js'; | |||
import { findFileUsage } from './findFileUsage.js'; | |||
import { parseFile } from './parseFile.js'; | |||
import { Output } from './Output.js'; | |||
import * as Export from './export.js'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've used namespaces to organise the code. This way you can do stuff like
Export.DeclarationWholeExport.isFileFound
Tell me what you think about this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have any particular opinion about using namespace imports (besides, it's not an issue in terms of detecting unused code since tsr
can detect these 😎
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’ve been thinking about this, but can we use import { foo } from 'foo'
to keep the style consistent? Sorry for the confusion🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
dbdf754
to
1e5eda1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your awesome work 🚀
lib/util/edit.ts
Outdated
@@ -536,13 +583,11 @@ export {};\n`, | |||
} | |||
|
|||
if (changes.length === 0) { | |||
const result = { | |||
return { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, I created the result
const intentionally so that I get the correct type inference without having to annotate the return type of the function. Would you mind reverting this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's your project mate, ask me and I'll do it 😄. This is done.
/** | ||
* Whole export when the file is found within the destFiles | ||
*/ | ||
export type FileFound = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
declaring a type which is almost the same seems a bit redundant. How about
export type FileFound = WholeExportDeclaration & { file: string }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this kind of case what I usually is
type Base = { ... };
type SubCase1 = Base & { ... };
type SubCase2 = Base & { ... };
type Whole = SubCase1 | SubCase2;
Because Base
isn't actually a type you can use as it's not really a WholeExportDeclaration
, which has either file: string
or file: null
, WDYT?
@@ -2,7 +2,8 @@ import ts from 'typescript'; | |||
import { Vertexes } from './DependencyGraph.js'; | |||
import { parseFile } from './parseFile.js'; | |||
|
|||
const ALL_EXPORTS_OF_UNKNOWN_FILE = '__all_exports_of_unknown_file__'; | |||
const ALL_EXPORTS_OF_UNKNOWN_FILE = '#all_exports_of_unknown_file#'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like your idea of using #
for special keywords. Definitely better than my original implementation!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The best way to do it would be a Symbol
though
lib/util/edit.ts
Outdated
* | ||
* No need to memoize this function because `parseFile` already memoizes the file parsing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* | |
* No need to memoize this function because `parseFile` already memoizes the file parsing. |
I think this comment is too much [nit]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
lib/util/edit.ts
Outdated
files, | ||
fileNames, | ||
options, | ||
filesAlreadyVisited = new Set<string>(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that this field is exposing unnecessary choice/information outside of the function's boundary. Can this be declared inside the function?
function foo() {
const visited = new Set();
// do something then
deeply(theOtherArgs, visited)
}
or maybe using a stack instead of recursively calling functions is better to have a shared context. (converting to using a stack is just a suggestion, not a must)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, I've kept the recursion because I didn't know how to do it with the stack 😄
@@ -1130,6 +1130,26 @@ export const b = 'b';`, | |||
assert.equal(fileService.exists('/app/a_reexport.ts'), false); | |||
assert.equal(fileService.exists('/app/a.ts'), false); | |||
}); | |||
|
|||
it('should look for deeply nested whole re-export without removing files', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the logic not supporting loops is acceptable as long as the behavior is defined 👍 Can you add a test case to assure what happens when there's a loop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well your test case will just hang until you stop it, so there isn't much I can do about this
lib/util/edit.ts
Outdated
@@ -12,6 +12,7 @@ import { MemoryFileService } from './MemoryFileService.js'; | |||
import { findFileUsage } from './findFileUsage.js'; | |||
import { parseFile } from './parseFile.js'; | |||
import { Output } from './Output.js'; | |||
import * as Export from './export.js'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have any particular opinion about using namespace imports (besides, it's not an issue in terms of detecting unused code since tsr
can detect these 😎
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
Fixes #109
But if you have a loop in your whole exports, now you are doomed 😬