Conversation
…a partial fix because each change uncovered another subtle issue. Still work to be done.
| || MapEntry.class == baseType ) | ||
| baseType = Map.class; | ||
| if (dimensions < 2) | ||
| if ( MapEntry.class == inferType && Void.TYPE == baseType |
There was a problem hiding this comment.
OperatorPrecedence: Use grouping parenthesis to make the operator precedence explicit
| if ( MapEntry.class == inferType && Void.TYPE == baseType | |
| if ( (MapEntry.class == inferType && Void.TYPE == baseType) |
ℹ️ Expand to see all @sonatype-lift commands
You can reply with the following commands. For example, reply with @sonatype-lift ignoreall to leave out all findings.
| Command | Usage |
|---|---|
@sonatype-lift ignore |
Leave out the above finding from this PR |
@sonatype-lift ignoreall |
Leave out all the existing findings from this PR |
@sonatype-lift exclude <file|issue|path|tool> |
Exclude specified file|issue|path|tool from Lift findings by updating your config.toml file |
Note: When talking to LiftBot, you need to refresh the page to see its response.
Click here to add LiftBot to another repo.
Help us improve LIFT! (Sonatype LiftBot external survey)
Was this a good recommendation for you? Answering this survey will not impact your Lift settings.
[ 🙁 Not relevant ] - [ 😕 Won't fix ] - [ 😑 Not critical, will fix ] - [ 🙂 Critical, will fix ] - [ 😊 Critical, fixing now ]
🛠 Lift Auto-fixSome of the Lift findings in this PR can be automatically fixed. You can download and apply these changes in your local project directory of your branch to review the suggestions before committing.1 # Download the patch
curl https://lift.sonatype.com/api/patch/github.com/beanshell/beanshell/732.diff -o lift-autofixes.diff
# Apply the patch with git
git apply lift-autofixes.diff
# Review the changes
git diffWant it all in a single command? Open a terminal in your project's directory and copy and paste the following command: curl https://lift.sonatype.com/api/patch/github.com/beanshell/beanshell/732.diff | git applyOnce you're satisfied, commit and push your changes in your project. Footnotes |
Adjust test to reflect new error message resulting from change.
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## master #732 +/- ##
============================================
+ Coverage 74.24% 74.35% +0.11%
- Complexity 3041 3051 +10
============================================
Files 108 108
Lines 9354 9368 +14
Branches 1857 1864 +7
============================================
+ Hits 6945 6966 +21
+ Misses 2070 2063 -7
Partials 339 339
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
|
I took another look and was able to fix the remaining issues, the fix just had to gestate. By the way This PR should be ready to merge. |
nickl-
left a comment
There was a problem hiding this comment.
More nitpicking than much else, over all looks good. Just worried about arrayElementType...
| else | ||
| throw new EvalError( | ||
| "Array dimensions not allowed on both type and name: " | ||
| + name, this, null ); |
There was a problem hiding this comment.
This seems like an easy enough test to add.
| baseType = Map.class; | ||
| if (dimensions < 2) | ||
| if ( MapEntry.class == inferType && Void.TYPE == baseType | ||
| || MapEntry.class == baseType ) |
There was a problem hiding this comment.
Seems like a fair suggestion, I know the code didn't change but it came under review now.
There was a problem hiding this comment.
Reference to Lift's suggestion, now seems to be lost.
OperatorPrecedence: Use grouping parenthesis to make the operator precedence explicit
| if ( MapEntry.class == inferType && Void.TYPE == baseType | ||
| || MapEntry.class == baseType ) | ||
| baseType = Map.class; | ||
| if (dimensions < 2) |
There was a problem hiding this comment.
Why does the dimensions matter again?
There was a problem hiding this comment.
It cannot be coerced to a map if there are more than two dimensions
| // the values are set. | ||
| dims[0] = jjtGetNumChildren(); | ||
| Object array = Array.newInstance( baseType, dims ); | ||
| Class<?> entryType = array.getClass().getComponentType(); |
There was a problem hiding this comment.
Isn't this what arrayElementType is supposed to do? I am still curious if that is not broken.
There was a problem hiding this comment.
Do you mean Types.arrayELementType()? That will return the ultimate base type of the array, so for int[][] it will return int. However here we want the type for the current dimension, which would be int[].
| public static Object castObject( Class<?> toType, Class<?> fromType, Object fromValue, | ||
| int operation, boolean checkOnly ) throws UtilEvalError { | ||
| // assignment to loose type, void type, or exactly same type | ||
| if ( toType == null || arrayElementType(toType) == arrayElementType(fromType) ) |
There was a problem hiding this comment.
What happens if we fix arrayElementType, I am wondering if this does not cause problems elsewhere...
There was a problem hiding this comment.
There is nothing wrong with the way the arrayElementType works, it is just that it is not appropriate here. You cannot just test for equality by comparing the ultimate base types because the number of dimensions might be different.
| int operation, boolean checkOnly ) throws UtilEvalError { | ||
| // assignment to loose type, void type, or exactly same type | ||
| if ( toType == null || arrayElementType(toType) == arrayElementType(fromType) ) | ||
| if ( toType == null || toType == fromType ) |
There was a problem hiding this comment.
However this condition does satisfy the comments, for what that's worth.
| assert(isEvalError("Class: Unknow.ObjectType not found in namespace", "new Unknow.ObjectType[0];")); | ||
| assert(isEvalError("Incompatible initializer. Allocation calls for a 2 dimensional array, but initializer is a 1 dimensional array", "new int[][] {};")); | ||
| assert(isEvalError("Incompatible type: boolean in initializer of array type: boolean", "new {{false}, true};")); | ||
| assert(isEvalError("Error in array initializer: Cannot cast primitive value to object type [Z", "new {{false}, true};")); |
|
Hopefully this can be merged |
Been a while, will need to pick up again to see where we are at. |
|
Has this been merged? If so should be closed. |
This is only a partial fix because each change uncovered another subtle issue. Still work to be done. I am posting this PR so that someone else who has a better idea of how this is supposed to work can at least see some of the issues that I found.
Fixing the issue for proper matching of the most specific method broke several other code paths that depended on the loose behaviour of the
Types.castObjectmethod.Other issues that popped up that I also fixed included:
Types.castObject, wasn't a problem before)Unfortunately as I made changes more issues started to crop up and I just ran out of time. For example
new {{false}, true};no longer compiles and executes correctly. This looks to me like it shouldn't work anyway, because it is not a proper 2D array.entries = {{new Entry {"k"=3, "l"=5}, {6}}};should get typed asObject[][][]but now is getting typed as 'MapEntry[][][]` and this fails.I suspect that I might have been going down the wrong track with some of my changes. Perhaps there is a simpler way to fix the original problem that does not cause so much other collateral damage.