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
PiranhaJava // config: add returnType, receiverType and argumentIndex; move to properties.json #39
PiranhaJava // config: add returnType, receiverType and argumentIndex; move to properties.json #39
Conversation
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.
Thanks for an excellent enhancement PR. Overall, looks great.
Can you clarify some of the questions raised in the review?
java/piranha/src/test/java/com/uber/piranha/XPFlagCleanerTest.java
Outdated
Show resolved
Hide resolved
java/piranha/src/test/resources/config/properties_test_receive.json
Outdated
Show resolved
Hide resolved
Thank you. I've replied to your comments and added one of my own. Will change:
|
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.
This is an amazing contribution overall. I did a first pass of commenting. Basically, I'd like to have some more structure to our fields than just one gigantic map encoding the full JSON, and also have some decoupling between config format and in-memory representation (so we can keep supporting .properties
for existing users), other than that, it's mostly nits. @mkr-plse , what do you think?
java/piranha/src/test/java/com/uber/piranha/XPFlagCleanerTest.java
Outdated
Show resolved
Hide resolved
java/piranha/src/test/java/com/uber/piranha/XPFlagCleanerTest.java
Outdated
Show resolved
Hide resolved
java/piranha/src/test/java/com/uber/piranha/XPFlagCleanerTest.java
Outdated
Show resolved
Hide resolved
java/piranha/src/test/java/com/uber/piranha/XPFlagCleanerTest.java
Outdated
Show resolved
Hide resolved
java/piranha/src/test/java/com/uber/piranha/XPFlagCleanerTest.java
Outdated
Show resolved
Hide resolved
java/piranha/src/test/java/com/uber/piranha/XPFlagCleanerTest.java
Outdated
Show resolved
Hide resolved
All good points, will get back to this over the weekend and wrap it up. Wanted to bring one thing to your attention though.
|
How are you bringing in Piranha? Are you making it a dependency for your project? (If so, I believe the build system would grab its dependencies from maven central) Or are you just sticking the jar somewhere? (Piranha is not supposed to be a fat jar, afaik) Note that the sample projects in this repo build by simply depending on Piranha and we'd be sure to test this with our internal (buck) build system before cutting a release. What happens if you replace |
Yes, Piranha is added as a dependency. Basically the same POM config that's given in the Java README. I figured out that adding
👍
This works too! Must have been some issue on my end. |
I think what is happening is, because you are moving the |
Have updated the PR with support for argumentIndex. This closes #6 Anything else remaining? Update: the README should be updated to mention the optional argumentIndex. I will do that. |
Haven't done the full review yet, but two things:
|
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.
Thanks @pranavsb for the PR again. The changes are looking good. Left a few comments and will review the tests after the comments are addressed.
Agree. |
Moved from defaultCharset to StandardCharsets.UTF_8 for reading properties.json
47ffe00
to
c89c433
Compare
Done! I also closed almost all review comments. Have left a few open in case there's further discussion required. One thing worth noting, I've changed the |
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.
Thanks for the changes. Left a few more comments, but at the high level, these are the main issues:
a) We can get rid of the pattern for receiverType and returnType and simplify the code
b) We can change the return type of checkValue...
to the appropriate Object. Will avoid redundant get
calls.
c) The tests may need to be enhanced to check for a few more combinations. Some cases that I can think of:
- when the required properties are not provided in the json,
- when receiverType alone is specified
- when returnType alone is specified
- when argumentIndex alone is specified
- when argumentIndex and receiverType are specified
- when argumentIndex and returnType are specified
- when all the three are specified
- for each of the above cases, there are likely two tests -- with or without method matching in the input source
Done.
Done.
Testcases
Also, I've changed the |
@pranavsb Can you push your changes? It looks like the files have not been updated yet. |
Was planning to finish tests before pushing. Have added a few. |
I thought you forgot to push because of the done comment. No hurry. Let me know when the code is available for review again. |
Added (lots of) tests and pushed. Guess it's in decent shape now. |
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.
Changes look great. The elaborate tests and the comments accompanying them are very helpful. Thanks for the painstaking effort.
There are a couple of comments. It will be great if you can address them. We can merge the changes after @lazaroclapp also takes a look at the changes.
java/README.md
Outdated
|
||
The `emptyMethods` specify the APIs which need to be discarded from the code. For example, a statement `enableFlag(SAMPLE_STALE_FLAG);` will be deleted from the code. | ||
For `returnType` and `receiverType`, types should be written as `boolean` or `void` for inbuilt types, and fully qualified for custom defined types. eg: `com.uber.piranha.XPFlagCleanerPositiveCases.XPTest` |
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.
inbuilt -> primitive.
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.
Also, question as a user reading this: what about String
? Is it string
or java.lang.String
? (I'd assume the second, specially if we say "primitive" but might be worth calling it out explicitly.
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.
Also added java.lang.string and a java.lang.boolean (which returns Boolean
instead of boolean
) test
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.
Overall, really happy with this version. There is a comment under noFlagCase
that I probably want some more clarity on before landing.
The rest, I think, are mostly nits and minor fixes.
java/README.md
Outdated
|
||
The `emptyMethods` specify the APIs which need to be discarded from the code. For example, a statement `enableFlag(SAMPLE_STALE_FLAG);` will be deleted from the code. | ||
For `returnType` and `receiverType`, types should be written as `boolean` or `void` for inbuilt types, and fully qualified for custom defined types. eg: `com.uber.piranha.XPFlagCleanerPositiveCases.XPTest` |
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.
Also, question as a user reading this: what about String
? Is it string
or java.lang.String
? (I'd assume the second, specially if we say "primitive" but might be worth calling it out explicitly.
java/piranha/src/test/resources/config/properties_test_invalid.json
Outdated
Show resolved
Hide resolved
* Methods with no arguments are simplified, provided argumentIndex is not specified | ||
* (assuming that returnType and receiverType - if specified - are a match) | ||
* Uses "properties_test_noFlag.json" as the config file. | ||
* Note that "Piranha:FlagName" is not considered when argumentIndex is not specified. |
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.
Out of curiosity: will this work only for versions of the method that take zero args?
My worry here is that a misconfiguration, where Piranha:FlagName
is empty, and the argumentIndex
is missing, it will go and delete half the code. We probably don't want that behavior. @Murali ??
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 we'd want any code that would delete experimentation.isToggleEnabled(SOME_FLAG) { ... }
for every possible value of SOME_FLAG
at once to error out by default. If someone really needs to do this, we can add a Piranha:AllowMassRemoval=true
argument or something. It just feels like the kind of thing that might scare new users from trying piranha if they don't configure it right.
Unless I am mistaken and this case will only delete treatment methods with zero args.
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.
My understanding is that this will only delete methods listed in the properties.json without checking for flagname in argument. At worst, this will delete all calls to an API if the argumentIndex is not specified. Your point on getting the configuration right is valid too.
Let us leave this functionality as it is in the current version of the PR and if it becomes a source of confusion, let us revisit 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 feel that worst case scenario is really really bad. Consider the effects of trying out Piranha in Uber's monorepos under those conditions, it would locally rewrite maybe hundreds of thousands of lines of code... and scare many people from ever trying it again.
I am fine with that check being a follow-up task, but I'd want to have it in place before we cut any release with this (it's already tricky enough that we are switching the config file format)
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.
Also for a follow up task (I can do it): Print a message whenever the config points to a file ending in .properties
explaining the format change and linking the docs in case someone is just upgrading Piranha.
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.
How about this:
a) By default, argumentIndex is a required parameter in json.
b) Using a configuration option (as you point above), this can be made optional.
(a) will be good for most users and in cases, where a user wants to delete all calls to the API, (b) can be used.
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.
Yup. That's exactly what I'd want. And we can add (a) to this PR and make (b) a follow up, to make this easier to land. But I'd rather have that small guardrail there than the extra functionality of deleting methods without arguments 😄
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.
^ @pranavsb Everything else is a nit and could be done later, but I'd like this one change before landing:
a) By default, argumentIndex is a required parameter in json.
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.
Also for a follow up task (I can do it): Print a message whenever the config points to a file ending in .properties explaining the format change and linking the docs in case someone is just upgrading Piranha.
Raised #49 for this. Clearly, I have issues :P
"class XPFlagCleanerSinglePositiveCase {", | ||
" private XPTest experimentation;", | ||
" public String evaluate() {", | ||
" if (experimentation.isToggleEnabled()) { int a = 1; }", |
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.
What does this code do about experimentation.isToggleEnabled(SOME_FLAG) { ... }
?
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.
As you know by now, argumentIndex not being specified would lead to all occurrences of isToggleEnabled
being removed, irrespective of its argument(s) count/value.
I'm in the process of adding ArgumentIndexOptional
Piranha argument to fix this
java/piranha/src/test/java/com/uber/piranha/XPFlagCleanerTest.java
Outdated
Show resolved
Hide resolved
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.
Mostly just the not allowing index to be missing change (see discussion above). You don't need to add the option to re-enable the empty index mode, and you can decide whether or not to address the other nits, but this one is kinda important :/
Alright I see your point about the mass deletion being confusing for new users. How about I make P.S. I'll need a few days before starting on this, but I'll be happy to work on the nits too. Let me know if you catch anything else. :) |
Instead of By adding this option, you can also leave most of the
|
Yes, that's what I meant by "enable empty index". Ok then, new Piranha option is the way. |
Sorry for that extra work, but it's a better long term solution and, compared with the rest of this PR, just adding that option will be a fairly small change, I think. I would not be comfortable releasing a new version of Piranha with "empty index" allowed by default, even if we could land this to master. |
Pushed support for
|
c35c674
to
0af7af9
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.
This is basically ready to land. I have just two short nit fixes and a question.
} | ||
methodPropertiesForMethodName.add(methodProperty); | ||
} else { |
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.
For readability, consider reversing this conditional, so you have:
if (methodName == null || getValueStringFromMap(methodProperty, FLAG_TYPE_KEY) == null) {
throw ...;
}
if (!isArgumentIndexOptional && getArgumentIndexFromMap(methodProperty) == null) {
throw ...;
}
List<Map<String, Object>> methodPropertiesForMethodName = ...;
...
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.
Also replaced the add methodProperty/new ArrayList logic with a one-liner using computeIfAbsent
@@ -372,15 +386,17 @@ private API getXPAPI( | |||
// if it's not a match, skip to next method property map | |||
String returnType = getValueStringFromMap(currentMethodProperties, RETURN_TYPE_STRING); | |||
if (returnType != null) { | |||
if (!isMethodTreeMatchesMethodProperty(mst, RETURN_TYPE_STRING, returnType)) { | |||
String mReturn = ASTHelpers.getReturnType(mst).toString(); | |||
if (!returnType.equalsIgnoreCase(mReturn)) { |
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.
Why equalsIgnoreCase
instead of case sensitive equals?
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.
Just to allow users the flexibility of wrongly capitalizing stuff. Like java.lang.string
or the fully qualified name of their class.
@lazaroclapp - waiting for your followup - if any - before pushing.
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 say let's compare case-sensitive, since Java itself is case sensitive, I think, e.g. you can have both a type com.foo.Bar
and one called com.foo.bar
at the same time in the same JVM (you probably shouldn't, but still). That said, I have no super strong opinion here. cc: @mkr-plse Any thoughts?
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.
...you can have both a type com.foo.Bar and one called com.foo.bar ...
Oh, didn't know this. Then a case sensitive match is a better default for now - just in case someone does this.
Updated and fixed testcase.
Pushed case-sensitive match for returnType and receiverType (and some refactoring) |
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.
LGTM!! 😄 🎉
Congrats and thank you for the massive contribution @pranavsb ! |
Thanks for all your help. It was good fun! :) |
Indeed, this is a massive contribution. Thanks a lot @pranavsb. Looking forward to more such contributions ;) |
This is an enhancement and a fix for #38 and #6 .
The config file is moved to
properties.json
, removing the necessity forpiranha.properties
.Return type and receiver type regexes can be specified in
properties.json
corresponding to theflagType
andmethodName
. Argument index to check against xpFlagName can also be specified. All 3 are optional fields.Please see
TODO
inXPFlagCleanerTest
. I have changedgetXPAPI
to returnAPI.UNKNOWN
if the specified method's receiver or return type don't match what is specified inproperties.json
, but I think there is some change required in some other part of the code.UPDATE: Have raised #40 for any further discussion related to this.
NOTE: Argument index is not yet implemented, so #6 is still open.