8266027: The diamond finder does not find diamond candidates in field initializers

Reviewed-by: jfranck, vromero
This commit is contained in:
Jan Lahoda 2021-04-29 14:55:28 +00:00
parent 8072ea5628
commit f0f6b0d919
3 changed files with 63 additions and 2 deletions

View File

@ -35,6 +35,7 @@ import java.util.stream.Collectors;
import com.sun.source.tree.LambdaExpressionTree;
import com.sun.source.tree.NewClassTree;
import com.sun.source.tree.VariableTree;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Kinds.Kind;
import com.sun.tools.javac.code.Source;
@ -556,14 +557,17 @@ public class Analyzer {
log.useSource(rewriting.env.toplevel.getSourceFile());
JCStatement treeToAnalyze = (JCStatement)rewriting.originalTree;
JCTree wrappedTree = null;
if (rewriting.env.info.scope.owner.kind == Kind.TYP) {
//add a block to hoist potential dangling variable declarations
treeToAnalyze = make.at(Position.NOPOS)
.Block(Flags.SYNTHETIC, List.of((JCStatement)rewriting.originalTree));
wrappedTree = rewriting.originalTree;
}
//TODO: to further refine the analysis, try all rewriting combinations
deferredAttr.attribSpeculative(treeToAnalyze, rewriting.env, attr.statInfo, new TreeRewriter(rewriting),
deferredAttr.attribSpeculative(treeToAnalyze, rewriting.env, attr.statInfo, new TreeRewriter(rewriting, wrappedTree),
() -> rewriting.diagHandler(), AttributionMode.ANALYZER, argumentAttr.withLocalCacheContext());
rewriting.analyzer.process(rewriting.oldTree, rewriting.replacement, rewriting.erroneous);
} catch (Throwable ex) {
@ -768,9 +772,11 @@ public class Analyzer {
class TreeRewriter extends AnalyzerCopier {
RewritingContext rewriting;
JCTree wrappedTree;
TreeRewriter(RewritingContext rewriting) {
TreeRewriter(RewritingContext rewriting, JCTree wrappedTree) {
this.rewriting = rewriting;
this.wrappedTree = wrappedTree;
}
@Override
@ -783,5 +789,19 @@ public class Analyzer {
}
return newTree;
}
@Override
public JCTree visitVariable(VariableTree node, Void p) {
JCTree result = super.visitVariable(node, p);
if (node == wrappedTree) {
//The current tree is a field and has been wrapped by a block, so it effectivelly
//became local variable. If it has some modifiers (except for final), an error
//would be reported, causing the whole rewrite to fail. Removing the non-final
//modifiers from the variable here:
((JCVariableDecl) result).mods.flags &= Flags.FINAL;
}
return result;
}
}
}

View File

@ -0,0 +1,29 @@
/**
* @test /nodynamiccopyright/
* @bug 8266027
* @summary Verify the diamond finder works on fields with modifiers.
* @compile/ref=DiamondFields.out -XDfind=diamond -XDrawDiagnostics DiamondFields.java
*/
import java.util.LinkedList;
import java.util.List;
public class DiamondFields {
List<String> f1 = new LinkedList<String>();
private List<String> f2 = new LinkedList<String>();
static List<String> f3 = new LinkedList<String>();
@Deprecated List<String> f4 = new LinkedList<String>();
final List<String> f5 = new LinkedList<String>();
DiamondFields() {
List<String> l1 = new LinkedList<String>();
final List<String> l2 = new LinkedList<String>();
@Deprecated List<String> l3 = new LinkedList<String>();
}
void t() {
List<String> l1 = new LinkedList<String>();
final List<String> l2 = new LinkedList<String>();
@Deprecated List<String> l3 = new LinkedList<String>();
}
}

View File

@ -0,0 +1,12 @@
DiamondFields.java:12:49: compiler.warn.diamond.redundant.args
DiamondFields.java:13:49: compiler.warn.diamond.redundant.args
DiamondFields.java:14:49: compiler.warn.diamond.redundant.args
DiamondFields.java:15:49: compiler.warn.diamond.redundant.args
DiamondFields.java:16:49: compiler.warn.diamond.redundant.args
DiamondFields.java:19:41: compiler.warn.diamond.redundant.args
DiamondFields.java:20:47: compiler.warn.diamond.redundant.args
DiamondFields.java:21:53: compiler.warn.diamond.redundant.args
DiamondFields.java:25:41: compiler.warn.diamond.redundant.args
DiamondFields.java:26:47: compiler.warn.diamond.redundant.args
DiamondFields.java:27:53: compiler.warn.diamond.redundant.args
11 warnings