[PATCH] D43764: [clang-apply-replacements] Convert tooling::Replacements to tooling::AtomicChange for conflict resolving of changes, code cleanup, and code formatting.
Jeremy Demeule via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 12 11:50:33 PDT 2018
jdemeule added inline comments.
================
Comment at: clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp:213-221
// Use the file manager to deduplicate paths. FileEntries are
// automatically canonicalized.
- if (const FileEntry *Entry = SM.getFileManager().getFile(R.getFilePath())) {
+ if (const FileEntry *Entry =
+ SM.getFileManager().getFile(R.getFilePath())) {
GroupedReplacements[Entry].push_back(R);
} else if (Warned.insert(R.getFilePath()).second) {
+ errs() << "Described file '" << R.getFilePath()
----------------
ioeric wrote:
> This code block is the same as the one in the above loop. Consider pulling it into a lambda.
Yes, for sure. I was not confident about this part.
================
Comment at: clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp:290
+ std::vector<tooling::AtomicChange> Changes;
+ for (const auto &R : AllChanges.getReplacements()) {
+ tooling::AtomicChange Change(Entry->getName(), Entry->getName());
----------------
ioeric wrote:
> I might be missing something, but why do we need to pull replacements from the result change into a set of changes?
I interpret you suggestion of set of `AtomicChange` a little bit too much.
================
Comment at: clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp:353
+ const FileEntry *Entry = FileAndReplacements.first;
+ ReplacementsToAtomicChanges DeduplicatedChanges(SM, Entry);
+ for (const auto &R : FileAndReplacements.second)
----------------
ioeric wrote:
> Sorry that I didn't make myself clear... what you had in the previous revision was correct (for the current use case of apply-all-replacements) i.e. store all replacements in one `AtomicChange`, which allows you to detect conflicts on the fly. So the code here can be simplified as:
>
> ```
> ...
> Entry = ...;
> AtomicChange FileChange;
> for (const auto &R : FileAndReplacements.second) {
> auto Err = FileChange.replace( <args from R> );
> if (Err)
> reportConflict(Entry, std::move(Err)); // reportConflict as we go
> }
> FileChanges.emplace(Entry, {FileChange});
> ...
> ```
>
> I think with this set up, you wouldn't need `ReplacementsToAtomicChanges`, `ConflictError` and `reportConflicts`.
I think I have over-interpreting your previous comment :-)
However, I am still confused about error reporting.
Currently, clang-apply-replacements reports conflicting replacement per file and per conflict.
For example:
```
There are conflicting changes to XXX:
The following changes conflict:
Replace 8:8-8:33 with "AAA"
Replace 8:8-8:33 with "BBB"
Remove 8:10-8:15
Insert at 8:14 CCC
```
With this patch, conflict are reported by pair (first replacement/conflicted one) and I am able to print the corresponding file only once (thanks to the defered reporting).
```
There are conflicting changes to XXX:
The following changes conflict:
Replace 8:8-8:33 with "AAA"
Replace 8:8-8:33 with "BBB"
The following changes conflict:
Replace 8:8-8:33 with "AAA"
Remove 8:10-8:15
The following changes conflict:
Replace 8:8-8:33 with "AAA"
Insert at 8:14 CCC
```
I prefer the way you suggest to report conflict but we will loose or print conflicting file at each conflict detected.
I even more prefer to use `llvm::toString(std::move(Err))` but this will fully change the reporting and will also be reported by pair.
```
The new replacement overlaps with an existing replacement.
New replacement: XXX: 106:+26:"AAA"
Existing replacement: XXX: 106:+26:"BBB"
The new replacement overlaps with an existing replacement.
New replacement: XXX: 106:+26:"AAA"
Existing replacement: XXX: 112:+0:"CCC"
The new replacement overlaps with an existing replacement.
New replacement: XXX: 106:+26:"AAA"
Existing replacement: XXX: 108:+12:""
```
================
Comment at: test/clang-apply-replacements/Inputs/basic/file2.yaml:1
---
MainSourceFile: source2.cpp
----------------
ioeric wrote:
> Could you please add two test cases for insertions: 1) identical insertions (e.g. "AB" and "AB") at the same location are applied sucessfully and 2) order-dependent insertions (e.g. "AB" and "BA") are detected.
>
> (It might make sense to do this in a different file)
I will.
================
Comment at: test/clang-apply-replacements/Inputs/conflict/expected.txt:8
+ Replace 9:5-9:11 with "elem"
The following changes conflict:
Remove 12:3-12:14
----------------
ioeric wrote:
> How could one replacement (`Remove 12:3-12:14`) conflict with itself?
It is not the case, they are reported by pair now.
https://reviews.llvm.org/D43764
More information about the cfe-commits
mailing list