Moving scoping from file's Context to HintContext/SPI. marks
authorJan Lahoda <jlahoda@netbeans.org>
Sat, 22 Jan 2011 21:51:05 +0100
branchmarks
changeset 527a19f2108d439
parent 526 4fde0197d631
child 550 1b17e3ff36e6
Moving scoping from file's Context to HintContext/SPI.
api/src/org/netbeans/modules/jackpot30/impl/hints/HintsInvoker.java
api/src/org/netbeans/modules/jackpot30/spi/HintContext.java
api/src/org/netbeans/modules/jackpot30/spi/HintDescription.java
file/src/org/netbeans/modules/jackpot30/file/conditionapi/Context.java
file/src/org/netbeans/modules/jackpot30/file/conditionapi/Matcher.java
     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