-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handling of switch expressions and rule cases in Flow and NPECheck hint. #35
base: master
Are you sure you want to change the base?
Changes from all commits
5d143fe
29b3fb7
ad7dc29
2dbc768
edd000c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -101,7 +101,8 @@ | |
import javax.lang.model.type.TypeMirror; | ||
import org.netbeans.api.java.source.CompilationInfo; | ||
import org.netbeans.api.java.source.CompilationInfo.CacheClearPolicy; | ||
import org.netbeans.api.java.source.support.CancellableTreePathScanner; | ||
import org.netbeans.api.java.source.support.CancellableTreeScanner; | ||
import org.netbeans.modules.editor.java.TreeShims; | ||
import org.netbeans.modules.java.hints.errors.Utilities; | ||
import org.netbeans.spi.java.hints.HintContext; | ||
|
||
|
@@ -353,7 +354,7 @@ public AV(TreePath path, State state) { | |
* that are qualified to belong to other scopes are ignored at the moment. | ||
* | ||
*/ | ||
private static final class VisitorImpl extends CancellableTreePathScanner<Boolean, ConstructorData> { | ||
private static final class VisitorImpl extends CancellableTreeScanner<Boolean, ConstructorData> { | ||
|
||
private final CompilationInfo info; | ||
private final TypeElement undefinedSymbolScope; | ||
|
@@ -444,11 +445,45 @@ protected boolean isCanceled() { | |
return cancel.isCanceled(); | ||
} | ||
|
||
private TreePath currentPath; | ||
|
||
public TreePath getCurrentPath() { | ||
return currentPath; | ||
} | ||
|
||
public Boolean scan(TreePath path, ConstructorData p) { | ||
TreePath oldPath = currentPath; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 455. |
||
try { | ||
currentPath = path; | ||
return super.scan(path.getLeaf(), p); | ||
} finally { | ||
currentPath = oldPath; | ||
} | ||
} | ||
|
||
@Override | ||
public Boolean scan(Tree tree, ConstructorData p) { | ||
resume(tree, resumeBefore); | ||
|
||
Boolean result = super.scan(tree, p); | ||
Boolean result; | ||
|
||
if (tree != null) { | ||
TreePath oldPath = currentPath; | ||
try { | ||
currentPath = new TreePath(currentPath, tree); | ||
if (TreeShims.SWITCH_EXPRESSION.equals(tree.getKind().name())) { | ||
result = visitSwitchExpression(tree, p); | ||
} else if (TreeShims.YIELD.equals(tree.getKind().name())) { | ||
result = visitYield(tree, p); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 477. |
||
} else { | ||
result = super.scan(tree, p); | ||
} | ||
} finally { | ||
currentPath = oldPath; | ||
} | ||
} else { | ||
result = null; | ||
} | ||
|
||
resume(tree, resumeAfter); | ||
|
||
|
@@ -1172,37 +1207,63 @@ public Boolean visitBreak(BreakTree node, ConstructorData p) { | |
|
||
Tree target = info.getTreeUtilities().getBreakContinueTargetTree(getCurrentPath()); | ||
|
||
resumeAfter(target, variable2State); | ||
breakTo(target); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 1210. |
||
|
||
variable2State = new HashMap< Element, State>(); | ||
return null; | ||
} | ||
|
||
public Boolean visitYield(Tree node, ConstructorData p) { | ||
scan(TreeShims.getYieldValue(node), p); | ||
|
||
Tree target = info.getTreeUtilities().getBreakContinueTargetTree(getCurrentPath()); | ||
|
||
breakTo(target); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 1220. |
||
|
||
return null; | ||
} | ||
|
||
private void breakTo(Tree target) { | ||
resumeAfter(target, variable2State); | ||
|
||
variable2State = new HashMap<>(); | ||
} | ||
|
||
public Boolean visitSwitch(SwitchTree node, ConstructorData p) { | ||
scan(node.getExpression(), null); | ||
generalizedSwitch(node, node.getExpression(), node.getCases()); | ||
return null; | ||
} | ||
|
||
public Boolean visitSwitchExpression(Tree node, ConstructorData p) { | ||
generalizedSwitch(node, TreeShims.getExpressions(node).get(0), TreeShims.getCases(node)); | ||
return null; //never a constant expression | ||
} | ||
|
||
private void generalizedSwitch(Tree switchTree, ExpressionTree expression, List<? extends CaseTree> cases) { | ||
scan(expression, null); | ||
|
||
Map< Element, State> origVariable2State = new HashMap< Element, State>(variable2State); | ||
|
||
variable2State = new HashMap< Element, State>(); | ||
|
||
boolean exhaustive = false; | ||
|
||
for (CaseTree ct : node.getCases()) { | ||
for (CaseTree ct : cases) { | ||
variable2State = mergeOr(variable2State, origVariable2State); | ||
|
||
if (ct.getExpression() == null) { | ||
exhaustive = true; | ||
} | ||
|
||
scan(ct, null); | ||
|
||
if (TreeShims.isRuleCase(ct)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 1259. |
||
breakTo(switchTree); | ||
} | ||
} | ||
|
||
if (!exhaustive) { | ||
variable2State = mergeOr(variable2State, origVariable2State); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
public Boolean visitEnhancedForLoop(EnhancedForLoopTree node, ConstructorData p) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line 105.