Moving scoping from file's Context to HintContext/SPI.
1.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/hints/HintsInvoker.java Sat Jan 22 19:28:36 2011 +0100
1.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/hints/HintsInvoker.java Sat Jan 22 21:51:05 2011 +0100
1.3 @@ -456,14 +456,21 @@
1.4 continue;
1.5
1.6 if (hd.getWorker() instanceof MarksWorker) {
1.7 + HintContext workerContext = new HintContext(c);
1.8 +
1.9 + workerContext.enterScope();
1.10 +
1.11 MarksWorker mw = (MarksWorker) hd.getWorker();
1.12 List<FixEvaluationData> fixData = new LinkedList<FixEvaluationData>();
1.13
1.14 for (DeclarativeFixDescription fd : mw.fixes) {
1.15 - fixData.add(new FixEvaluationData(new LinkedList<MarkCondition>(fd.marks), fd.acceptor, fd.fix));
1.16 + HintContext fixContext = new HintContext(workerContext);
1.17 +
1.18 + fixContext.enterScope();
1.19 + fixData.add(new FixEvaluationData(fixContext, new LinkedList<MarkCondition>(fd.marks), fd.acceptor, fd.fix));
1.20 }
1.21
1.22 - HintEvaluationData data = new HintEvaluationData(c, hd, new LinkedList<MarkCondition>(mw.marks), mw.acceptor, fixData);
1.23 + HintEvaluationData data = new HintEvaluationData(workerContext, hd, new LinkedList<MarkCondition>(mw.marks), mw.acceptor, fixData);
1.24
1.25 evaluationData.add(data);
1.26 continue;
1.27 @@ -497,10 +504,9 @@
1.28
1.29 for (Iterator<HintEvaluationData> it = evaluationData.iterator(); it.hasNext(); ) {
1.30 HintEvaluationData hed = it.next();
1.31 - HintContext ctx = hed.ctx;
1.32 int origMarksSize = hed.marks.size();
1.33
1.34 - Boolean hres = processConditions(ctx, marks, hed.marks);
1.35 + Boolean hres = processConditions(hed.ctx, marks, hed.marks);
1.36
1.37 currentWasChange |= origMarksSize != hed.marks.size();
1.38
1.39 @@ -511,9 +517,9 @@
1.40
1.41 if (hres != null && !hres) {
1.42 currentWasChange = true;
1.43 - clearSpeculativeAssignments(ctx, hed.marks, marks);
1.44 + clearSpeculativeAssignments(hed.ctx, hed.marks, marks);
1.45 for (FixEvaluationData fed : hed.fixDescriptions) {
1.46 - clearSpeculativeAssignments(ctx, fed.marks, marks);
1.47 + clearSpeculativeAssignments(hed.ctx, fed.marks, marks);
1.48 }
1.49 it.remove();
1.50 continue;
1.51 @@ -522,20 +528,20 @@
1.52 for (Iterator<FixEvaluationData> fixes = hed.fixDescriptions.iterator(); fixes.hasNext(); ) {
1.53 FixEvaluationData fed = fixes.next();
1.54 int o = fed.marks.size();
1.55 - Boolean res = processConditions(ctx, marks, fed.marks);
1.56 + Boolean res = processConditions(fed.ctx, marks, fed.marks);
1.57
1.58 currentWasChange |= o != fed.marks.size();
1.59
1.60 if (res == null) continue;
1.61
1.62 if (res) {
1.63 - if (fed.acceptor.accept(ctx)) {
1.64 - Fix fix = JavaFix.rewriteFix(ctx.getInfo(), "XXX: todo", ctx.getPath(), fed.fix, ctx.getVariables(), ctx.getMultiVariables(), ctx.getVariableNames(), Collections.<String, TypeMirror>emptyMap()/*XXX*/ /*XXX: , imports*/);
1.65 + if (fed.acceptor.accept(fed.ctx)) {
1.66 + Fix fix = JavaFix.rewriteFix(fed.ctx.getInfo(), "XXX: todo", fed.ctx.getPath(), fed.fix, fed.ctx.getVariables(), fed.ctx.getMultiVariables(), fed.ctx.getVariableNames(), Collections.<String, TypeMirror>emptyMap()/*XXX*/ /*XXX: , imports*/);
1.67
1.68 hed.createdFixes.add(fix);
1.69 }
1.70 } else {
1.71 - clearSpeculativeAssignments(ctx, fed.marks, marks);
1.72 + clearSpeculativeAssignments(fed.ctx, fed.marks, marks);
1.73 }
1.74
1.75 fixes.remove();
1.76 @@ -547,9 +553,9 @@
1.77 }
1.78
1.79 if (hed.fixDescriptions.isEmpty()) {
1.80 - if (hed.acceptor.accept(ctx)) {
1.81 + if (hed.acceptor.accept(hed.ctx)) {
1.82 //XXX: @SuppressWarnings!
1.83 - ErrorDescription ed = ErrorDescriptionFactory.forName(ctx, ctx.getPath(), hed.hd.getMetadata().displayName, hed.createdFixes.toArray(new Fix[0]));
1.84 + ErrorDescription ed = ErrorDescriptionFactory.forName(hed.ctx, hed.ctx.getPath(), hed.hd.getMetadata().displayName, hed.createdFixes.toArray(new Fix[0]));
1.85
1.86 merge(errors, hed.hd, ed);
1.87 }
1.88 @@ -1078,10 +1084,12 @@
1.89 }
1.90
1.91 private static final class FixEvaluationData {
1.92 + public final HintContext ctx;
1.93 public final List<MarkCondition> marks;
1.94 public final Acceptor acceptor;
1.95 public final String fix;
1.96 - public FixEvaluationData(List<MarkCondition> marks, Acceptor acceptor, String fix) {
1.97 + public FixEvaluationData(HintContext ctx, List<MarkCondition> marks, Acceptor acceptor, String fix) {
1.98 + this.ctx = ctx;
1.99 this.marks = marks;
1.100 this.acceptor = acceptor;
1.101 this.fix = fix;
2.1 --- a/api/src/org/netbeans/modules/jackpot30/spi/HintContext.java Sat Jan 22 19:28:36 2011 +0100
2.2 +++ b/api/src/org/netbeans/modules/jackpot30/spi/HintContext.java Sat Jan 22 21:51:05 2011 +0100
2.3 @@ -44,6 +44,7 @@
2.4 import java.util.Collections;
2.5 import java.util.HashMap;
2.6 import java.util.LinkedList;
2.7 +import java.util.List;
2.8 import java.util.Map;
2.9 import java.util.prefs.Preferences;
2.10 import javax.lang.model.type.TypeMirror;
2.11 @@ -63,9 +64,9 @@
2.12 private final HintSeverity severity;
2.13 private final Collection<? extends String> suppressWarningsKeys;
2.14 private final TreePath path;
2.15 - private final Map<String, TreePath> variables;
2.16 - private final Map<String, Collection<? extends TreePath>> multiVariables;
2.17 - private final Map<String, String> variableNames;
2.18 + private final List<Map<String, TreePath>> variables = new LinkedList<Map<String, TreePath>>();
2.19 + private final List<Map<String, Collection<? extends TreePath>>> multiVariables = new LinkedList<Map<String, Collection<? extends TreePath>>>();
2.20 + private final List<Map<String, String>> variableNames = new LinkedList<Map<String, String>>();
2.21 private final Collection<? super MessageImpl> messages;
2.22 private final Map<String, TypeMirror> constraints;
2.23
2.24 @@ -87,13 +88,26 @@
2.25 variables = new HashMap<String, TreePath>(variables);
2.26 variables.put("$_", path);
2.27
2.28 - this.variables = variables;
2.29 - this.multiVariables = multiVariables;
2.30 - this.variableNames = variableNames;
2.31 + this.variables.add(Collections.unmodifiableMap(variables));
2.32 + this.multiVariables.add(Collections.unmodifiableMap(multiVariables));
2.33 + this.variableNames.add(Collections.unmodifiableMap(variableNames));
2.34 this.messages = problems;
2.35 this.constraints = constraints;
2.36 }
2.37
2.38 + public HintContext(HintContext orig) {
2.39 + this.info = orig.info;
2.40 + this.preferences = orig.preferences;
2.41 + this.severity = orig.severity;
2.42 + this.suppressWarningsKeys = orig.suppressWarningsKeys;
2.43 + this.path = orig.path;
2.44 + this.variables.addAll(orig.variables);
2.45 + this.multiVariables.addAll(orig.multiVariables);
2.46 + this.variableNames.addAll(orig.variableNames);
2.47 + this.messages = orig.messages;
2.48 + this.constraints = orig.constraints;
2.49 + }
2.50 +
2.51 public CompilationInfo getInfo() {
2.52 return info;
2.53 }
2.54 @@ -110,16 +124,56 @@
2.55 return path;
2.56 }
2.57
2.58 + public void putVariable(String name, TreePath path) {
2.59 + variables.get(0).put(name, path);
2.60 + }
2.61 +
2.62 public Map<String, TreePath> getVariables() {
2.63 - return variables;
2.64 + Map<String, TreePath> result = new HashMap<String, TreePath>();
2.65 +
2.66 + for (Map<String, TreePath> m : reverse(variables)) {
2.67 + result.putAll(m);
2.68 + }
2.69 +
2.70 + return result;
2.71 }
2.72
2.73 + public void putMultiVariable(String name, Collection<? extends TreePath> path) {
2.74 + multiVariables.get(0).put(name, path);
2.75 + }
2.76 +
2.77 public Map<String, Collection<? extends TreePath>> getMultiVariables() {
2.78 - return multiVariables;
2.79 + Map<String, Collection<? extends TreePath>> result = new HashMap<String, Collection<? extends TreePath>>();
2.80 +
2.81 + for (Map<String, Collection<? extends TreePath>> m : reverse(multiVariables)) {
2.82 + result.putAll(m);
2.83 + }
2.84 +
2.85 + return result;
2.86 }
2.87
2.88 + public void putVariableName(String variable, String name) {
2.89 + variableNames.get(0).put(variable, name);
2.90 + }
2.91 +
2.92 public Map<String, String> getVariableNames() {
2.93 - return variableNames;
2.94 + Map<String, String> result = new HashMap<String, String>();
2.95 +
2.96 + for (Map<String, String> m : reverse(variableNames)) {
2.97 + result.putAll(m);
2.98 + }
2.99 +
2.100 + return result;
2.101 + }
2.102 +
2.103 + private <T> List<T> reverse(List<T> original) {
2.104 + List<T> result = new LinkedList<T>();
2.105 +
2.106 + for (T t : original) {
2.107 + result.add(0, t);
2.108 + }
2.109 +
2.110 + return result;
2.111 }
2.112
2.113 public Collection<? extends String> getSuppressWarningsKeys() {
2.114 @@ -141,6 +195,18 @@
2.115 messages.add(new MessageImpl(kind, text));
2.116 }
2.117
2.118 + public void enterScope() {
2.119 + variables.add(0, new HashMap<String, TreePath>());
2.120 + multiVariables.add(0, new HashMap<String, Collection<? extends TreePath>>());
2.121 + variableNames.add(0, new HashMap<String, String>());
2.122 + }
2.123 +
2.124 + public void leaveScope() {
2.125 + variables.remove(0);
2.126 + multiVariables.remove(0);
2.127 + variableNames.remove(0);
2.128 + }
2.129 +
2.130 //XXX: probably should not be visible to clients:
2.131 public static HintContext create(CompilationInfo info, HintMetadata metadata, TreePath path, Map<String, TreePath> variables, Map<String, Collection<? extends TreePath>> multiVariables, Map<String, String> variableNames) {
2.132 return new HintContext(info, metadata, path, variables, multiVariables, variableNames);
3.1 --- a/api/src/org/netbeans/modules/jackpot30/spi/HintDescription.java Sat Jan 22 19:28:36 2011 +0100
3.2 +++ b/api/src/org/netbeans/modules/jackpot30/spi/HintDescription.java Sat Jan 22 21:51:05 2011 +0100
3.3 @@ -250,7 +250,7 @@
3.4 }
3.5
3.6 //XXX: should be a method on the factory:
3.7 - //XXX: currently the mark conditions do not allow the clients to do any scoping, which is required by semantics of matchesWithBind
3.8 + //XXX: currently does not support ordering of custom conditions:
3.9 public static final class MarksWorker implements Worker {
3.10
3.11 public final List<MarkCondition> marks;
4.1 --- a/file/src/org/netbeans/modules/jackpot30/file/conditionapi/Context.java Sat Jan 22 19:28:36 2011 +0100
4.2 +++ b/file/src/org/netbeans/modules/jackpot30/file/conditionapi/Context.java Sat Jan 22 21:51:05 2011 +0100
4.3 @@ -71,17 +71,11 @@
4.4 public class Context {
4.5
4.6 final HintContext ctx;
4.7 - final List<Map<String, TreePath>> variables = new LinkedList<Map<String, TreePath>>();
4.8 - final List<Map<String, Collection<? extends TreePath>>> multiVariables = new LinkedList<Map<String, Collection<? extends TreePath>>>();
4.9 - final List<Map<String, String>> variableNames = new LinkedList<Map<String, String>>();
4.10 private final AtomicInteger auxiliaryVariableCounter = new AtomicInteger();
4.11
4.12 //XXX: should not be public:
4.13 public Context(HintContext ctx) {
4.14 this.ctx = ctx;
4.15 - this.variables.add(Collections.unmodifiableMap(ctx.getVariables()));
4.16 - this.multiVariables.add(Collections.unmodifiableMap(ctx.getMultiVariables()));
4.17 - this.variableNames.add(Collections.unmodifiableMap(ctx.getVariableNames()));
4.18 }
4.19
4.20 public @NonNull SourceVersion sourceVersion() {
4.21 @@ -146,7 +140,7 @@
4.22
4.23 String output = "*" + auxiliaryVariableCounter.getAndIncrement();
4.24
4.25 - variables.get(0).put(output, tp.getParentPath());
4.26 + ctx.putVariable(output, tp.getParentPath());
4.27
4.28 return new Variable(output);
4.29 }
4.30 @@ -163,10 +157,10 @@
4.31
4.32 public void createRenamed(@NonNull Variable from, @NonNull Variable to, @NonNull String newName) {
4.33 //TODO: check (the variable should not exist)
4.34 - variableNames.get(0).put(to.variableName, newName);
4.35 + ctx.putVariableName(to.variableName, newName);
4.36 TreePath origVariablePath = getSingleVariable(from);
4.37 TreePath newVariablePath = new TreePath(origVariablePath.getParentPath(), Hacks.createRenameTree(origVariablePath.getLeaf(), newName));
4.38 - variables.get(0).put(to.variableName, newVariablePath);
4.39 + ctx.putVariable(to.variableName, newVariablePath);
4.40 }
4.41
4.42 public boolean isNullLiteral(@NonNull Variable var) {
4.43 @@ -193,15 +187,11 @@
4.44 }
4.45
4.46 public void enterScope() {
4.47 - variables.add(0, new HashMap<String, TreePath>());
4.48 - multiVariables.add(0, new HashMap<String, Collection<? extends TreePath>>());
4.49 - variableNames.add(0, new HashMap<String, String>());
4.50 + ctx.enterScope();
4.51 }
4.52
4.53 public void leaveScope() {
4.54 - variables.remove(0);
4.55 - multiVariables.remove(0);
4.56 - variableNames.remove(0);
4.57 + ctx.leaveScope();
4.58 }
4.59
4.60 Iterable<? extends TreePath> getVariable(Variable v) {
4.61 @@ -220,10 +210,10 @@
4.62 //TODO: check if correct variable is provided:
4.63 TreePath getSingleVariable(Variable v) {
4.64 if (v.index == (-1)) {
4.65 - for (Map<String, TreePath> map : variables) {
4.66 - if (map.containsKey(v.variableName)) {
4.67 - return map.get(v.variableName);
4.68 - }
4.69 + Map<String, TreePath> map = ctx.getVariables();
4.70 +
4.71 + if (map.containsKey(v.variableName)) {
4.72 + return map.get(v.variableName);
4.73 }
4.74
4.75 return null;
4.76 @@ -233,10 +223,10 @@
4.77 }
4.78
4.79 private Collection<? extends TreePath> getMultiVariable(Variable v) {
4.80 - for (Map<String, Collection<? extends TreePath>> multi : multiVariables) {
4.81 - if (multi.containsKey(v.variableName)) {
4.82 - return multi.get(v.variableName);
4.83 - }
4.84 + Map<String, Collection<? extends TreePath>> multi = ctx.getMultiVariables();
4.85 +
4.86 + if (multi.containsKey(v.variableName)) {
4.87 + return multi.get(v.variableName);
4.88 }
4.89
4.90 return null;
4.91 @@ -258,47 +248,19 @@
4.92 return ctx.ctx;
4.93 }
4.94
4.95 - @Override
4.96 + @Override //XXX can be removed:
4.97 public Map<String, TreePath> getVariables(Context ctx) {
4.98 - Map<String, TreePath> result = new HashMap<String, TreePath>();
4.99 -
4.100 - for (Map<String, TreePath> m : reverse(ctx.variables)) {
4.101 - result.putAll(m);
4.102 - }
4.103 -
4.104 - return result;
4.105 + return ctx.ctx.getVariables();
4.106 }
4.107
4.108 - @Override
4.109 + @Override //XXX can be removed:
4.110 public Map<String, Collection<? extends TreePath>> getMultiVariables(Context ctx) {
4.111 - Map<String, Collection<? extends TreePath>> result = new HashMap<String, Collection<? extends TreePath>>();
4.112 -
4.113 - for (Map<String, Collection<? extends TreePath>> m : reverse(ctx.multiVariables)) {
4.114 - result.putAll(m);
4.115 - }
4.116 -
4.117 - return result;
4.118 + return ctx.ctx.getMultiVariables();
4.119 }
4.120
4.121 - @Override
4.122 + @Override //XXX can be removed:
4.123 public Map<String, String> getVariableNames(Context ctx) {
4.124 - Map<String, String> result = new HashMap<String, String>();
4.125 -
4.126 - for (Map<String, String> m : reverse(ctx.variableNames)) {
4.127 - result.putAll(m);
4.128 - }
4.129 -
4.130 - return result;
4.131 - }
4.132 -
4.133 - private <T> List<T> reverse(List<T> original) {
4.134 - List<T> result = new LinkedList<T>();
4.135 -
4.136 - for (T t : original) {
4.137 - result.add(0, t);
4.138 - }
4.139 -
4.140 - return result;
4.141 + return ctx.ctx.getVariableNames();
4.142 }
4.143
4.144 }
5.1 --- a/file/src/org/netbeans/modules/jackpot30/file/conditionapi/Matcher.java Sat Jan 22 19:28:36 2011 +0100
5.2 +++ b/file/src/org/netbeans/modules/jackpot30/file/conditionapi/Matcher.java Sat Jan 22 21:51:05 2011 +0100
5.3 @@ -42,6 +42,10 @@
5.4 import com.sun.source.tree.Tree;
5.5 import com.sun.source.util.TreePath;
5.6 import com.sun.source.util.TreePathScanner;
5.7 +import java.util.Collection;
5.8 +import java.util.HashMap;
5.9 +import java.util.Map;
5.10 +import java.util.Map.Entry;
5.11 import javax.lang.model.element.Element;
5.12 import org.netbeans.api.annotations.common.NonNull;
5.13 import org.netbeans.modules.jackpot30.spi.MatcherUtilities;
5.14 @@ -163,7 +167,20 @@
5.15 return false;
5.16 }
5.17
5.18 - if (MatcherUtilities.matches(ctx.ctx, path, pattern, ctx.variables.get(0), ctx.multiVariables.get(0), ctx.variableNames.get(0))) {
5.19 + Map<String, TreePath> variables = new HashMap<String, TreePath>();
5.20 + Map<String, Collection<? extends TreePath>> multiVariables = new HashMap<String, Collection<? extends TreePath>>();
5.21 + Map<String, String> variableNames = new HashMap<String, String>();
5.22 +
5.23 + if (MatcherUtilities.matches(ctx.ctx, path, pattern, variables, multiVariables, variableNames)) {
5.24 + for (Entry<String, TreePath> e : variables.entrySet()) {
5.25 + ctx.ctx.putVariable(e.getKey(), e.getValue());
5.26 + }
5.27 + for (Entry<String, Collection<? extends TreePath>> e : multiVariables.entrySet()) {
5.28 + ctx.ctx.putMultiVariable(e.getKey(), e.getValue());
5.29 + }
5.30 + for (Entry<String, String> e : variableNames.entrySet()) {
5.31 + ctx.ctx.putVariableName(e.getKey(), e.getValue());
5.32 + }
5.33 return true;
5.34 }
5.35