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

Scope symbol IDs per element package name #788

Merged
merged 18 commits into from Feb 27, 2017

Conversation

felipecsl
Copy link
Contributor

@felipecsl felipecsl commented Oct 26, 2016

the integer ID itself is not enough to correctly identify a symbol. We need to scope that somehow in order to prevent clashes. This can be observed in a multiple modules project where butterknife is used in modules that depend on other modules that also use Butterknife.
Since IDs can repeat across modules, we need to scope them according to the package name of the current element being evaluated.
This PR fixes #779

@felipecsl felipecsl changed the title Fix #779 Scope symbol IDs per element package name Oct 26, 2016
@@ -1231,17 +1246,20 @@ private void scanForRClasses(RoundEnvironment env) {
for (Element element : env.getElementsAnnotatedWith(annotation)) {
JCTree tree = (JCTree) trees.getTree(element, getMirror(element, annotation));
if (tree != null) { // tree can be null if the references are compiled types and not source
String respectivePackageName =
elementUtils.getPackageOf(element).getQualifiedName().toString();
scanner.setCurrentPackageName(respectivePackageName);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is pretty janky, but couldn't figure out a simpler way to do this. Suggestions welcome

@@ -1284,28 +1302,38 @@ private void parseCompiledR(TypeElement rClass) {
}

private static class RClassScanner extends TreeScanner {
private final Set<String> rClasses = new LinkedHashSet<>();
// Maps the currently evaulated packageName to R Classes
private final Map<String, String> rClasses = new LinkedHashMap<>();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is also a bit confusing

@felipecsl
Copy link
Contributor Author

felipecsl commented Oct 27, 2016

@kageiit wonder if you could take a look too, since you wrote this originally

private Id getId(int id) {
if (symbols.get(id) == null) {
symbols.put(id, new Id(id));
private Id getId(QualifiedId qualifiedId) {
Copy link
Contributor

Choose a reason for hiding this comment

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

QualifiedId already has the id as part of it right? why do you still need the symbol map

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correct. I kept the Map just for the fast lookup

}
}

private void parseRClass(String rClass) {
private void parseRClass(String respectivePackageName, String rClass) {
Copy link
Contributor

Choose a reason for hiding this comment

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

rename to rPackageName?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sure!

@felipecsl
Copy link
Contributor Author

@JakeWharton friendly ping!

@JakeWharton
Copy link
Owner

Monday at earliest. Traveling.

On Thu, Oct 27, 2016 at 8:58 PM Felipe Lima notifications@github.com
wrote:

@JakeWharton https://github.com/JakeWharton friendly ping!


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#788 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAEEEeyfWeVNCyLjelMC0Tqs58Vb74muks5q4QJRgaJpZM4Khp_h
.

@felipecsl
Copy link
Contributor Author

No worries, I just realized that this is not quite right yet. More updates coming

@kunong
Copy link

kunong commented Nov 14, 2016

@felipecsl anymore updates coming? I'm a guy that waiting this fix. :)

@felipecsl
Copy link
Contributor Author

@kunong yep, planning to finish today or tomorrow

@javajoker
Copy link

@felipecsl , any update on this issue? Thanks, Ning

@felipecsl
Copy link
Contributor Author

no updates yet. We stopped seeing this issue so it's not burning anymore.

@mrhether
Copy link

@felipecsl what still needs to be done here?

@felipecsl
Copy link
Contributor Author

@mrhether If I'm not mistaken, this change breaks usage of ButterKnife when you're not using it as a gradle plugin. If you always use it as a plugin, then it should work fine.

@mrhether
Copy link

@felipecsl Is this hosted anywhere?

@felipecsl
Copy link
Contributor Author

felipecsl commented Jan 17, 2017 via email

BenSchwab added a commit to BenSchwab/butterknife that referenced this pull request Feb 16, 2017
This PR does not work with projects that use butterknife
in application modules!!

Squashed commit of the following:

commit 02a845f
Merge: 34b2228 d5fb986
Author: Felipe Lima <felipe.lima@gmail.com>
Date:   Mon Nov 21 11:58:11 2016 -0800

    Merges with master

commit 34b2228
Author: Felipe Lima <felipe.lima@gmail.com>
Date:   Thu Oct 27 12:57:23 2016 -0700

    Simple rename

commit a34d982
Author: Felipe Lima <felipe.lima@gmail.com>
Date:   Thu Oct 27 12:56:48 2016 -0700

    More checkstyle

commit 8098a01
Author: Felipe Lima <felipe.lima@gmail.com>
Date:   Wed Oct 26 22:46:55 2016 -0700

    Make checkstyle happy

commit 4b8f7f5
Author: Felipe Lima <felipe.lima@gmail.com>
Date:   Wed Oct 26 14:01:01 2016 -0700

    Also revert this

commit dd64ff5
Author: Felipe Lima <felipe.lima@gmail.com>
Date:   Wed Oct 26 13:59:02 2016 -0700

    Undo some changes

commit e2847f1
Author: Felipe Lima <felipe.lima@gmail.com>
Date:   Wed Oct 26 13:54:44 2016 -0700

    Remove debug statements

commit 3d83d25
Author: Felipe Lima <felipe.lima@gmail.com>
Date:   Wed Oct 26 13:49:06 2016 -0700

    Fixes JakeWharton#779 by scoping symbols by package

commit 1692866
Author: Felipe Lima <felipe.lima@gmail.com>
Date:   Wed Oct 19 17:43:45 2016 -0700

    Adds failing test for JakeWharton#779
felipecsl and others added 4 commits February 23, 2017 10:55
My understanding of whats going on is it is possible for R files
in two different modules to generate the same id for different resoureces.

Butterknife used to use a Map<Integer,Id> where Id is a class that
contains knowledge of how to generate code. Thus, when ids are
duplicated only one would win the map. The loser would have it's
generated code import the wrong id.

Now we qualify the id with the package name of the id element. However,
due to the structure of the code-gen, we parse R files without knowing
exactly what packages reference which generated ids.

But we do know all the packages that reference something in the R file.
So we can defensively generated id's for ALL permutations. This sorta
stinks from a performance stand-point, but is the only quick way I can
figure out to use the QualifiedId, and gaurentee we generate all the
qualified ids we will need.

 Essentially, for every package
that has a butterknife annotation, we parse all R files in that
package with all package combinatios. This creates many
unneeded qualified ids, but it gaurentees that everything will be
present.
@felipecsl
Copy link
Contributor Author

felipecsl commented Feb 23, 2017

Alright thanks to @BenSchwab 's airbnb@b0aa4ad this is finally functional and ready for review.
We've been using it internally for a ~week and it seems to have fixed the bug.
@JakeWharton PTAL at your earliest convenience 😄

build.gradle Outdated
@@ -37,7 +37,7 @@ subprojects { project ->
}
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
classpath 'com.android.tools.build:gradle:2.3.0-rc1'
Copy link
Owner

Choose a reason for hiding this comment

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

Is this required? Non-final releases are timeboxed and I don't want to commit code that uses pre-release versions because that makes the commit unbuildable after a month or two.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not required. it was just Android Studio being annoying. Reverting now..

@JakeWharton
Copy link
Owner

Looks like there's a checkstyle failure.

@felipecsl
Copy link
Contributor Author

Green and ready to go 🎉

@JakeWharton JakeWharton merged commit 4ad9f98 into JakeWharton:master Feb 27, 2017
@felipecsl felipecsl deleted the felipe/fix-779 branch May 24, 2017 09:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ButterKnife generates ViewBinding class with wrong resource ID
7 participants