Starting with an attributed index: allowing to augment file content with set of erased types occurring in the file
authorJan Lahoda <jlahoda@netbeans.org>
Sun, 16 Jan 2011 19:22:56 +0100
changeset 5175b0b48cf992a
parent 516 1c422bf80082
child 518 b5c29f249d1f
Starting with an attributed index: allowing to augment file content with set of erased types occurring in the file
api/src/org/netbeans/modules/jackpot30/impl/batch/BatchSearch.java
api/src/org/netbeans/modules/jackpot30/impl/indexing/AbstractLuceneIndex.java
api/src/org/netbeans/modules/jackpot30/impl/indexing/CustomIndexerImpl.java
api/src/org/netbeans/modules/jackpot30/impl/indexing/Index.java
api/src/org/netbeans/modules/jackpot30/impl/pm/BulkSearch.java
api/src/org/netbeans/modules/jackpot30/impl/pm/CopyFinderBasedBulkSearch.java
api/src/org/netbeans/modules/jackpot30/impl/pm/NFABasedBulkSearch.java
api/src/org/netbeans/modules/jackpot30/spi/HintDescription.java
api/src/org/netbeans/modules/jackpot30/spi/HintDescriptionFactory.java
api/src/org/netbeans/modules/jackpot30/spi/PatternConvertor.java
api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/CustomIndexerImplTest.java
api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/IndexTest.java
api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/IndexTestBase.java
api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/IndexingTestUtils.java
api/test/unit/src/org/netbeans/modules/jackpot30/impl/pm/NFABasedBulkSearchTest.java
build.xml
server/indexer/nbproject/project.properties
server/indexer/src/org/netbeans/modules/jackpot30/server/indexer/StandaloneFinder.java
server/indexer/src/org/netbeans/modules/jackpot30/server/indexer/StandaloneIndexer.java
     1.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/batch/BatchSearch.java	Sun Jan 16 13:56:54 2011 +0100
     1.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/batch/BatchSearch.java	Sun Jan 16 19:22:56 2011 +0100
     1.3 @@ -100,6 +100,7 @@
     1.4  import org.netbeans.modules.jackpot30.impl.pm.CopyFinder;
     1.5  import org.netbeans.modules.jackpot30.spi.HintContext.MessageKind;
     1.6  import org.netbeans.modules.jackpot30.spi.HintDescription;
     1.7 +import org.netbeans.modules.jackpot30.spi.HintDescription.AdditionalQueryConstraints;
     1.8  import org.netbeans.modules.jackpot30.spi.HintDescription.PatternDescription;
     1.9  import org.netbeans.modules.java.source.JavaSourceAccessor;
    1.10  import org.netbeans.spi.editor.hints.ErrorDescription;
    1.11 @@ -306,15 +307,17 @@
    1.12      private static BulkPattern preparePattern(final Iterable<? extends HintDescription> patterns, CompilationInfo info) {
    1.13          Collection<String> code = new LinkedList<String>();
    1.14          Collection<Tree> trees = new LinkedList<Tree>();
    1.15 +        Collection<AdditionalQueryConstraints> additionalConstraints = new LinkedList<AdditionalQueryConstraints>();
    1.16  
    1.17          for (HintDescription pattern : patterns) {
    1.18              String textPattern = pattern.getTriggerPattern().getPattern();
    1.19  
    1.20              code.add(textPattern);
    1.21              trees.add(Utilities.parseAndAttribute(info, textPattern, null));
    1.22 +            additionalConstraints.add(pattern.getAdditionalConstraints());
    1.23          }
    1.24  
    1.25 -        return BulkSearch.getDefault().create(code, trees);
    1.26 +        return BulkSearch.getDefault().create(code, trees, additionalConstraints);
    1.27      }
    1.28  
    1.29      private static void recursive(FileObject root, FileObject file, Collection<FileObject> collected, ProgressHandleWrapper progress, int depth, Properties timeStamps, Set<String> removedFiles) {
     2.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/indexing/AbstractLuceneIndex.java	Sun Jan 16 13:56:54 2011 +0100
     2.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/indexing/AbstractLuceneIndex.java	Sun Jan 16 19:22:56 2011 +0100
     2.3 @@ -40,6 +40,9 @@
     2.4  package org.netbeans.modules.jackpot30.impl.indexing;
     2.5  
     2.6  import com.sun.source.tree.CompilationUnitTree;
     2.7 +import com.sun.source.tree.Tree;
     2.8 +import com.sun.source.util.TreePath;
     2.9 +import com.sun.source.util.TreePathScanner;
    2.10  import java.io.ByteArrayInputStream;
    2.11  import java.io.ByteArrayOutputStream;
    2.12  import java.io.IOException;
    2.13 @@ -50,9 +53,13 @@
    2.14  import java.util.HashSet;
    2.15  import java.util.Iterator;
    2.16  import java.util.List;
    2.17 +import java.util.Set;
    2.18  import java.util.logging.Level;
    2.19  import java.util.logging.Logger;
    2.20  import java.util.zip.DataFormatException;
    2.21 +import javax.lang.model.type.ArrayType;
    2.22 +import javax.lang.model.type.TypeKind;
    2.23 +import javax.lang.model.type.TypeMirror;
    2.24  import org.apache.lucene.analysis.Token;
    2.25  import org.apache.lucene.analysis.TokenStream;
    2.26  import org.apache.lucene.document.CompressionTools;
    2.27 @@ -77,6 +84,7 @@
    2.28  import org.netbeans.modules.jackpot30.impl.pm.BulkSearch;
    2.29  import org.netbeans.modules.jackpot30.impl.pm.BulkSearch.BulkPattern;
    2.30  import org.netbeans.modules.jackpot30.impl.pm.BulkSearch.EncodingContext;
    2.31 +import org.netbeans.modules.jackpot30.spi.HintDescription.AdditionalQueryConstraints;
    2.32  import org.openide.util.Exceptions;
    2.33  
    2.34  /**
    2.35 @@ -86,7 +94,8 @@
    2.36  public abstract class AbstractLuceneIndex extends Index {
    2.37  
    2.38      public static final int MAJOR_VERSION = 1;
    2.39 -    public static final int MINOR_VERSION = 1;
    2.40 +    //2: partial attribution added (erased types that occur in the file)
    2.41 +    public static final int MINOR_VERSION = 2;
    2.42      
    2.43      private final int  stripLength;
    2.44      private final boolean readOnly;
    2.45 @@ -106,6 +115,7 @@
    2.46      protected abstract IndexReader createReader() throws IOException;
    2.47      protected abstract org.apache.lucene.index.IndexWriter createWriter() throws IOException;
    2.48  
    2.49 +    @Override
    2.50      public Collection<? extends String> findCandidates(BulkPattern pattern) throws IOException {
    2.51          IndexReader reader = createReader();
    2.52  
    2.53 @@ -171,6 +181,24 @@
    2.54                  
    2.55                  emb.add(pq, BooleanClause.Occur.MUST);
    2.56              }
    2.57 +            
    2.58 +            AdditionalQueryConstraints additionalConstraints = pattern.getAdditionalConstraints().get(cntr);
    2.59 +
    2.60 +            if (additionalConstraints != null && !additionalConstraints.requiredErasedTypes.isEmpty()) {
    2.61 +                BooleanQuery constraintsQuery = new BooleanQuery();
    2.62 +
    2.63 +                constraintsQuery.add(new TermQuery(new Term("attributed", "false")), BooleanClause.Occur.SHOULD);
    2.64 +
    2.65 +                BooleanQuery constr = new BooleanQuery();
    2.66 +
    2.67 +                for (String tc : additionalConstraints.requiredErasedTypes) {
    2.68 +                    constr.add(new TermQuery(new Term("erasedTypes", tc)), BooleanClause.Occur.MUST);
    2.69 +                }
    2.70 +
    2.71 +                constraintsQuery.add(constr, BooleanClause.Occur.SHOULD);
    2.72 +                emb.add(constraintsQuery, BooleanClause.Occur.MUST);
    2.73 +            }
    2.74 +
    2.75              result.add(emb, BooleanClause.Occur.SHOULD);
    2.76          }
    2.77  
    2.78 @@ -220,7 +248,8 @@
    2.79              info = getIndexInfo();
    2.80          }
    2.81  
    2.82 -        public void record(URL source, final CompilationUnitTree cut) throws IOException {
    2.83 +        @Override
    2.84 +        public void record(URL source, final CompilationUnitTree cut, final AttributionWrapper attributed) throws IOException {
    2.85              String relative = source.getPath().substring(stripLength);
    2.86              ByteArrayOutputStream out = null;
    2.87              EncodingContext ec = null;
    2.88 @@ -244,6 +273,38 @@
    2.89                  }
    2.90                  doc.add(new Field("path", relative, Field.Store.YES, Field.Index.NOT_ANALYZED));
    2.91  
    2.92 +                if (attributed != null) {
    2.93 +                    final Set<String> erased = new HashSet<String>();
    2.94 +
    2.95 +                    new TreePathScanner<Void, Void>() {
    2.96 +                        @Override
    2.97 +                        public Void scan(Tree tree, Void p) {
    2.98 +                            if (tree != null) {
    2.99 +                                TreePath tp = new TreePath(getCurrentPath(), tree);
   2.100 +                                TypeMirror type = attributed.trees.getTypeMirror(tp);
   2.101 +
   2.102 +                                if (type != null) {
   2.103 +                                    if (type.getKind() == TypeKind.ARRAY) {
   2.104 +                                        erased.add(attributed.types.erasure(type).toString());
   2.105 +                                        type = ((ArrayType) type).getComponentType();
   2.106 +                                    }
   2.107 +
   2.108 +                                    if (type.getKind().isPrimitive() || type.getKind() == TypeKind.DECLARED) {
   2.109 +                                        addErasedTypeAndSuperTypes(attributed, erased, type);
   2.110 +                                    }
   2.111 +                                }
   2.112 +
   2.113 +                                //bounds for type variables!!!
   2.114 +                            }
   2.115 +                            return super.scan(tree, p);
   2.116 +                        }
   2.117 +                    }.scan(cut, null);
   2.118 +
   2.119 +                    doc.add(new Field("attributed", "true", Field.Store.YES, Field.Index.NOT_ANALYZED));
   2.120 +                    doc.add(new Field("erasedTypes", new TokenStreamImpl(erased)));
   2.121 +                } else {
   2.122 +                    doc.add(new Field("attributed", "false", Field.Store.YES, Field.Index.NOT_ANALYZED));
   2.123 +                }
   2.124                  luceneWriter.addDocument(doc);
   2.125              } catch (ThreadDeath td) {
   2.126                  throw td;
   2.127 @@ -275,6 +336,18 @@
   2.128          }
   2.129      }
   2.130  
   2.131 +    private static void addErasedTypeAndSuperTypes(AttributionWrapper attributed, Set<String> types, TypeMirror type) {
   2.132 +        if (type.getKind() == TypeKind.DECLARED) {
   2.133 +            if (types.add(attributed.types.erasure(type).toString())) {
   2.134 +                for (TypeMirror sup : attributed.types.directSupertypes(type)) {
   2.135 +                    addErasedTypeAndSuperTypes(attributed, types, sup);
   2.136 +                }
   2.137 +            }
   2.138 +        } else if (type.getKind().isPrimitive()) {
   2.139 +            types.add(type.toString());
   2.140 +        }
   2.141 +    }
   2.142 +
   2.143      public static final class TokenStreamImpl extends TokenStream {
   2.144  
   2.145          private final Iterator<? extends String> tokens;
     3.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/indexing/CustomIndexerImpl.java	Sun Jan 16 13:56:54 2011 +0100
     3.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/indexing/CustomIndexerImpl.java	Sun Jan 16 19:22:56 2011 +0100
     3.3 @@ -48,6 +48,7 @@
     3.4  import org.netbeans.api.java.source.JavaSource;
     3.5  import org.netbeans.api.java.source.JavaSource.Phase;
     3.6  import org.netbeans.api.java.source.Task;
     3.7 +import org.netbeans.modules.jackpot30.impl.indexing.Index.AttributionWrapper;
     3.8  import org.netbeans.modules.jackpot30.impl.indexing.Index.IndexWriter;
     3.9  import org.netbeans.modules.parsing.spi.indexing.Context;
    3.10  import org.netbeans.modules.parsing.spi.indexing.CustomIndexer;
    3.11 @@ -104,10 +105,10 @@
    3.12              if (!toIndex.isEmpty()) {
    3.13                  JavaSource.create(cpInfo, toIndex).runUserActionTask(new Task<CompilationController>() {
    3.14                      public void run(final CompilationController cc) throws Exception {
    3.15 -                        if (cc.toPhase(Phase.PARSED).compareTo(Phase.PARSED) < 0)
    3.16 +                        if (cc.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0)
    3.17                              return ;
    3.18  
    3.19 -                        w[0].record(cc.getFileObject().getURL(), cc.getCompilationUnit());
    3.20 +                        w[0].record(cc.getFileObject().getURL(), cc.getCompilationUnit(), new AttributionWrapper(cc));
    3.21                      }
    3.22                  }, true);
    3.23              }
     4.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/indexing/Index.java	Sun Jan 16 13:56:54 2011 +0100
     4.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/indexing/Index.java	Sun Jan 16 19:22:56 2011 +0100
     4.3 @@ -39,6 +39,9 @@
     4.4  
     4.5  package org.netbeans.modules.jackpot30.impl.indexing;
     4.6  
     4.7 +import org.netbeans.modules.jackpot30.spi.HintDescription.AdditionalQueryConstraints;
     4.8 +import com.sun.source.util.Trees;
     4.9 +import javax.lang.model.util.Types;
    4.10  import org.netbeans.modules.jackpot30.impl.WebUtilities;
    4.11  import java.util.ArrayList;
    4.12  import com.sun.source.tree.CompilationUnitTree;
    4.13 @@ -50,6 +53,7 @@
    4.14  import java.util.Collections;
    4.15  import org.codeviation.pojson.Pojson;
    4.16  import org.netbeans.api.annotations.common.NonNull;
    4.17 +import org.netbeans.api.java.source.CompilationInfo;
    4.18  import org.netbeans.modules.jackpot30.impl.pm.BulkSearch.BulkPattern;
    4.19  import org.openide.util.Exceptions;
    4.20  import static org.netbeans.modules.jackpot30.impl.WebUtilities.escapeForQuery;
    4.21 @@ -127,11 +131,9 @@
    4.22  
    4.23      public abstract static class IndexWriter {
    4.24  
    4.25 -        protected IndexWriter() throws IOException {
    4.26 -            
    4.27 -        }
    4.28 +        protected IndexWriter() throws IOException {}
    4.29  
    4.30 -        public abstract void record(URL source, final CompilationUnitTree cut) throws IOException;
    4.31 +        public abstract void record(URL source, final CompilationUnitTree cut, AttributionWrapper attributed) throws IOException;
    4.32  
    4.33          public abstract void remove(String relativePath) throws IOException;
    4.34  
    4.35 @@ -141,4 +143,20 @@
    4.36          
    4.37      }
    4.38  
    4.39 +    public static final class AttributionWrapper {
    4.40 +        public final Trees trees;
    4.41 +        public final Types types;
    4.42 +
    4.43 +        public AttributionWrapper(CompilationInfo info) {
    4.44 +            trees = info.getTrees();
    4.45 +            types = info.getTypes();
    4.46 +        }
    4.47 +
    4.48 +        public AttributionWrapper(Trees trees, Types types) {
    4.49 +            this.trees = trees;
    4.50 +            this.types = types;
    4.51 +        }
    4.52 +
    4.53 +    }
    4.54 +
    4.55  }
     5.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/pm/BulkSearch.java	Sun Jan 16 13:56:54 2011 +0100
     5.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/pm/BulkSearch.java	Sun Jan 16 19:22:56 2011 +0100
     5.3 @@ -51,6 +51,7 @@
     5.4  import java.util.Set;
     5.5  import org.netbeans.api.java.source.CompilationInfo;
     5.6  import org.netbeans.modules.jackpot30.impl.Utilities;
     5.7 +import org.netbeans.modules.jackpot30.spi.HintDescription.AdditionalQueryConstraints;
     5.8  
     5.9  /**
    5.10   *
    5.11 @@ -93,26 +94,30 @@
    5.12  
    5.13      public final BulkPattern create(CompilationInfo info, Collection<? extends String> code) {
    5.14          List<Tree> patterns = new LinkedList<Tree>();
    5.15 +        List<AdditionalQueryConstraints> additionalConstraints = new LinkedList<AdditionalQueryConstraints>();
    5.16  
    5.17          for (String c : code) {
    5.18              patterns.add(Utilities.parseAndAttribute(info, c, null));
    5.19 +            additionalConstraints.add(AdditionalQueryConstraints.empty());
    5.20          }
    5.21  
    5.22 -        return create(code, patterns);
    5.23 +        return create(code, patterns, additionalConstraints);
    5.24      }
    5.25      
    5.26 -    public abstract BulkPattern create(Collection<? extends String> code, Collection<? extends Tree> patterns);
    5.27 +    public abstract BulkPattern create(Collection<? extends String> code, Collection<? extends Tree> patterns, Collection<? extends AdditionalQueryConstraints> additionalConstraints);
    5.28  
    5.29      public static abstract class BulkPattern {
    5.30  
    5.31          private final List<? extends String> patterns;
    5.32          private final List<? extends Set<? extends String>> identifiers;
    5.33          private final List<List<List<String>>> requiredContent;
    5.34 +        private final List<AdditionalQueryConstraints> additionalConstraints;
    5.35  
    5.36 -        public BulkPattern(List<? extends String> patterns, List<? extends Set<? extends String>> identifiers, List<List<List<String>>> requiredContent) {
    5.37 +        public BulkPattern(List<? extends String> patterns, List<? extends Set<? extends String>> identifiers, List<List<List<String>>> requiredContent, List<AdditionalQueryConstraints> additionalConstraints) {
    5.38              this.patterns = patterns;
    5.39              this.identifiers = identifiers;//TODO: immutable, maybe clone
    5.40              this.requiredContent = requiredContent;
    5.41 +            this.additionalConstraints = additionalConstraints;
    5.42          }
    5.43  
    5.44          public List<? extends String> getPatterns() {
    5.45 @@ -127,6 +132,10 @@
    5.46              return requiredContent;
    5.47          }
    5.48  
    5.49 +        public List<AdditionalQueryConstraints> getAdditionalConstraints() {
    5.50 +            return additionalConstraints;
    5.51 +        }
    5.52 +
    5.53      }
    5.54  
    5.55      public static final class EncodingContext {
     6.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/pm/CopyFinderBasedBulkSearch.java	Sun Jan 16 13:56:54 2011 +0100
     6.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/pm/CopyFinderBasedBulkSearch.java	Sun Jan 16 19:22:56 2011 +0100
     6.3 @@ -52,6 +52,7 @@
     6.4  import java.util.concurrent.atomic.AtomicBoolean;
     6.5  import javax.lang.model.type.TypeMirror;
     6.6  import org.netbeans.api.java.source.CompilationInfo;
     6.7 +import org.netbeans.modules.jackpot30.spi.HintDescription.AdditionalQueryConstraints;
     6.8  import org.openide.util.Parameters;
     6.9  
    6.10  /**
    6.11 @@ -93,7 +94,7 @@
    6.12      }
    6.13  
    6.14      @Override
    6.15 -    public BulkPattern create(Collection<? extends String> code, Collection<? extends Tree> patterns) {
    6.16 +    public BulkPattern create(Collection<? extends String> code, Collection<? extends Tree> patterns, Collection<? extends AdditionalQueryConstraints> additionalConstraints) {
    6.17          Map<Tree, String> pattern2Code = new HashMap<Tree, String>();
    6.18  
    6.19          Iterator<? extends String> itCode = code.iterator();
    6.20 @@ -103,7 +104,7 @@
    6.21              pattern2Code.put(itPatt.next(), itCode.next());
    6.22          }
    6.23  
    6.24 -        return new BulkPatternImpl(pattern2Code);
    6.25 +        return new BulkPatternImpl(additionalConstraints, pattern2Code);
    6.26      }
    6.27  
    6.28      @Override
    6.29 @@ -120,8 +121,8 @@
    6.30  
    6.31          private final Map<Tree, String> pattern2Code;
    6.32          
    6.33 -        public BulkPatternImpl(Map<Tree, String> pattern2Code) {
    6.34 -            super(new LinkedList<String>(pattern2Code.values()), null, null);
    6.35 +        public BulkPatternImpl(Collection<? extends AdditionalQueryConstraints> additionalConstraints, Map<Tree, String> pattern2Code) {
    6.36 +            super(new LinkedList<String>(pattern2Code.values()), null, null, new LinkedList<AdditionalQueryConstraints>(additionalConstraints));
    6.37              this.pattern2Code = pattern2Code;
    6.38          }
    6.39  
     7.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/pm/NFABasedBulkSearch.java	Sun Jan 16 13:56:54 2011 +0100
     7.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/pm/NFABasedBulkSearch.java	Sun Jan 16 19:22:56 2011 +0100
     7.3 @@ -71,6 +71,7 @@
     7.4  import javax.lang.model.element.Name;
     7.5  import org.netbeans.api.java.source.CompilationInfo;
     7.6  import org.netbeans.modules.jackpot30.impl.Utilities;
     7.7 +import org.netbeans.modules.jackpot30.spi.HintDescription.AdditionalQueryConstraints;
     7.8  import org.openide.util.Exceptions;
     7.9  
    7.10  /**
    7.11 @@ -153,7 +154,7 @@
    7.12      }
    7.13  
    7.14      @Override
    7.15 -    public BulkPattern create(Collection<? extends String> code, Collection<? extends Tree> patterns) {
    7.16 +    public BulkPattern create(Collection<? extends String> code, Collection<? extends Tree> patterns, Collection<? extends AdditionalQueryConstraints> additionalConstraints) {
    7.17          int startState = 0;
    7.18          final int[] nextState = new int[] {1};
    7.19          final Map<NFA.Key<Input>, NFA.State> transitionTable = new LinkedHashMap<NFA.Key<Input>, NFA.State>();
    7.20 @@ -331,7 +332,7 @@
    7.21  
    7.22          NFA<Input, Res> nfa = NFA.<Input, Res>create(startState, nextState[0], null, transitionTable, finalStates);
    7.23  
    7.24 -        return new BulkPatternImpl(new LinkedList<String>(code), identifiers, requiredContent, nfa);
    7.25 +        return new BulkPatternImpl(new LinkedList<String>(code), identifiers, requiredContent, new LinkedList<AdditionalQueryConstraints>(additionalConstraints), nfa);
    7.26      }
    7.27  
    7.28      private static void setBit(Map<NFA.Key<Input>, NFA.State> transitionTable, NFA.Key<Input> input, int state) {
    7.29 @@ -605,8 +606,8 @@
    7.30  
    7.31          private final NFA<Input, Res> nfa;
    7.32  
    7.33 -        private BulkPatternImpl(List<? extends String> patterns, List<? extends Set<? extends String>> identifiers, List<List<List<String>>> requiredContent, NFA<Input, Res> nfa) {
    7.34 -            super(patterns, identifiers, requiredContent);
    7.35 +        private BulkPatternImpl(List<? extends String> patterns, List<? extends Set<? extends String>> identifiers, List<List<List<String>>> requiredContent, List<AdditionalQueryConstraints> additionalConstraints, NFA<Input, Res> nfa) {
    7.36 +            super(patterns, identifiers, requiredContent, additionalConstraints);
    7.37              this.nfa = nfa;
    7.38          }
    7.39  
    7.40 @@ -614,10 +615,6 @@
    7.41              return nfa;
    7.42          }
    7.43          
    7.44 -        private static BulkPattern create(List<? extends String> patterns, List<? extends Set<? extends String>> identifiers, List<List<List<String>>> requiredContent, NFA<Input, Res> nfa) {
    7.45 -            return new BulkPatternImpl(patterns, identifiers, requiredContent, nfa);
    7.46 -        }
    7.47 -
    7.48      }
    7.49  
    7.50      private static final class Res {
     8.1 --- a/api/src/org/netbeans/modules/jackpot30/spi/HintDescription.java	Sun Jan 16 13:56:54 2011 +0100
     8.2 +++ b/api/src/org/netbeans/modules/jackpot30/spi/HintDescription.java	Sun Jan 16 19:22:56 2011 +0100
     8.3 @@ -42,7 +42,10 @@
     8.4  import com.sun.source.tree.Tree.Kind;
     8.5  import java.util.Arrays;
     8.6  import java.util.Collection;
     8.7 +import java.util.Collections;
     8.8 +import java.util.HashSet;
     8.9  import java.util.Map;
    8.10 +import java.util.Set;
    8.11  import org.netbeans.spi.editor.hints.ErrorDescription;
    8.12  import org.openide.util.Parameters;
    8.13  
    8.14 @@ -56,12 +59,14 @@
    8.15      private final Kind triggerKind;
    8.16      private final PatternDescription triggerPattern;
    8.17      private final Worker worker;
    8.18 +    private final AdditionalQueryConstraints additionalConstraints;
    8.19  
    8.20 -    private HintDescription(HintMetadata metadata, Kind triggerKind, PatternDescription triggerPattern, Worker worker) {
    8.21 +    private HintDescription(HintMetadata metadata, Kind triggerKind, PatternDescription triggerPattern, Worker worker, AdditionalQueryConstraints additionalConstraints) {
    8.22          this.metadata = metadata;
    8.23          this.triggerKind = triggerKind;
    8.24          this.triggerPattern = triggerPattern;
    8.25          this.worker = worker;
    8.26 +        this.additionalConstraints = additionalConstraints;
    8.27      }
    8.28  
    8.29      //XXX: should not be public
    8.30 @@ -87,12 +92,16 @@
    8.31          return metadata.suppressWarnings;
    8.32      }
    8.33  
    8.34 -    static HintDescription create(HintMetadata metadata, PatternDescription triggerPattern, Worker worker) {
    8.35 -        return new HintDescription(metadata, null, triggerPattern, worker);
    8.36 +    public AdditionalQueryConstraints getAdditionalConstraints() {
    8.37 +        return additionalConstraints;
    8.38      }
    8.39  
    8.40 -    static HintDescription create(HintMetadata metadata, Kind triggerKind, Worker worker) {
    8.41 -        return new HintDescription(metadata, triggerKind, null, worker);
    8.42 +    static HintDescription create(HintMetadata metadata, PatternDescription triggerPattern, Worker worker, AdditionalQueryConstraints additionalConstraints) {
    8.43 +        return new HintDescription(metadata, null, triggerPattern, worker, additionalConstraints);
    8.44 +    }
    8.45 +
    8.46 +    static HintDescription create(HintMetadata metadata, Kind triggerKind, Worker worker, AdditionalQueryConstraints additionalConstraints) {
    8.47 +        return new HintDescription(metadata, triggerKind, null, worker, additionalConstraints);
    8.48      }
    8.49  
    8.50      @Override
    8.51 @@ -174,4 +183,16 @@
    8.52  
    8.53      }
    8.54  
    8.55 +    public static final class AdditionalQueryConstraints {
    8.56 +        public final Set<String> requiredErasedTypes;
    8.57 +
    8.58 +        public AdditionalQueryConstraints(Set<String> requiredErasedTypes) {
    8.59 +            this.requiredErasedTypes = Collections.unmodifiableSet(new HashSet<String>(requiredErasedTypes));
    8.60 +        }
    8.61 +
    8.62 +        private static final AdditionalQueryConstraints EMPTY = new AdditionalQueryConstraints(Collections.<String>emptySet());
    8.63 +        public static AdditionalQueryConstraints empty() {
    8.64 +            return EMPTY;
    8.65 +        }
    8.66 +    }
    8.67  }
     9.1 --- a/api/src/org/netbeans/modules/jackpot30/spi/HintDescriptionFactory.java	Sun Jan 16 13:56:54 2011 +0100
     9.2 +++ b/api/src/org/netbeans/modules/jackpot30/spi/HintDescriptionFactory.java	Sun Jan 16 19:22:56 2011 +0100
     9.3 @@ -43,6 +43,7 @@
     9.4  import java.util.Collections;
     9.5  import java.util.LinkedList;
     9.6  import java.util.List;
     9.7 +import org.netbeans.modules.jackpot30.spi.HintDescription.AdditionalQueryConstraints;
     9.8  import org.netbeans.modules.jackpot30.spi.HintDescription.PatternDescription;
     9.9  import org.netbeans.modules.jackpot30.spi.HintDescription.Worker;
    9.10  import org.netbeans.modules.jackpot30.spi.HintMetadata.HintSeverity;
    9.11 @@ -57,6 +58,7 @@
    9.12      private       Kind triggerKind;
    9.13      private       PatternDescription triggerPattern;
    9.14      private       Worker worker;
    9.15 +    private       AdditionalQueryConstraints additionalConstraints;
    9.16      private       boolean finished;
    9.17  
    9.18      private HintDescriptionFactory() {
    9.19 @@ -94,14 +96,22 @@
    9.20          return this;
    9.21      }
    9.22  
    9.23 +    public HintDescriptionFactory setAdditionalConstraints(AdditionalQueryConstraints additionalConstraints) {
    9.24 +        this.additionalConstraints = additionalConstraints;
    9.25 +        return this;
    9.26 +    }
    9.27 +
    9.28      public HintDescription produce() {
    9.29          if (metadata == null) {
    9.30              metadata = new HintMetadata("no-id", "", "", "", true, HintMetadata.Kind.HINT_NON_GUI, HintSeverity.WARNING, null, Collections.<String>emptyList());
    9.31          }
    9.32 +        if (this.additionalConstraints == null) {
    9.33 +            this.additionalConstraints = AdditionalQueryConstraints.empty();
    9.34 +        }
    9.35          if (this.triggerKind == null) {
    9.36 -            return HintDescription.create(metadata, triggerPattern, worker);
    9.37 +            return HintDescription.create(metadata, triggerPattern, worker, additionalConstraints);
    9.38          } else {
    9.39 -            return HintDescription.create(metadata, triggerKind, worker);
    9.40 +            return HintDescription.create(metadata, triggerKind, worker, additionalConstraints);
    9.41          }
    9.42      }
    9.43      
    10.1 --- a/api/src/org/netbeans/modules/jackpot30/spi/PatternConvertor.java	Sun Jan 16 13:56:54 2011 +0100
    10.2 +++ b/api/src/org/netbeans/modules/jackpot30/spi/PatternConvertor.java	Sun Jan 16 19:22:56 2011 +0100
    10.3 @@ -39,6 +39,7 @@
    10.4  
    10.5  package org.netbeans.modules.jackpot30.spi;
    10.6  
    10.7 +import java.util.ArrayList;
    10.8  import java.util.Collection;
    10.9  import java.util.Collections;
   10.10  import org.netbeans.api.annotations.common.CheckForNull;
   10.11 @@ -58,26 +59,43 @@
   10.12      protected abstract @CheckForNull Iterable<? extends HintDescription> parseString(@NonNull String code);
   10.13  
   10.14      public static @CheckForNull Iterable<? extends HintDescription> create(@NonNull String code) {
   10.15 +        Collection<String> patterns = new ArrayList<String>();
   10.16 +        
   10.17          //XXX:
   10.18          if (code.contains(";;")) {
   10.19              PatternConvertor c = Lookup.getDefault().lookup(PatternConvertor.class);
   10.20  
   10.21 -            if (c == null) {
   10.22 -                return null;
   10.23 +            if (c != null) {
   10.24 +                return c.parseString(code);
   10.25              }
   10.26  
   10.27 -            return c.parseString(code);
   10.28 +            for (String s : code.split(";;")) {
   10.29 +                s = s.trim();
   10.30 +                if (s.isEmpty()) {
   10.31 +                    continue;
   10.32 +                }
   10.33 +                
   10.34 +                patterns.add(s);
   10.35 +            }
   10.36 +        } else {
   10.37 +            patterns.add(code);
   10.38          }
   10.39  
   10.40 -        PatternDescription pd = PatternDescription.create(code, Collections.<String, String>emptyMap());
   10.41 +        Collection<HintDescription> result = new ArrayList<HintDescription>(patterns.size());
   10.42  
   10.43 -        HintDescription desc = HintDescriptionFactory.create()
   10.44 -//                                                     .setDisplayName("Pattern Matches")
   10.45 -                                                     .setTriggerPattern(pd)
   10.46 -                                                     .setWorker(new WorkerImpl())
   10.47 -                                                     .produce();
   10.48 +        for (String pattern : patterns) {
   10.49 +            PatternDescription pd = PatternDescription.create(pattern, Collections.<String, String>emptyMap());
   10.50  
   10.51 -        return Collections.singletonList(desc);
   10.52 +            HintDescription desc = HintDescriptionFactory.create()
   10.53 +    //                                                     .setDisplayName("Pattern Matches")
   10.54 +                                                         .setTriggerPattern(pd)
   10.55 +                                                         .setWorker(new WorkerImpl())
   10.56 +                                                         .produce();
   10.57 +            
   10.58 +            result.add(desc);
   10.59 +        }
   10.60 +
   10.61 +        return result;
   10.62      }
   10.63  
   10.64      private static final class WorkerImpl implements Worker {
    11.1 --- a/api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/CustomIndexerImplTest.java	Sun Jan 16 13:56:54 2011 +0100
    11.2 +++ b/api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/CustomIndexerImplTest.java	Sun Jan 16 19:22:56 2011 +0100
    11.3 @@ -39,6 +39,7 @@
    11.4  
    11.5  package org.netbeans.modules.jackpot30.impl.indexing;
    11.6  
    11.7 +import java.util.Collections;
    11.8  import java.net.URL;
    11.9  import java.util.Arrays;
   11.10  import java.util.HashSet;
    12.1 --- a/api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/IndexTest.java	Sun Jan 16 13:56:54 2011 +0100
    12.2 +++ b/api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/IndexTest.java	Sun Jan 16 19:22:56 2011 +0100
    12.3 @@ -39,6 +39,8 @@
    12.4  
    12.5  package org.netbeans.modules.jackpot30.impl.indexing;
    12.6  
    12.7 +import org.netbeans.modules.jackpot30.impl.Utilities;
    12.8 +import java.util.Collections;
    12.9  import java.net.URL;
   12.10  import java.util.Arrays;
   12.11  import java.util.HashSet;
   12.12 @@ -52,11 +54,14 @@
   12.13  import org.netbeans.api.java.source.TestUtilities;
   12.14  import org.netbeans.modules.jackpot30.impl.indexing.IndexingTestUtils.File;
   12.15  import org.netbeans.modules.jackpot30.impl.pm.BulkSearch;
   12.16 +import org.netbeans.modules.jackpot30.impl.pm.BulkSearch.BulkPattern;
   12.17 +import org.netbeans.modules.jackpot30.spi.HintDescription.AdditionalQueryConstraints;
   12.18  import org.netbeans.modules.parsing.api.indexing.IndexingManager;
   12.19  import org.netbeans.spi.java.classpath.support.ClassPathSupport;
   12.20  import org.openide.filesystems.FileObject;
   12.21  import org.openide.filesystems.FileUtil;
   12.22  
   12.23 +import static org.netbeans.modules.jackpot30.impl.indexing.IndexingTestUtils.indexFiles;
   12.24  import static org.netbeans.modules.jackpot30.impl.indexing.IndexingTestUtils.writeFilesAndWaitForScan;
   12.25  
   12.26  /**
   12.27 @@ -124,6 +129,26 @@
   12.28          assertEquals(2, FileBasedIndex.get(src.getURL()).getIndexInfo().totalFiles);
   12.29      }
   12.30  
   12.31 +    public void testPartiallyAttributed1() throws Exception {
   12.32 +        Index index = FileBasedIndex.get(src.getURL());
   12.33 +        indexFiles(src.getURL().toURI(),
   12.34 +                   index,
   12.35 +                   new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }", true),
   12.36 +                   new File("test/Test2.java", "package test; public class Test2 { private void isDirectory() { this.isDirectory(); } }", true),
   12.37 +                   new File("test/Test3.java", "package test; public class Test3 { private void isDirectory() { this.isDirectory(); } }", false));
   12.38 +
   12.39 +        verifyIndex("$1.isDirectory()", new AdditionalQueryConstraints(Collections.singleton("java.io.File")), "test/Test1.java", "test/Test3.java");
   12.40 +    }
   12.41 +
   12.42 +    public void testPartiallyAttributed2() throws Exception {
   12.43 +        Index index = FileBasedIndex.get(src.getURL());
   12.44 +        indexFiles(src.getURL().toURI(),
   12.45 +                   index,
   12.46 +                   new File("test/Test1.java", "package test; public class Test1 { private void test() { String str = null; int l = str.length(); } }", true));
   12.47 +
   12.48 +        verifyIndex("$1.length()", new AdditionalQueryConstraints(Collections.singleton("java.lang.CharSequence")), "test/Test1.java");
   12.49 +    }
   12.50 +
   12.51      private void verifyIndex(final String[] patterns, String... containedIn) throws Exception {
   12.52          ClassPath EMPTY = ClassPathSupport.createClassPath(new FileObject[0]);
   12.53          ClasspathInfo cpInfo = ClasspathInfo.create(ClassPathSupport.createClassPath(SourceUtilsTestUtil.getBootClassPath().toArray(new URL[0])),
   12.54 @@ -143,4 +168,27 @@
   12.55          assertEquals(golden, real);
   12.56      }
   12.57  
   12.58 +    private void verifyIndex(final String pattern, final AdditionalQueryConstraints additionalConstraints, String... containedIn) throws Exception {
   12.59 +        ClassPath EMPTY = ClassPathSupport.createClassPath(new FileObject[0]);
   12.60 +        ClasspathInfo cpInfo = ClasspathInfo.create(ClassPathSupport.createClassPath(SourceUtilsTestUtil.getBootClassPath().toArray(new URL[0])),
   12.61 +                                                    EMPTY,
   12.62 +                                                    EMPTY);
   12.63 +
   12.64 +        final Set<String> real = new HashSet<String>();
   12.65 +
   12.66 +        JavaSource.create(cpInfo).runUserActionTask(new Task<CompilationController>() {
   12.67 +            public void run(CompilationController parameter) throws Exception {
   12.68 +                BulkPattern bulkPattern = BulkSearch.getDefault().create(Collections.singletonList(pattern),
   12.69 +                                                                          Collections.singletonList(Utilities.parseAndAttribute(parameter, pattern, null)),
   12.70 +                                                                          Collections.singletonList(additionalConstraints));
   12.71 +                
   12.72 +                real.addAll(FileBasedIndex.get(src.getURL()).findCandidates(bulkPattern));
   12.73 +            }
   12.74 +        }, true);
   12.75 +
   12.76 +        Set<String> golden = new HashSet<String>(Arrays.asList(containedIn));
   12.77 +
   12.78 +        assertEquals(golden, real);
   12.79 +    }
   12.80 +
   12.81  }
   12.82 \ No newline at end of file
    13.1 --- a/api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/IndexTestBase.java	Sun Jan 16 13:56:54 2011 +0100
    13.2 +++ b/api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/IndexTestBase.java	Sun Jan 16 19:22:56 2011 +0100
    13.3 @@ -80,6 +80,7 @@
    13.4          GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, new ClassPath[] {sourceCP});
    13.5      }
    13.6  
    13.7 +    protected FileObject sources;
    13.8      protected FileObject src;
    13.9      protected FileObject src2;
   13.10  
   13.11 @@ -88,8 +89,9 @@
   13.12      private void prepareTest() throws Exception {
   13.13          FileObject workdir = SourceUtilsTestUtil.makeScratchDir(this);
   13.14  
   13.15 -        src = FileUtil.createFolder(workdir, "src");
   13.16 -        src2 = FileUtil.createFolder(workdir, "src2");
   13.17 +        sources = FileUtil.createFolder(workdir, "sources");
   13.18 +        src = FileUtil.createFolder(sources, "src");
   13.19 +        src2 = FileUtil.createFolder(sources, "src2");
   13.20  
   13.21          FileObject cache = FileUtil.createFolder(workdir, "cache");
   13.22  
    14.1 --- a/api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/IndexingTestUtils.java	Sun Jan 16 13:56:54 2011 +0100
    14.2 +++ b/api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/IndexingTestUtils.java	Sun Jan 16 19:22:56 2011 +0100
    14.3 @@ -16,7 +16,7 @@
    14.4   * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    14.5   * particular file as subject to the "Classpath" exception as provided
    14.6   * by Sun in the GPL Version 2 section of the License file that
    14.7 - * accompanied this code. If applicable, add the following below the
    14.8 + * accompanied this content. If applicable, add the following below the
    14.9   * License Header, with the fields enclosed by brackets [] replaced by
   14.10   * your own identifying information:
   14.11   * "Portions Copyrighted [year] [name of copyright owner]"
   14.12 @@ -28,8 +28,8 @@
   14.13   * single choice of license, a recipient has the option to distribute
   14.14   * your version of this file under either the CDDL, the GPL Version 2 or
   14.15   * to extend the choice of license to its licensees as provided above.
   14.16 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   14.17 - * Version 2 license, then the option applies only if the new code is
   14.18 + * However, if you add GPL Version 2 content and therefore, elected the GPL
   14.19 + * Version 2 license, then the option applies only if the new content is
   14.20   * made subject to such option by the copyright holder.
   14.21   *
   14.22   * Contributor(s):
   14.23 @@ -39,11 +39,30 @@
   14.24  
   14.25  package org.netbeans.modules.jackpot30.impl.indexing;
   14.26  
   14.27 +import com.sun.source.tree.CompilationUnitTree;
   14.28 +import com.sun.source.util.Trees;
   14.29 +import com.sun.tools.javac.api.JavacTaskImpl;
   14.30 +import com.sun.tools.javac.model.JavacTypes;
   14.31 +import java.io.IOException;
   14.32 +import java.net.URI;
   14.33 +import java.net.URL;
   14.34 +import java.util.Arrays;
   14.35 +import java.util.Collections;
   14.36 +import javax.tools.Diagnostic;
   14.37 +import javax.tools.DiagnosticListener;
   14.38 +import javax.tools.JavaCompiler;
   14.39 +import javax.tools.JavaFileObject;
   14.40 +import javax.tools.SimpleJavaFileObject;
   14.41 +import javax.tools.StandardJavaFileManager;
   14.42 +import javax.tools.StandardLocation;
   14.43 +import javax.tools.ToolProvider;
   14.44  import org.netbeans.api.editor.mimelookup.MimePath;
   14.45  import org.netbeans.api.java.source.SourceUtils;
   14.46  import org.netbeans.api.java.source.TestUtilities;
   14.47  import org.netbeans.modules.jackpot30.impl.duplicates.indexing.DuplicatesCustomIndexerImpl.FactoryImpl;
   14.48 +import org.netbeans.modules.jackpot30.impl.duplicates.indexing.DuplicatesIndex;
   14.49  import org.netbeans.modules.jackpot30.impl.indexing.CustomIndexerImpl.CustomIndexerFactoryImpl;
   14.50 +import org.netbeans.modules.jackpot30.impl.indexing.Index.IndexWriter;
   14.51  import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
   14.52  import org.openide.filesystems.FileObject;
   14.53  import org.openide.filesystems.FileUtil;
   14.54 @@ -66,13 +85,33 @@
   14.55          SourceUtils.waitScanFinished();
   14.56      }
   14.57  
   14.58 +    public static void indexFiles(URI root, Index idx, File... files) throws Exception {
   14.59 +        IndexWriter iw = idx.openForWriting();
   14.60 +
   14.61 +        try {
   14.62 +            iw.clear();
   14.63 +
   14.64 +            for (File f : files) {
   14.65 +                indexFile(root, iw, null, f);
   14.66 +            }
   14.67 +        } finally {
   14.68 +            iw.close();
   14.69 +        }
   14.70 +    }
   14.71 +
   14.72      public static final class File {
   14.73          public final String filename;
   14.74          public final String content;
   14.75 +        public final boolean index;
   14.76  
   14.77          public File(String filename, String content) {
   14.78 +            this(filename, content, true);
   14.79 +        }
   14.80 +
   14.81 +        public File(String filename, String content, boolean index) {
   14.82              this.filename = filename;
   14.83              this.content = content;
   14.84 +            this.index = index;
   14.85          }
   14.86      }
   14.87  
   14.88 @@ -89,4 +128,41 @@
   14.89          }
   14.90  
   14.91      }
   14.92 +
   14.93 +    //copied from StandaloneIndexer:
   14.94 +    private static void indexFile(URI root, IndexWriter w, DuplicatesIndex.IndexWriter dw, File source) throws IOException {
   14.95 +        if (!source.filename.endsWith(".java"))
   14.96 +            return ;
   14.97 +
   14.98 +        final String bootPath = System.getProperty("sun.boot.class.path"); //NOI18N
   14.99 +        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
  14.100 +        assert tool != null;
  14.101 +
  14.102 +        DiagnosticListener<JavaFileObject> devNull = new DiagnosticListener<JavaFileObject>() {
  14.103 +            public void report(Diagnostic<? extends JavaFileObject> diagnostic) {}
  14.104 +        };
  14.105 +        StandardJavaFileManager m = tool.getStandardFileManager(devNull, null, null);
  14.106 +
  14.107 +        m.setLocation(StandardLocation.CLASS_PATH, Collections.<java.io.File>emptyList());
  14.108 +        m.setLocation(StandardLocation.SOURCE_PATH, Collections.<java.io.File>emptyList());
  14.109 +
  14.110 +        JavacTaskImpl ct = (JavacTaskImpl)tool.getTask(null, null, devNull, Arrays.asList("-bootclasspath",  bootPath), null, Collections.singleton(new JFOImpl(source.filename, source.content)));
  14.111 +        CompilationUnitTree cut = ct.parse().iterator().next();
  14.112 +
  14.113 +        ct.analyze(ct.enter(Collections.singletonList(cut)));
  14.114 +
  14.115 +        w.record(root.resolve(source.filename).toURL(), cut, source.index ? new Index.AttributionWrapper(Trees.instance(ct), JavacTypes.instance(ct.getContext())) : null);
  14.116 +    }
  14.117 +
  14.118 +    private static final class JFOImpl extends SimpleJavaFileObject {
  14.119 +        private final String content;
  14.120 +        public JFOImpl(String filename, String content) {
  14.121 +            super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
  14.122 +            this.content = content;
  14.123 +        }
  14.124 +        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
  14.125 +            return content;
  14.126 +        }
  14.127 +    }
  14.128 +
  14.129  }
  14.130 \ No newline at end of file
    15.1 --- a/api/test/unit/src/org/netbeans/modules/jackpot30/impl/pm/NFABasedBulkSearchTest.java	Sun Jan 16 13:56:54 2011 +0100
    15.2 +++ b/api/test/unit/src/org/netbeans/modules/jackpot30/impl/pm/NFABasedBulkSearchTest.java	Sun Jan 16 19:22:56 2011 +0100
    15.3 @@ -57,6 +57,7 @@
    15.4  import org.netbeans.modules.jackpot30.impl.indexing.AbstractLuceneIndex;
    15.5  import org.netbeans.modules.jackpot30.impl.indexing.Index.IndexWriter;
    15.6  import org.netbeans.modules.jackpot30.impl.indexing.IndexInfo;
    15.7 +import org.netbeans.modules.jackpot30.spi.HintDescription.AdditionalQueryConstraints;
    15.8  
    15.9  /**
   15.10   *
   15.11 @@ -94,7 +95,7 @@
   15.12                  IndexImpl ii = new IndexImpl();
   15.13                  IndexWriter writer = ii.openForWriting();
   15.14  
   15.15 -                writer.record(toSearch.getCompilationUnit().getSourceFile().toUri().toURL(), toSearch.getCompilationUnit());
   15.16 +                writer.record(toSearch.getCompilationUnit().getSourceFile().toUri().toURL(), toSearch.getCompilationUnit(), null);
   15.17                  writer.close();
   15.18  
   15.19                  if (!ii.findCandidates(pattern).isEmpty()) {
   15.20 @@ -124,8 +125,8 @@
   15.21          }
   15.22  
   15.23          @Override
   15.24 -        public BulkPattern create(Collection<? extends String> code, Collection<? extends Tree> patterns) {
   15.25 -            return new NFABasedBulkSearch().create(code, patterns);
   15.26 +        public BulkPattern create(Collection<? extends String> code, Collection<? extends Tree> patterns, Collection<? extends AdditionalQueryConstraints> additionalConstraints) {
   15.27 +            return new NFABasedBulkSearch().create(code, patterns, additionalConstraints);
   15.28          }
   15.29      }
   15.30  
    16.1 --- a/build.xml	Sun Jan 16 13:56:54 2011 +0100
    16.2 +++ b/build.xml	Sun Jan 16 19:22:56 2011 +0100
    16.3 @@ -13,6 +13,7 @@
    16.4          <copy file="${nbplatform.active.dir}/platform/core/org-openide-filesystems.jar" todir="server/lib" />
    16.5          <copy file="${nbplatform.active.dir}/platform/lib/org-openide-util.jar" todir="server/lib" />
    16.6          <copy file="${nbplatform.active.dir}/platform/lib/org-openide-util-lookup.jar" todir="server/lib" />
    16.7 +        <copy file="${nbplatform.active.dir}/ide/modules/org-netbeans-spi-editor-hints.jar" todir="server/lib" />
    16.8          <copy file="${nbplatform.active.dir}/java/modules/ext/javac-api-nb-7.0-b07.jar" todir="server/lib/javac" />
    16.9          <copy file="${nbplatform.active.dir}/java/modules/ext/javac-impl-nb-7.0-b07.jar" todir="server/lib/javac" />
   16.10      </target>
    17.1 --- a/server/indexer/nbproject/project.properties	Sun Jan 16 13:56:54 2011 +0100
    17.2 +++ b/server/indexer/nbproject/project.properties	Sun Jan 16 19:22:56 2011 +0100
    17.3 @@ -26,7 +26,10 @@
    17.4  endorsed.classpath=
    17.5  excludes=
    17.6  file.reference.org-netbeans-modules-java-source.jar=../lib/org-netbeans-modules-java-source.jar
    17.7 +file.reference.org-netbeans-spi-editor-hints.jar=../lib/org-netbeans-spi-editor-hints.jar
    17.8  file.reference.org-openide-filesystems.jar=../lib/org-openide-filesystems.jar
    17.9 +file.reference.org-openide-util-lookup.jar=../lib/org-openide-util-lookup.jar
   17.10 +file.reference.org-openide-util.jar=../lib/org-openide-util.jar
   17.11  file.reference.util-commons.jar=../../libs.jerig/external/util-commons.jar
   17.12  file.reference.util-lutz.jar=../../libs.jerig/external/util-lutz.jar
   17.13  file.reference.util-pojson.jar=../../libs.jerig/external/util-pojson.jar
   17.14 @@ -42,7 +45,10 @@
   17.15      ${file.reference.util-lutz.jar}:\
   17.16      ${file.reference.util-pojson.jar}:\
   17.17      ${file.reference.util-strast.jar}:\
   17.18 -    ${file.reference.org-openide-filesystems.jar}
   17.19 +    ${file.reference.org-openide-filesystems.jar}:\
   17.20 +    ${file.reference.org-openide-util.jar}:\
   17.21 +    ${file.reference.org-openide-util-lookup.jar}:\
   17.22 +    ${file.reference.org-netbeans-spi-editor-hints.jar}
   17.23  # Space-separated list of extra javac options
   17.24  javac.compilerargs=
   17.25  javac.deprecation=false
    18.1 --- a/server/indexer/src/org/netbeans/modules/jackpot30/server/indexer/StandaloneFinder.java	Sun Jan 16 13:56:54 2011 +0100
    18.2 +++ b/server/indexer/src/org/netbeans/modules/jackpot30/server/indexer/StandaloneFinder.java	Sun Jan 16 19:22:56 2011 +0100
    18.3 @@ -75,6 +75,9 @@
    18.4  import org.netbeans.modules.jackpot30.impl.indexing.FileBasedIndex;
    18.5  import org.netbeans.modules.jackpot30.impl.pm.BulkSearch;
    18.6  import org.netbeans.modules.jackpot30.impl.pm.BulkSearch.BulkPattern;
    18.7 +import org.netbeans.modules.jackpot30.spi.HintDescription;
    18.8 +import org.netbeans.modules.jackpot30.spi.HintDescription.AdditionalQueryConstraints;
    18.9 +import org.netbeans.modules.jackpot30.spi.PatternConvertor;
   18.10  
   18.11  /**
   18.12   *
   18.13 @@ -152,19 +155,25 @@
   18.14      }
   18.15      
   18.16      private static BulkPattern preparePattern(String pattern, Collection<Diagnostic<? extends JavaFileObject>> errors) {
   18.17 -        Collection<String> patterns = new LinkedList<String>();
   18.18 +        return preparePattern(PatternConvertor.create(pattern), errors);
   18.19 +    }
   18.20 +
   18.21 +    //XXX: copied from BatchSearch, may be possible to merge once CompilationInfo is accessible in server mode
   18.22 +    private static BulkPattern preparePattern(final Iterable<? extends HintDescription> patterns, Collection<Diagnostic<? extends JavaFileObject>> errors) {
   18.23 +        JavacTaskImpl javac = prepareJavacTaskImpl();
   18.24 +        Collection<String> code = new LinkedList<String>();
   18.25          Collection<Tree> trees = new LinkedList<Tree>();
   18.26 +        Collection<AdditionalQueryConstraints> additionalConstraints = new LinkedList<AdditionalQueryConstraints>();
   18.27  
   18.28 -        for (String s : pattern.split(";;")) {
   18.29 -            s = s.trim();
   18.30 -            if (s.isEmpty()) {
   18.31 -                continue;
   18.32 -            }
   18.33 -            patterns.add(s);
   18.34 -            trees.add(Utilities.parseAndAttribute(prepareJavacTaskImpl(), s, errors));
   18.35 +        for (HintDescription pattern : patterns) {
   18.36 +            String textPattern = pattern.getTriggerPattern().getPattern();
   18.37 +
   18.38 +            code.add(textPattern);
   18.39 +            trees.add(Utilities.parseAndAttribute(javac, textPattern, errors));
   18.40 +            additionalConstraints.add(pattern.getAdditionalConstraints());
   18.41          }
   18.42  
   18.43 -        return BulkSearch.getDefault().create(patterns, trees);
   18.44 +        return BulkSearch.getDefault().create(code, trees, additionalConstraints);
   18.45      }
   18.46  
   18.47      private static JavacTaskImpl prepareJavacTaskImpl() {
    19.1 --- a/server/indexer/src/org/netbeans/modules/jackpot30/server/indexer/StandaloneIndexer.java	Sun Jan 16 13:56:54 2011 +0100
    19.2 +++ b/server/indexer/src/org/netbeans/modules/jackpot30/server/indexer/StandaloneIndexer.java	Sun Jan 16 19:22:56 2011 +0100
    19.3 @@ -135,7 +135,7 @@
    19.4          JavacTaskImpl ct = (JavacTaskImpl)tool.getTask(null, null, devNull, Arrays.asList("-bootclasspath",  bootPath), null, fos);
    19.5          CompilationUnitTree cut = ct.parse().iterator().next();
    19.6  
    19.7 -        w.record(source.toURI().toURL(), cut);
    19.8 +        w.record(source.toURI().toURL(), cut, null);
    19.9  
   19.10          if (dw != null) {
   19.11              ct.analyze(ct.enter(Collections.singletonList(cut)));