RFR JDK-8188225: AST could be improved in presence of var types.
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Tue Oct 3 17:58:56 UTC 2017
On 03/10/17 18:53, Jan Lahoda wrote:
> Hi Maurizio,
>
> Thanks for the comments - some responses inline.
>
> On 3.10.2017 17:59, Maurizio Cimadamore wrote:
>> Thanks for taking care of this, I have a couple of suggestion:
>>
>> * the routine for generating synthetic type tree should be shared. E.g.
>> you need a method that takes a type and generates something that is
>> suitable for a local variable or a lambda parameter - e.g.
>>
>> toSyntheticTypeTree(Type t) {
>> if (t.isErroneous()) {
>> return make.at(Position.NOPOS).Erroneous();
>> } else {
>> return make.at(Position.NOPOS).Type(t);
>> }
>> }
>
> Sure, will do.
>
>>
>> * secondly, while adding the startpos tree is fine - here it seems like
>> we morally would like to override the getStartPosition for the synthetic
>> type trees created above, so that the former position is returned (e.g.
>> that of 'var'). So, I wonder if something like this could work:
>>
>> toSyntheticTypeTree(Type t, int preferredPos) {
>> if (t.isErroneous()) {
>> return make.at(preferredPos).Erroneous();
>> } else {
>> return make.at(preferredPos).Type(t);
>> }
>> }
>>
>> Then, assuming the parser creates the local variable node with the
>> correct pos (which it doesn't now), I think everything should work even
>
> Hm, you mean put the starting position to the JCVariableDecl.pos? If
> that would be the value, we could surely avoid the field, but AFAIK
> the JCVariableDecl.pos usually points to the name of the variable, and
> I didn't want to add an inconsistency, or change that (as the position
> is useful for error reporting),
>
> Alternatives I was thinking of included playing tricks with modifiers
> (setting the position to modifiers (if there are no/empty modifiers)
> and filtering it in getStartPos), with nameexpr or having a subclass
> of JCVariableDecl for vars which would include the extra field.
I see good points. I also thought about using a tree copier, but that
also goes through TreeMaker, which makes it hard to e.g. create anon
tree instances which override getStartPosition.
No bother - your original solution is good enough, at least for now. I
appreciate that the new pos field is just for var AST nodes.
Maurizio
>
> (I was also trying to have -1 as the position of the synthetic type to
> aid its detection, but it could still be detected by looking at the
> end position, so this is not that big deal.)
>
> Thanks,
> Jan
>
>> w/o a dedicated field?
>>
>> Maurizio
>>
>>
>>
>>
>> On 02/10/17 16:35, Jan Lahoda wrote:
>>> Hello,
>>>
>>> JShell produces not ideal errors related to local variable type
>>> inference in some cases:
>>> ---
>>> jshell> var i = () -> {};
>>> | Error:
>>> | incompatible types: java.lang.Object is not a functional interface
>>> | var i = () -> {};
>>> | ^------^
>>> ---
>>>
>>> Better would be:
>>> ---
>>> jshell> var i = () -> {};
>>> | Error:
>>> | cannot infer type for local variable i
>>> | (lambda expression needs an explicit target-type)
>>> | var i = () -> {};
>>> | ^---------------^
>>> ---
>>>
>>> (which is the error produced by javac)
>>>
>>> The AST model could also be improved for local variables whose type
>>> have been inferred (which also improves the jshell errors in some
>>> cases):
>>> - for "var i = 0;", the VariableTree.getType() will be null even after
>>> attribution, but for: "for (var i : Arrays.asList(0, 1)) {}", the
>>> VariableTree.getType() will be filled in by Attr. (The inferred type
>>> is also filled in for lambda parameters.) This is not only
>>> inconsistent, but also Attr.PostAttrAnalyzer.visitVarDef may fill in
>>> the type with an ErroneousTree (with a wrong position). The proposal
>>> here is to always fill in the type for consistency, and to
>>> consistently use NOPOS for the synthetic type position
>>>
>>> -for "var i = 0;" SourcePositions.getStartPosition does not return a
>>> proper starting position (the position of "var"), but rather the
>>> position of the synthetic type, if any (which can also be
>>> ErroneousTree) or the position of the variable name. The proposal here
>>> is to remember the real start of the variable and return it.
>>>
>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8188225
>>> Webrev:
>>> http://cr.openjdk.java.net/~jlahoda/8188225/webrev.00/index.html
>>>
>>> What do you think?
>>>
>>> Thanks,
>>> Jan
>>
More information about the kulla-dev
mailing list