[
https://issues.apache.org/jira/browse/GROOVY-7971?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18044236#comment-18044236
]
ASF GitHub Bot commented on GROOVY-7971:
----------------------------------------
eric-milles opened a new pull request, #2353:
URL: https://github.com/apache/groovy/pull/2353
NOTE: I still have some refactoring to do to make the push/pop/peek
interactions with the temp type info data structure a bit better. I thought I
would get this in front of you to see the solution design. I also try not to
use union and intersection to maintain clarity.
see also #1293 and #1269
```groovy
if (x instanceof String || x instanceof Number || x instanceof Pattern)
x.something()
```
```groovy
switch (x) {
case String:
case Number:
case Pattern:
x.something()
}
```
Treat both of these cases as typeof(x) is (String | Number | Pattern) for
STC. Maybe extend to `catch (Exception | Error e)`.
The `UnionTypeClassNode` represents the any-of type alternatives, as
described in its javadoc. So use it for that, not for all-of types.
`LowestUpperBoundClassNode` is one type that represents (Type & Serializable)
for example. I did not want to overload its usage, so I opted to create a
`ClassNode` instance with abstract modifier, Type as the super class, and
Serializable as one interface. See `getInferredTypeFromTempInfo`.
The duck-typing is in place for a `UnionTypeClassNode`. Thus 8965 (Deque
and Stack peek) keeps working. I modified the switch case handling to collect
types together in a union so the temp types list represents the and
relationship and any element of the list may represent an or relationship (that
is be an `UnionTypeClassNode`).
When processing a logical-or binary expression, temp types are collected for
left and right sides. If an `instanceof` expression appears on either side, a
(T | U) type is created and added to the temp type list. The logical-and
binary expression remanins as before, adding any `instanceof` types from left
or right expression directly to the temp type list as strong guarantees.
> @CS flow typing incorrectly casting to map at runtime
> -----------------------------------------------------
>
> Key: GROOVY-7971
> URL: https://issues.apache.org/jira/browse/GROOVY-7971
> Project: Groovy
> Issue Type: Bug
> Affects Versions: 2.4.7
> Reporter: Graeme Rocher
> Assignee: Eric Milles
> Priority: Major
> Time Spent: 4h 10m
> Remaining Estimate: 0h
>
> The following code:
> {code}
> import groovy.json.*
> import groovy.transform.*
> @CompileStatic
> class Bar {
> private Writable renderTemplate(Object o, Map args) {
>
> }
> private boolean isSimpleType(Class type) {
> return type == String
> }
> def foo(Map map, Map arguments) {
>
> def writable = new Writable() {
> @Override
> Writer writeTo(Writer out) throws IOException {
> for(entry in map.entrySet()) {
> def value = entry.value
> if(isSimpleType(value.getClass()) || (value instanceof
> Map)) {
> out.append(JsonOutput.toJson(value))
> }
> }
> return out
> }
> }
> }
> }
> writable = new Bar().foo([one:'two'],[foo:'bar'])
> sw = new StringWriter()
> writable.writeTo(sw)
> println sw
> {code}
> Fails with:
> {code}
> org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast
> object 'two' with class 'java.lang.String' to class 'java.util.Map'
> at
> org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:405)
> at
> org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:319)
> at
> org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:232)
>
> {code}
> For some reason Groovy is attempting to cast value to Map when it isn't one.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)