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

Suggest autofixes for declaration diagnostics #30

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Options:
```

`-t path/to/tsconfig.json` or `--tsconfig path/to/tsconfig.json`
Specifies the project to use the tool on. If no arguement given, the tool will use the tsconfig in the current working directory.
Specifies the project to use the tool on. If no argument given, the tool will use the tsconfig in the current working directory.

`-e <number>` or `--errorCode <number>`
Specifies the errors to fix. Several error codes can be specified during the same command.
Expand Down
25 changes: 14 additions & 11 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,16 @@ export const checkOptions = async (opt: Options): Promise<[string[], string[]]>

// Check git status if the write flag was provided and the output folder is the same as the project folder
// Do not allow overwriting files with previous changes on them unless --ignoreGitStatus flag was provided
if (opt.write && path.dirname(opt.tsconfig) === opt.outputFolder) {
if (!opt.ignoreGitStatus && opt.write && path.dirname(opt.tsconfig) === opt.outputFolder) {
Copy link
Contributor Author

@MichaelMitchell-at MichaelMitchell-at Apr 30, 2024

Choose a reason for hiding this comment

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

It doesn't make sense to run any of the code in this block if ignoreGitStatus is true.

It will also just crash on MacOS due to #26. Not bothering to fix that as there's already an (over-year old) PR for that at #23.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I noticed this one when I tried ts-fix last.

let isModified = false;
const status = await (getGitStatus(opt.tsconfig));
const splitStatus = status.split(/\r?\n/);
if (splitStatus.length && splitStatus[0] != '') {
const re = /[MARCD?]\s(package).+?(json)/g
isModified = splitStatus.length && splitStatus[0] !== '' ? !(splitStatus.filter((text) => { return text.match(re) }).length === splitStatus.length) : false;
}
if (isModified && !opt.ignoreGitStatus) {
throw new Error(`Please provide the --ignoreGitStatus flag if you are sure you'ld like to override your exisiting changes`);
if (isModified) {
throw new Error(`Please provide the --ignoreGitStatus flag if you are sure you'd like to override your existing changes`);
}
}

Expand Down Expand Up @@ -312,12 +312,12 @@ export async function getCodeFixesFromProject(project: Project, opt: Options, ho
return fixesAndDiagnostics;
});

const flatCodeFixesAndDiagnostics = <FixAndDiagnostic[]>_.flatten(codefixesPerFile);
const flatCodeFixesAndDiagnostics: FixAndDiagnostic[] = _.flatten(codefixesPerFile);
let [filteredCodeFixesAndDiagnostics, filteredCodeFixByNameOut] = filterCodeFixesByFixName(flatCodeFixesAndDiagnostics, opt.fixName);
filteredCodeFixByNameOut.forEach((s: string) => { host.log(s); });
[fixesAndDiagnostics, noAppliedFixes] = getAppliedAndNoAppliedFixes(filteredCodeFixesAndDiagnostics);
if (!opt.showMultiple) {
fixesAndDiagnostics = removeMutilpleDiagnostics(fixesAndDiagnostics);
fixesAndDiagnostics = removeMultipleDiagnostics(fixesAndDiagnostics);
}
fixesAndDiagnostics = removeDuplicatedFixes(fixesAndDiagnostics);
if (filteredCodeFixesAndDiagnostics.length) {
Expand All @@ -340,7 +340,10 @@ export async function getCodeFixesFromProject(project: Project, opt: Options, ho

export function getDiagnostics(project: Project): (readonly Diagnostic[])[] {
const diagnostics = project.program.getSourceFiles().map(function (file: SourceFile) {
return project.program.getSemanticDiagnostics(file);
return [
...project.program.getDeclarationDiagnostics(file),
MichaelMitchell-at marked this conversation as resolved.
Show resolved Hide resolved
...project.program.getSemanticDiagnostics(file),
];
});
return diagnostics;
}
Expand All @@ -350,7 +353,7 @@ export function filterDiagnosticsByFileAndErrorCode(diagnostics: (readonly Diagn
// if errorCodes were passed in, only use the specified errors
// diagnostics is guaranteed to not be [] or [[]]
let filteredDiagnostics = diagnostics.filter((diagnostics) => diagnostics.length);
let returnStrings = <string[]>[];
let returnStrings: string[] = [];

// Check if file is in node_modules, if so remove it from filteredDiagnostics, we'll not be applying fixes there
filteredDiagnostics = filteredDiagnostics.filter((filteredDiagnostic) => {
Expand Down Expand Up @@ -486,7 +489,7 @@ export function filterCodeFixesByFixName(codeFixesAndDiagnostics: FixAndDiagnost
// do we want to distinguish the case when no codefixes are picked? (no hits)

let fixCounter = new Map<string, number>();
let out = <string[]>[];
let out: string[] = [];
const filteredFixesAndDiagnostics = codeFixesAndDiagnostics.filter((codeFixAndDiagnostic) => {
if (codeFixAndDiagnostic.fix && fixNames.includes(codeFixAndDiagnostic.fix.fixName)) {
const currentVal = fixCounter.get(codeFixAndDiagnostic.fix.fixName);
Expand Down Expand Up @@ -532,15 +535,15 @@ async function getUpdatedCodeFixesAndDiagnostics(codeFixesAndDiagnostics: FixAnd
if (userInput === Choices.ACCEPT) {
addToCodefixes(codefixes, [currentCodeFix]);
if (showMultiple) {
codeFixesAndDiagnostics = removeMutilpleDiagnostics(codeFixesAndDiagnostics, Choices.ACCEPT)
codeFixesAndDiagnostics = removeMultipleDiagnostics(codeFixesAndDiagnostics, Choices.ACCEPT)
}
else {
codeFixesAndDiagnostics.splice(0, count);
};
}
else if (userInput === Choices.ACCEPTALL) {
if (showMultiple) {
codeFixesAndDiagnostics = removeMutilpleDiagnostics(codeFixesAndDiagnostics);
codeFixesAndDiagnostics = removeMultipleDiagnostics(codeFixesAndDiagnostics);
}
let updatedFixesAndDiagnostics = codeFixesAndDiagnostics.filter((diagnosticAndFix) => diagnosticAndFix.diagnostic.code === currentDiagnostic.code);
updatedFixesAndDiagnostics.map((diagnosticAndFix) => {
Expand Down Expand Up @@ -632,7 +635,7 @@ export interface ChangeDiagnostic {

// Removes duplicate diagnostics if showMultiple = false
// Also removes multiple code fixes for the diagnostic if the user accepts the first one or to accept all of that type
export function removeMutilpleDiagnostics(codeFixesAndDiagnostics: FixAndDiagnostic[], choice?: Choices.ACCEPT): FixAndDiagnostic[] {
export function removeMultipleDiagnostics(codeFixesAndDiagnostics: FixAndDiagnostic[], choice?: Choices.ACCEPT): FixAndDiagnostic[] {
if (choice === Choices.ACCEPT) {
for (let i = 1; i < codeFixesAndDiagnostics.length; i++) {
let count = 1;
Expand Down