JDK-8076281 : Investigate compiler Tree API client's expectations for inferred elided types.
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 9
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2015-03-30
  • Updated: 2017-10-30
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbd_majorUnresolved
Related Reports
Relates :  
Relates :  
Description
This is a follow up ticket from https://bugs.openjdk.java.net/browse/JDK-8062373 (Coins - <>
inference with anonymous classes) to investigate what exactly (if anything) needs to change
with respect to how the AST should appear to a Tree API client when certain types are elided
in the source code and are inferred during attribution.

Specifically after <> inference (with or without anonymous classes in the picture), should the
compiler "fill in" the diamond in the AST with tree nodes representing the inferred elided types
or whether a client should rely on other "decorations" in the tree to discover the elided types ?

One school of thought would be to leave the tree to be a pure AST representation of the source.
But in general javac munges the tree in so many ways that this model is not the norm.

I'll investigate what exactly needs to be done.
Comments
@Jan, I think you are correct about Attr.visitLambda being the place where the elided parameter types are filled in. I think I was misled by the fact even after this point, a breakpoint in JavaCompiler.java:1453 shows env.tree to be: public class X { public X() { super(); } I i = (x,y)->{ }; } but if you step over this line of code you see the tree to be: public class X { public X() { super(); } I i = java.lang.invoke.LambdaMetafactory.metafactory(); /*synthetic*/ private static void lambda$new$0(int x, String y) { } }
01-04-2015

I don't think the vartypes for implicit lambda params are set in LTM - to my knowledge, they are set in Attr.visitLambda. Note that the clients can easily get the inferred type (for ordinary diamond at least) by using Trees.getTypeMirror.
01-04-2015

For the record, Inferred types of implicit lambda's parameter types get on the bus in LambdaToMethod which runs as a part of desugar, post transtypes. So right after attribution lambda parameters are type less as far as the AST sans decorations are concerned.
01-04-2015

I guess what I'm trying to say is that there could be multiple version of the same tree a given could be interested in. Sometimes, 100% fidelity is needed - other times you just don't want to care about inference, and would like to just get the types as you would have written them out. Maybe there's no official API for it - but I think something like this could be very useful for clients (i.e. REPL?)
31-03-2015

Filtering the synthetic trees at API level has been proposed before, and was generally considered as hacky. But it is surely a possible way to solve most of JDK-8024098 (enum constants need something more, so not all of JDK-8024098 can be done by mere filtering). But, if we would filter out the "diamond" types at the API level, why fill them at all? My understanding is that it would not help the implementation (would in fact complicate it I think), and constructing something just to filter out it later does not seem like a good direction to me. In the lambda param case, my understanding is that adding the type there simplifies some parts of the implementation, and so there is a reason for it (although it would be cleaner to not add the type into the AST).
31-03-2015

I believe it's not all so crystal clear - there are other cases where inferred types end up in the AST - namely inferred lambda parameter types; I'm totally happy with not throwing in synthetic types, but then we should do it consistently on _all_ inferred types - I think the problem here is that we are treating this as an all or nothing decision - there's no reason why we couldn't create synthetic type nodes which are tagged in such a way so that we can better control how they are exposed back to clients, either in the printer or in the compiler API.
31-03-2015

Jan, Thanks for weighing in - personally I am in agreement, which is why I deferred it out of https://bugs.openjdk.java.net/browse/JDK-8062373 so we can take the time to look into this and not rush in. FWIW, on other compilers I have worked on, modifying the AST in a manner the changes are visible to the tree API client is an absolute no no. Because there are use cases where modifications may be done programmatically by the API client and the modified AST may be "flattened" to feedback into the editor buffer - A code formatter may be implemented thus for example. Let us wait for others to chime in with their views and decide the course of action.
31-03-2015

I think the AST should be kept as is, to represent what is in the source code. The synthetic AST nodes are usually causing trouble to the API clients are bring only little benefit. Even though the are currently synthetic nodes in the AST, that is considered undesirable (JDK-8024098), and making the situation even worse seems even less desirable to me.
31-03-2015