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.LambdaExpressionTree;
import com.sun.source.tree.NewClassTree; 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.Flags;
import com.sun.tools.javac.code.Kinds.Kind; import com.sun.tools.javac.code.Kinds.Kind;
import com.sun.tools.javac.code.Source; import com.sun.tools.javac.code.Source;
@ -556,14 +557,17 @@ public class Analyzer {
log.useSource(rewriting.env.toplevel.getSourceFile()); log.useSource(rewriting.env.toplevel.getSourceFile());
JCStatement treeToAnalyze = (JCStatement)rewriting.originalTree; JCStatement treeToAnalyze = (JCStatement)rewriting.originalTree;
JCTree wrappedTree = null;
if (rewriting.env.info.scope.owner.kind == Kind.TYP) { if (rewriting.env.info.scope.owner.kind == Kind.TYP) {
//add a block to hoist potential dangling variable declarations //add a block to hoist potential dangling variable declarations
treeToAnalyze = make.at(Position.NOPOS) treeToAnalyze = make.at(Position.NOPOS)
.Block(Flags.SYNTHETIC, List.of((JCStatement)rewriting.originalTree)); .Block(Flags.SYNTHETIC, List.of((JCStatement)rewriting.originalTree));
wrappedTree = rewriting.originalTree;
} }
//TODO: to further refine the analysis, try all rewriting combinations //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.diagHandler(), AttributionMode.ANALYZER, argumentAttr.withLocalCacheContext());
rewriting.analyzer.process(rewriting.oldTree, rewriting.replacement, rewriting.erroneous); rewriting.analyzer.process(rewriting.oldTree, rewriting.replacement, rewriting.erroneous);
} catch (Throwable ex) { } catch (Throwable ex) {
@ -768,9 +772,11 @@ public class Analyzer {
class TreeRewriter extends AnalyzerCopier { class TreeRewriter extends AnalyzerCopier {
RewritingContext rewriting; RewritingContext rewriting;
JCTree wrappedTree;
TreeRewriter(RewritingContext rewriting) { TreeRewriter(RewritingContext rewriting, JCTree wrappedTree) {
this.rewriting = rewriting; this.rewriting = rewriting;
this.wrappedTree = wrappedTree;
} }
@Override @Override
@ -783,5 +789,19 @@ public class Analyzer {
} }
return newTree; 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