UcasRichard / snakeyaml

Automatically exported from code.google.com/p/snakeyaml
Apache License 2.0
0 stars 0 forks source link

Fix generics in BaseRepresenter.representMapping() #171

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
You can't pass strongly typed Map (Map<String,Collection<OtherType>> in example 
case) to BaseRepresenter.representMapping():

private class RepresentTenantNode implements Represent {
    @Override
    public Node representData(final Object data) {
        final SomeObject obj = (SomeObject) data;
        return representMapping(Tag.MAP, obj.services, false);
    }
}

will produce:
The method representMapping(Tag, Map<? extends Object,Object>, Boolean) in the 
type BaseRepresenter is not applicable for the arguments (Tag, 
Map<String,Collection<OtherType>>, boolean)

You have to workaround it by castings:
private class RepresentTenantNode implements Represent {
    @Override
    public Node representData(final Object data) {
        final SomeObject obj = (SomeObject) data;
        // workaround for typing bug in SnakeYaml =(
        @SuppressWarnings({ "rawtypes", "unchecked" })
        final Map<String, Object> services = (Map) obj.services;
        return representMapping(Tag.MAP, services, false);
    }
}

What is the expected output? What do you see instead?
I expect to be able to pass Map without casts. I.e. method's signature should be

Node representMapping(Tag tag, Map<?, ?> mapping, Boolean flowStyle)

because it don't care for types.
What version of SnakeYAML are you using? On what Java version?
1.11, 1.12

Please provide any additional information below. (Often a failing test is
the best way to describe the problem.)

Also
representSequence(Tag tag, Iterable<? extends Object> sequence, Boolean 
flowStyle)
can be simplified too:
representSequence(Tag tag, Iterable<?> sequence, Boolean flowStyle)

Original issue reported on code.google.com by Ash2kk@gmail.com on 27 Mar 2013 at 9:44

GoogleCodeExporter commented 9 years ago
If you have compilation problems, can you please provide some complete code 
that should compile after the change ?

Original comment by py4fun@gmail.com on 27 Mar 2013 at 4:48

GoogleCodeExporter commented 9 years ago
Something like this:

class ClassX {
  public final Map<String, Collection<Integer>> services = new HashMap<>();
}

class CustomRepresenter extends Representer {
  public CustomRepresenter() {
    this.representers.put(ClassX.class, new RepresentClassX());
  }

  private class RepresentClassX implements Represent {
    @Override
    public Node representData(Object data) {
      ClassX classX = (ClassX) data;
      return representMapping(Tag.MAP, classX.services, false);
    }
  }
}

You can't pass Map<String, Collection<Integer>> into method that accepts Map<? 
extends Object, Object>.

Original comment by Ash2kk@gmail.com on 29 Mar 2013 at 6:58

GoogleCodeExporter commented 9 years ago

Original comment by py4fun@gmail.com on 30 Mar 2013 at 8:18

GoogleCodeExporter commented 9 years ago

Original comment by py4fun@gmail.com on 30 Mar 2013 at 8:19

GoogleCodeExporter commented 9 years ago
Fixed. Feel free to try the latest snapshot. Please check if it works for you. 

http://code.google.com/p/snakeyaml/source/list

Original comment by py4fun@gmail.com on 30 Mar 2013 at 2:15

GoogleCodeExporter commented 9 years ago
That works, thanks!

Original comment by Ash2kk@gmail.com on 9 Apr 2013 at 12:41

GoogleCodeExporter commented 9 years ago
It will be delivered in version 1.13

Original comment by py4fun@gmail.com on 9 Apr 2013 at 6:15