-
Notifications
You must be signed in to change notification settings - Fork 889
Conversation
@alexeagle, do you plan to review this? I doubt I'll be able to get to this until sometime next week at the earliest. Definitely a great feature I want to get implemented! |
cc: @mprobst |
I've reviewed it on Scott's branch. I'll take another pass here, but the design already LGTM |
if (stat.isFile()) { | ||
fixedFileText = fs.readFileSync(fixedFile, "utf8"); | ||
// accumulate replacements | ||
const replacements = failures.reduce((acc, failure) => { |
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'm not sure the reduce here is worth the syntactic and cognitive cost, it might be simpler to just iterate?
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
constructor(private start: number, private length: number, private text: string) { | ||
} | ||
|
||
public getStart() { |
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'd be fine with making all of these real get
methods. I find that this sort of method can get frustrating (but fine either way)
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.
Looking good @ScottSWu. Is the Replacement API robust enough? How tricky to use is it when you get into weird changes, like overlapping fixes? What about when multiple rules want to apply fixes to the same file? I know you looked into the way it's done in other similar tools. Also, a test or two for your new test code would be great if possible! You could just add it to |
Applying fixes from multiple rules at once sounds like trouble to me. In the worst case, two rules may conflict, and after applying one set of replacements, you are left with some that don't apply, and now the result isn't even syntactically valid. Within a single rule, I'm not sure there is a need for overlapping fixes. Fixes should prepend or append text where possible, rather than replacing a whole range (and it's hard to convert an AST subtree to text anyway) |
To add on a bit, no these replacement functions are not robust, but would be building blocks for an something that is. A single fix should not have overlapping replacements within itself, but also should be applied entirely or not at all (e.g. it doesn't make sense to replace one quote mark). Thus the Fix.apply and the Replacement.apply functions will be useful. From what ESLint does, fixes are automatically applied, and only fixes that failed to be applied are displayed. EDIT: |
* Created IFix and IReplacement structures for representing fixes * programWalker includes createFix and createReplacement * Added optional parameter to createFailure for suggesting fixes * Modified semicolon rule to suggest fixes * Modified testing to check against a file with fixes applied
- Replaced reduce with for loop - Changed Fix and Replacement to classes - Added apply method to each - Fix.apply applies all replacements in reverse order - Replacement.apply performs the text substitution - Added function to display diff results in the tester
Ping @jkillian - Scott's internship has only a couple more weeks so we'd like to get this moving |
@@ -82,6 +82,14 @@ export class RuleWalker extends SyntaxWalker { | |||
} | |||
} | |||
|
|||
public createFix(replacements: Replacement[]): Fix { |
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 went back and forth on if we should have these wrapper methods at all (as the constructors have the exact same functionality). Do you think it makes sense to have them?
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'd prefer to expose only the typical fix methods. These are what we need for the current check and expose less API details to all the rules that might start using it.
so far we need
appendText(n: node, t: text)
for putting a semicolon after the statement, and
delete(start: number, length: number)
for deleting a semicolon?
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.
Fix is probably redundant. Eventually we should proxy replacements (including createReplacement) to make sure replacements at the same spots are applied in the right order. It turns out sorting is not guaranteed to be stable, but adding an additional ordering counter breaks ties correctly.
|
||
public apply(content: string) { | ||
// sort replacements in reverse so that diffs are properly applied | ||
this.innerReplacements.sort((a, b) => b.end - a.end); |
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'm thinking we could have a Replacements.applyAll
that is parallel to Fix.applyAll
?
This is looking good though, I think we can merge this shortly. @ScottSWu, @alexeagle what do you plan to proceed with after this merges? Implementing fixes for more rules? |
Got it, added a passing and failing check-bin tests. I believe the next step is to add the --fix option to the CLI. Implementing more fixes for rules is definitely important. There's also adding more helper functions for creating replacements, and outputting fixes in the other formatters. |
Sweet, future plans sound good to me. Merged this so things can more easily continue! |
Awesome! Thanks for pushing this through! |
* Created IFix and IReplacement structures for representing fixes * programWalker includes createFix and createReplacement * Added optional parameter to createFailure for suggesting fixes * Modified semicolon rule to suggest fixes (add / remove semicolon) * Modified testing to check against a file with fixes applied * If there is a ".ts.fix" file, then the test will take the first suggested fix and apply to the test file (without markup) and compare Addresses palantir#561
Addresses #561