Introducing several changes to Jackpot 3.0 proper needed for a full-blown server backend
authorJan Lahoda <jlahoda@netbeans.org>
Fri, 11 Feb 2011 22:33:43 +0100
changeset 5438ab0811eabd6
parent 541 bcaf48a2e220
child 544 04d4090c1fdb
Introducing several changes to Jackpot 3.0 proper needed for a full-blown server backend
api/src/org/netbeans/modules/jackpot30/impl/Utilities.java
api/src/org/netbeans/modules/jackpot30/impl/batch/BatchSearch.java
api/src/org/netbeans/modules/jackpot30/impl/batch/BatchUtilities.java
api/src/org/netbeans/modules/jackpot30/impl/indexing/CustomIndexerImpl.java
api/src/org/netbeans/modules/jackpot30/impl/pm/CopyFinder.java
api/test/unit/src/org/netbeans/modules/jackpot30/impl/batch/BatchSearchTest.java
api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/IndexingTestUtils.java
api/test/unit/src/org/netbeans/modules/jackpot30/impl/pm/CopyFinderTest.java
bridges/refactoring/src/org/netbeans/modules/jackpot30/refactoring/invertboolean/InvertBooleanRefactoringPluginImpl.java
cmdline/compiler/src/org/netbeans/modules/jackpot30/compiler/HintsAnnotationProcessing.java
cmdline/tool/src/org/netbeans/modules/jackpot30/cmdline/Main.java
file/src/org/netbeans/modules/jackpot30/file/DeclarativeHintRegistry.java
file/test/unit/src/org/netbeans/modules/jackpot30/file/DeclarativeHintRegistryTest.java
     1.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/Utilities.java	Tue Feb 08 23:16:16 2011 +0100
     1.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/Utilities.java	Fri Feb 11 22:33:43 2011 +0100
     1.3 @@ -327,6 +327,10 @@
     1.4          return parseAndAttribute(null, jti, pattern, null, errors);
     1.5      }
     1.6  
     1.7 +    public static Tree parseAndAttribute(JavacTaskImpl jti, String pattern, SourcePositions[] sourcePositions, Collection<Diagnostic<? extends JavaFileObject>> errors) {
     1.8 +        return parseAndAttribute(null, jti, pattern, null, sourcePositions, errors);
     1.9 +    }
    1.10 +
    1.11      private static Tree parseAndAttribute(CompilationInfo info, JavacTaskImpl jti, String pattern, Scope scope, Collection<Diagnostic<? extends JavaFileObject>> errors) {
    1.12          return parseAndAttribute(info, jti, pattern, scope, new SourcePositions[1], errors);
    1.13      }
     2.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/batch/BatchSearch.java	Tue Feb 08 23:16:16 2011 +0100
     2.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/batch/BatchSearch.java	Fri Feb 11 22:33:43 2011 +0100
     2.3 @@ -133,7 +133,7 @@
     2.4              private Set<FileObject> KNOWN_SOURCE_ROOTS = new HashSet<FileObject>(GlobalPathRegistry.getDefault().getSourceRoots());
     2.5              public Index findIndex(FileObject root, ProgressHandleWrapper progress) {
     2.6                  progress.startNextPart(1);
     2.7 -                if (KNOWN_SOURCE_ROOTS.contains(root)) {
     2.8 +                if (KNOWN_SOURCE_ROOTS.contains(root) || scope.forceIndicesUpToDate) {
     2.9                      try {
    2.10                          return FileBasedIndex.get(root.getURL());
    2.11                      } catch (IOException ex) {
    2.12 @@ -424,6 +424,10 @@
    2.13      }
    2.14      
    2.15      public static void getVerifiedSpans(BatchResult candidates, @NonNull ProgressHandleWrapper progress, final VerifiedSpansCallBack callback, final Collection<? super MessageImpl> problems) {
    2.16 +        getVerifiedSpans(candidates, progress, callback, false, problems);
    2.17 +    }
    2.18 +
    2.19 +    public static void getVerifiedSpans(BatchResult candidates, @NonNull ProgressHandleWrapper progress, final VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, final Collection<? super MessageImpl> problems) {
    2.20          int[] parts = new int[candidates.projectId2Resources.size()];
    2.21          int   index = 0;
    2.22  
    2.23 @@ -436,11 +440,11 @@
    2.24          for (Collection<? extends Resource> it :candidates.projectId2Resources.values()) {
    2.25              inner.startNextPart(it.size());
    2.26  
    2.27 -            getVerifiedSpans(it, inner, callback, problems);
    2.28 +            getVerifiedSpans(it, inner, callback, doNotRegisterClassPath, problems);
    2.29          }
    2.30      }
    2.31  
    2.32 -    private static void getVerifiedSpans(Collection<? extends Resource> resources, @NonNull final ProgressHandleWrapper progress, final VerifiedSpansCallBack callback, final Collection<? super MessageImpl> problems) {
    2.33 +    private static void getVerifiedSpans(Collection<? extends Resource> resources, @NonNull final ProgressHandleWrapper progress, final VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, final Collection<? super MessageImpl> problems) {
    2.34          Collection<FileObject> files = new LinkedList<FileObject>();
    2.35          final Map<FileObject, Resource> file2Resource = new HashMap<FileObject, Resource>();
    2.36  
    2.37 @@ -457,20 +461,24 @@
    2.38          }
    2.39  
    2.40          Map<ClasspathInfo, Collection<FileObject>> cp2Files = BatchUtilities.sortFiles(files);
    2.41 -        Set<ClassPath> toRegisterSet = new HashSet<ClassPath>();
    2.42 +        ClassPath[] toRegister = null;
    2.43  
    2.44 -        for (ClasspathInfo cpInfo : cp2Files.keySet()) {
    2.45 -            toRegisterSet.add(cpInfo.getClassPath(PathKind.SOURCE));
    2.46 -        }
    2.47 +        if (!doNotRegisterClassPath) {
    2.48 +            Set<ClassPath> toRegisterSet = new HashSet<ClassPath>();
    2.49  
    2.50 -        ClassPath[] toRegister = !toRegisterSet.isEmpty() ? toRegisterSet.toArray(new ClassPath[0]) : null;
    2.51 +            for (ClasspathInfo cpInfo : cp2Files.keySet()) {
    2.52 +                toRegisterSet.add(cpInfo.getClassPath(PathKind.SOURCE));
    2.53 +            }
    2.54  
    2.55 -        if (toRegister != null) {
    2.56 -            GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, toRegister);
    2.57 -            try {
    2.58 -                Utilities.waitScanFinished();
    2.59 -            } catch (InterruptedException ex) {
    2.60 -                Exceptions.printStackTrace(ex);
    2.61 +            toRegister = !toRegisterSet.isEmpty() ? toRegisterSet.toArray(new ClassPath[0]) : null;
    2.62 +
    2.63 +            if (toRegister != null) {
    2.64 +                GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, toRegister);
    2.65 +                try {
    2.66 +                    Utilities.waitScanFinished();
    2.67 +                } catch (InterruptedException ex) {
    2.68 +                    Exceptions.printStackTrace(ex);
    2.69 +                }
    2.70              }
    2.71          }
    2.72  
    2.73 @@ -563,18 +571,20 @@
    2.74          public  final String subIndex; //public only for AddScopePanel
    2.75          public  final boolean update; //public only for AddScopePanel
    2.76          private final Collection<? extends FileObject> sourceRoots;
    2.77 +        private final boolean forceIndicesUpToDate;
    2.78  
    2.79          private Scope() {
    2.80 -            this(null, null, null, null, true, null);
    2.81 +            this(null, null, null, null, true, null, false);
    2.82          }
    2.83  
    2.84 -        private Scope(ScopeType scopeType, String folder, String indexURL, String subIndex, boolean update, Collection<? extends FileObject> sourceRoots) {
    2.85 +        private Scope(ScopeType scopeType, String folder, String indexURL, String subIndex, boolean update, Collection<? extends FileObject> sourceRoots, boolean forceIndicesUpToDate) {
    2.86              this.scopeType = scopeType;
    2.87              this.folder = folder;
    2.88              this.indexURL = indexURL;
    2.89              this.subIndex = subIndex;
    2.90              this.update = update;
    2.91              this.sourceRoots = sourceRoots;
    2.92 +            this.forceIndicesUpToDate = forceIndicesUpToDate;
    2.93          }
    2.94  
    2.95          public String serialize() {
    2.96 @@ -591,27 +601,31 @@
    2.97          }
    2.98  
    2.99          public static Scope createAllOpenedProjectsScope() {
   2.100 -            return new Scope(ScopeType.ALL_OPENED_PROJECTS, null, null, null, false, null);
   2.101 +            return new Scope(ScopeType.ALL_OPENED_PROJECTS, null, null, null, false, null, false);
   2.102          }
   2.103  
   2.104          public static Scope createAllDependentOpenedSourceRoots(FileObject from) {
   2.105 -            return new Scope(ScopeType.ALL_DEPENDENT_OPENED_SOURCE_ROOTS, null, null, null, false, Collections.singletonList(from));
   2.106 +            return new Scope(ScopeType.ALL_DEPENDENT_OPENED_SOURCE_ROOTS, null, null, null, false, Collections.singletonList(from), false);
   2.107          }
   2.108  
   2.109          public static Scope createGivenFolderNoIndex(String folder) {
   2.110 -            return new Scope(ScopeType.GIVEN_FOLDER, folder, null, null, false, null);
   2.111 +            return new Scope(ScopeType.GIVEN_FOLDER, folder, null, null, false, null, false);
   2.112          }
   2.113  
   2.114          public static Scope createGivenFolderLocalIndex(String folder, File indexFolder, boolean update) {
   2.115 -            return new Scope(ScopeType.GIVEN_FOLDER, folder, indexFolder.getAbsolutePath(), null, update, null);
   2.116 +            return new Scope(ScopeType.GIVEN_FOLDER, folder, indexFolder.getAbsolutePath(), null, update, null, false);
   2.117          }
   2.118  
   2.119          public static Scope createGivenFolderRemoteIndex(String folder, String urlIndex, String subIndex) {
   2.120 -            return new Scope(ScopeType.GIVEN_FOLDER, folder, urlIndex, subIndex, false, null);
   2.121 +            return new Scope(ScopeType.GIVEN_FOLDER, folder, urlIndex, subIndex, false, null, false);
   2.122          }
   2.123  
   2.124          public static Scope createGivenSourceRoots(FileObject... sourceRoots) {
   2.125 -            return new Scope(ScopeType.GIVEN_SOURCE_ROOTS, null, null, null, false, Arrays.asList(sourceRoots));
   2.126 +            return createGivenSourceRoots(false, sourceRoots);
   2.127 +        }
   2.128 +
   2.129 +        public static Scope createGivenSourceRoots(boolean forceIndicesUpToDate, FileObject... sourceRoots) {
   2.130 +            return new Scope(ScopeType.GIVEN_SOURCE_ROOTS, null, null, null, false, Arrays.asList(sourceRoots), forceIndicesUpToDate);
   2.131          }
   2.132  
   2.133          public String getDisplayName() {
     3.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/batch/BatchUtilities.java	Tue Feb 08 23:16:16 2011 +0100
     3.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/batch/BatchUtilities.java	Fri Feb 11 22:33:43 2011 +0100
     3.3 @@ -44,13 +44,10 @@
     3.4  import com.sun.source.util.TreePath;
     3.5  import com.sun.tools.javac.api.JavacTaskImpl;
     3.6  import com.sun.tools.javac.util.Log;
     3.7 -import java.io.ByteArrayInputStream;
     3.8 -import java.io.File;
     3.9  import java.io.IOException;
    3.10 -import java.io.InputStream;
    3.11 -import java.io.OutputStream;
    3.12  import java.io.Reader;
    3.13  import java.io.StringReader;
    3.14 +import java.io.Writer;
    3.15  import java.lang.reflect.Constructor;
    3.16  import java.lang.reflect.Method;
    3.17  import java.nio.charset.Charset;
    3.18 @@ -71,6 +68,7 @@
    3.19  import java.util.logging.Logger;
    3.20  import javax.swing.text.Document;
    3.21  import org.netbeans.api.annotations.common.NonNull;
    3.22 +import org.netbeans.api.annotations.common.NullAllowed;
    3.23  import org.netbeans.api.java.classpath.ClassPath;
    3.24  import org.netbeans.api.java.source.ClasspathInfo;
    3.25  import org.netbeans.api.java.source.CompilationController;
    3.26 @@ -327,7 +325,7 @@
    3.27  //        }
    3.28      }
    3.29  
    3.30 -    public static void exportDiff(ModificationResult result, OutputStream out) throws IOException {
    3.31 +    public static void exportDiff(ModificationResult result, @NullAllowed FileObject relativeTo, Writer out) throws IOException {
    3.32          for (FileObject f : result.getModifiedFileObjects()) {
    3.33              Charset c = FileEncodingQuery.getEncoding(f);
    3.34              String orig = new String(f.asBytes(), c);
    3.35 @@ -336,15 +334,15 @@
    3.36              if (orig.equals(nue)) {
    3.37                  continue;
    3.38              }
    3.39 +
    3.40 +            String name = relativeTo != null ? FileUtil.getRelativePath(relativeTo, f) : FileUtil.toFile(f).getAbsolutePath();
    3.41              
    3.42 -            File jiFile = FileUtil.toFile(f);
    3.43 -            
    3.44 -            doExportDiff(jiFile.getAbsolutePath(), orig, nue, out);
    3.45 +            doExportDiff(name, orig, nue, out);
    3.46          }
    3.47      }
    3.48  
    3.49      //copied from the diff module:
    3.50 -    private static void doExportDiff(String name, String original, String modified, OutputStream out) throws IOException {
    3.51 +    private static void doExportDiff(String name, String original, String modified, Writer out) throws IOException {
    3.52          DiffProvider diff = new BuiltInDiffProvider();//(DiffProvider) Lookup.getDefault().lookup(DiffProvider.class);
    3.53  
    3.54          Reader r1 = null;
    3.55 @@ -361,7 +359,6 @@
    3.56          }
    3.57  
    3.58          try {
    3.59 -            InputStream is;
    3.60              r1 = new StringReader(original);
    3.61              r2 = new StringReader(modified);
    3.62              TextDiffVisualizer.TextDiffInfo info = new TextDiffVisualizer.TextDiffInfo(
    3.63 @@ -380,12 +377,7 @@
    3.64  //            } else {
    3.65  //                diffText = TextDiffVisualizer.differenceToNormalDiffText(info);
    3.66  //            }
    3.67 -            is = new ByteArrayInputStream(diffText.getBytes("utf8"));  // NOI18N
    3.68 -            while(true) {
    3.69 -                int i = is.read();
    3.70 -                if (i == -1) break;
    3.71 -                out.write(i);
    3.72 -            }
    3.73 +            out.write(diffText);
    3.74          } finally {
    3.75              if (r1 != null) try { r1.close(); } catch (Exception e) {}
    3.76              if (r2 != null) try { r2.close(); } catch (Exception e) {}
     4.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/indexing/CustomIndexerImpl.java	Tue Feb 08 23:16:16 2011 +0100
     4.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/indexing/CustomIndexerImpl.java	Fri Feb 11 22:33:43 2011 +0100
     4.3 @@ -102,13 +102,20 @@
     4.4                  w[0].remove(path);
     4.5              }
     4.6  
     4.7 +            final boolean attributed = Boolean.getBoolean(CustomIndexerImpl.class.getName() + "-attributed");
     4.8 +
     4.9              if (!toIndex.isEmpty()) {
    4.10                  JavaSource.create(cpInfo, toIndex).runUserActionTask(new Task<CompilationController>() {
    4.11                      public void run(final CompilationController cc) throws Exception {
    4.12 +                        if (attributed) {
    4.13 +                            if (cc.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0)
    4.14 +                                return ;
    4.15 +                        } else {
    4.16                          if (cc.toPhase(Phase.PARSED).compareTo(Phase.PARSED) < 0)
    4.17                              return ;
    4.18 +                        }
    4.19  
    4.20 -                        w[0].record(cc.getFileObject().getURL(), cc.getCompilationUnit(), null);
    4.21 +                        w[0].record(cc.getFileObject().getURL(), cc.getCompilationUnit(), attributed ? new AttributionWrapper(cc) : null);
    4.22                      }
    4.23                  }, true);
    4.24              }
     5.1 --- a/api/src/org/netbeans/modules/jackpot30/impl/pm/CopyFinder.java	Tue Feb 08 23:16:16 2011 +0100
     5.2 +++ b/api/src/org/netbeans/modules/jackpot30/impl/pm/CopyFinder.java	Fri Feb 11 22:33:43 2011 +0100
     5.3 @@ -363,6 +363,8 @@
     5.4                          bind = info.getTypes().isAssignable(real, designed);
     5.5                      else
     5.6                          bind = false;
     5.7 +                } else {
     5.8 +                    bind = designed == null;
     5.9                  }
    5.10  
    5.11                  if (bind) {
     6.1 --- a/api/test/unit/src/org/netbeans/modules/jackpot30/impl/batch/BatchSearchTest.java	Tue Feb 08 23:16:16 2011 +0100
     6.2 +++ b/api/test/unit/src/org/netbeans/modules/jackpot30/impl/batch/BatchSearchTest.java	Fri Feb 11 22:33:43 2011 +0100
     6.3 @@ -39,6 +39,8 @@
     6.4  
     6.5  package org.netbeans.modules.jackpot30.impl.batch;
     6.6  
     6.7 +import org.netbeans.modules.jackpot30.impl.indexing.CustomIndexerImpl;
     6.8 +import org.netbeans.api.java.source.SourceUtils;
     6.9  import java.net.URLStreamHandlerFactory;
    6.10  import junit.framework.Assert;
    6.11  import java.io.ByteArrayInputStream;
    6.12 @@ -90,6 +92,7 @@
    6.13  
    6.14  import org.openide.util.Exceptions;
    6.15  import org.openide.util.lookup.ServiceProvider;
    6.16 +import static org.netbeans.modules.jackpot30.impl.indexing.IndexingTestUtils.writeFiles;
    6.17  import static org.netbeans.modules.jackpot30.impl.indexing.IndexingTestUtils.writeFilesAndWaitForScan;
    6.18  
    6.19  /**
    6.20 @@ -215,7 +218,7 @@
    6.21          assertEquals(golden, output);
    6.22  
    6.23          //check verification:
    6.24 -        Map<String, Map<String, Iterable<String>>> verifiedOutput = verifiedSpans(result);
    6.25 +        Map<String, Map<String, Iterable<String>>> verifiedOutput = verifiedSpans(result, false);
    6.26          Map<String, Map<String, Iterable<String>>> verifiedGolden = new HashMap<String, Map<String, Iterable<String>>>();
    6.27  
    6.28          verifiedGolden.put(src1.getURL().toExternalForm(), Collections.<String, Iterable<String>>singletonMap("test/Test1.java", Arrays.<String>asList()));
    6.29 @@ -275,7 +278,7 @@
    6.30          });
    6.31  
    6.32  //        verifiedGolden.put(data.getURL().toExternalForm(), Arrays.asList("0:75-0:86:verifier:TODO: No display name"));
    6.33 -        Map<String, Map<String, Iterable<String>>> verifiedOutput = verifiedSpans(result);
    6.34 +        Map<String, Map<String, Iterable<String>>> verifiedOutput = verifiedSpans(result, false);
    6.35          Map<String, Map<String, Iterable<String>>> verifiedGolden = new HashMap<String, Map<String, Iterable<String>>>();
    6.36  
    6.37          Map<String, Iterable<String>> verifiedGoldenPart = new HashMap<String, Iterable<String>>();
    6.38 @@ -367,6 +370,88 @@
    6.39          assertEquals(golden, output);
    6.40      }
    6.41  
    6.42 +    public void testEfficientIndexQuery() throws Exception {
    6.43 +        String orig = System.getProperty(CustomIndexerImpl.class.getName() + "-attributed", "false");
    6.44 +
    6.45 +        try {
    6.46 +            System.setProperty(CustomIndexerImpl.class.getName() + "-attributed", "true");
    6.47 +            FileObject data = FileUtil.createFolder(workdir, "data");
    6.48 +            FileObject extrasrc = FileUtil.createFolder(data, "extrasrc");
    6.49 +            writeFilesAndWaitForScan(extrasrc,
    6.50 +                                     new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
    6.51 +                                     new File("test/Test2.java", "package test; public class Test2 { private boolean isDirectory() { return this.isDirectory(); } }"));
    6.52 +
    6.53 +            ClassPath extraCP = ClassPathSupport.createClassPath(extrasrc);
    6.54 +
    6.55 +            GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, new ClassPath[] {extraCP});
    6.56 +
    6.57 +            SourceUtils.waitScanFinished();
    6.58 +
    6.59 +            GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, new ClassPath[] {extraCP});
    6.60 +
    6.61 +            //delete the source files, to verify that the index and just the index is used the get the results:
    6.62 +            extrasrc.getFileObject("test/Test1.java").delete();
    6.63 +            extrasrc.getFileObject("test/Test2.java").delete();
    6.64 +
    6.65 +            Iterable<? extends HintDescription> hints = PatternConvertor.create("$1.isDirectory();;");
    6.66 +            Map<String, Iterable<String>> golden = new HashMap<String, Iterable<String>>();
    6.67 +
    6.68 +            golden.put(extrasrc.getURL().toExternalForm(), new HashSet<String>(Arrays.asList("test/Test1.java", "test/Test2.java")));
    6.69 +
    6.70 +            BatchResult result = BatchSearch.findOccurrences(hints, Scope.createGivenSourceRoots(true, extrasrc));
    6.71 +            Map<String, Iterable<String>> output = toDebugOutput(result);
    6.72 +
    6.73 +            assertEquals(golden, output);
    6.74 +
    6.75 +            Iterable<? extends HintDescription> hints2 = PatternConvertor.create("$1.isDirectory() :: $1 instanceof java.io.File;;");
    6.76 +            Map<String, Iterable<String>> golden2 = new HashMap<String, Iterable<String>>();
    6.77 +
    6.78 +            golden2.put(extrasrc.getURL().toExternalForm(), new HashSet<String>(Arrays.asList("test/Test1.java")));
    6.79 +
    6.80 +            BatchResult result2 = BatchSearch.findOccurrences(hints2, Scope.createGivenSourceRoots(true, extrasrc));
    6.81 +            Map<String, Iterable<String>> output2 = toDebugOutput(result2);
    6.82 +
    6.83 +            assertEquals(golden2, output2);
    6.84 +
    6.85 +            //add the content back, so that the spans can be verified:
    6.86 +            writeFiles(extrasrc,
    6.87 +                       new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
    6.88 +                       new File("test/Test2.java", "package test; public class Test2 { private boolean isDirectory() { return this.isDirectory(); } }"));
    6.89 +
    6.90 +            //check verification:
    6.91 +            final Set<FileObject> added = new HashSet<FileObject>();
    6.92 +            final Set<FileObject> removed = new HashSet<FileObject>();
    6.93 +
    6.94 +            GlobalPathRegistry.getDefault().addGlobalPathRegistryListener(new GlobalPathRegistryListener() {
    6.95 +                public void pathsAdded(GlobalPathRegistryEvent event) {
    6.96 +                    for (ClassPath cp : event.getChangedPaths()) {
    6.97 +                        added.addAll(Arrays.asList(cp.getRoots()));
    6.98 +                    }
    6.99 +                }
   6.100 +                public void pathsRemoved(GlobalPathRegistryEvent event) {
   6.101 +                    for (ClassPath cp : event.getChangedPaths()) {
   6.102 +                        removed.addAll(Arrays.asList(cp.getRoots()));
   6.103 +                    }
   6.104 +                }
   6.105 +            });
   6.106 +
   6.107 +            Map<String, Map<String, Iterable<String>>> verifiedOutput = verifiedSpans(result2, true);
   6.108 +            Map<String, Map<String, Iterable<String>>> verifiedGolden = new HashMap<String, Map<String, Iterable<String>>>();
   6.109 +
   6.110 +            Map<String, Iterable<String>> verifiedGoldenPart = new HashMap<String, Iterable<String>>();
   6.111 +
   6.112 +            verifiedGoldenPart.put("test/Test1.java", Arrays.<String>asList("0:82-0:93:verifier:TODO: No display name"));
   6.113 +
   6.114 +            verifiedGolden.put(extrasrc.getURL().toExternalForm(), verifiedGoldenPart);
   6.115 +
   6.116 +            assertEquals(verifiedGolden, verifiedOutput);
   6.117 +            assertEquals(Collections.emptySet(), added);
   6.118 +            assertEquals(Collections.emptySet(), removed);
   6.119 +        } finally {
   6.120 +            System.setProperty(CustomIndexerImpl.class.getName() + "-attributed", orig);
   6.121 +        }
   6.122 +    }
   6.123 +
   6.124      public void testScopeDeSerialization() throws Exception {
   6.125          serializeDeserialize(Scope.createAllOpenedProjectsScope());
   6.126          serializeDeserialize(Scope.createGivenFolderLocalIndex(new java.io.File("/tmp/src").getAbsolutePath(), new java.io.File("/tmp/index"), true));
   6.127 @@ -424,7 +509,7 @@
   6.128          return output;
   6.129      }
   6.130  
   6.131 -    private Map<String, Map<String, Iterable<String>>> verifiedSpans(BatchResult candidates) throws Exception {
   6.132 +    private Map<String, Map<String, Iterable<String>>> verifiedSpans(BatchResult candidates, boolean doNotRegisterClassPath) throws Exception {
   6.133          final Map<String, Map<String, Iterable<String>>> result = new HashMap<String, Map<String, Iterable<String>>>();
   6.134          List<MessageImpl> errors = new LinkedList<MessageImpl>();
   6.135          BatchSearch.getVerifiedSpans(candidates, new ProgressHandleWrapper(1), new BatchSearch.VerifiedSpansCallBack() {
   6.136 @@ -450,7 +535,7 @@
   6.137              public void cannotVerifySpan(Resource r) {
   6.138                  fail("Cannot verify: " +r.getRelativePath());
   6.139              }
   6.140 -        }, errors);
   6.141 +        }, doNotRegisterClassPath, errors);
   6.142  
   6.143          return result;
   6.144      }
     7.1 --- a/api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/IndexingTestUtils.java	Tue Feb 08 23:16:16 2011 +0100
     7.2 +++ b/api/test/unit/src/org/netbeans/modules/jackpot30/impl/indexing/IndexingTestUtils.java	Fri Feb 11 22:33:43 2011 +0100
     7.3 @@ -72,7 +72,7 @@
     7.4  
     7.5  public class IndexingTestUtils {
     7.6      
     7.7 -    public static void writeFilesAndWaitForScan(FileObject sourceRoot, File... files) throws Exception {
     7.8 +    public static void writeFiles(FileObject sourceRoot, File... files) throws Exception {
     7.9          for (FileObject c : sourceRoot.getChildren()) {
    7.10              c.delete();
    7.11          }
    7.12 @@ -81,7 +81,10 @@
    7.13              FileObject fo = FileUtil.createData(sourceRoot, f.filename);
    7.14              TestUtilities.copyStringToFile(fo, f.content);
    7.15          }
    7.16 +    }
    7.17  
    7.18 +    public static void writeFilesAndWaitForScan(FileObject sourceRoot, File... files) throws Exception {
    7.19 +        writeFiles(sourceRoot, files);
    7.20          SourceUtils.waitScanFinished();
    7.21      }
    7.22  
     8.1 --- a/api/test/unit/src/org/netbeans/modules/jackpot30/impl/pm/CopyFinderTest.java	Tue Feb 08 23:16:16 2011 +0100
     8.2 +++ b/api/test/unit/src/org/netbeans/modules/jackpot30/impl/pm/CopyFinderTest.java	Fri Feb 11 22:33:43 2011 +0100
     8.3 @@ -298,4 +298,14 @@
     8.4                               true);
     8.5      }
     8.6  
     8.7 +    public void testNonResolvableType() throws Exception {
     8.8 +        performVariablesTest("package test; public class Test { { java.io.File f = null; boolean b = f.isDirectory(); } }",
     8.9 +                             "$1{can.not.Resolve}.$m($args$)",
    8.10 +                             new Pair[0],
    8.11 +                             new Pair[0],
    8.12 +                             new Pair[0],
    8.13 +                             true,
    8.14 +                             true);
    8.15 +    }
    8.16 +
    8.17  }
     9.1 --- a/bridges/refactoring/src/org/netbeans/modules/jackpot30/refactoring/invertboolean/InvertBooleanRefactoringPluginImpl.java	Tue Feb 08 23:16:16 2011 +0100
     9.2 +++ b/bridges/refactoring/src/org/netbeans/modules/jackpot30/refactoring/invertboolean/InvertBooleanRefactoringPluginImpl.java	Fri Feb 11 22:33:43 2011 +0100
     9.3 @@ -52,6 +52,7 @@
     9.4  import java.util.Map;
     9.5  import javax.lang.model.element.Modifier;
     9.6  import javax.lang.model.element.TypeElement;
     9.7 +import javax.lang.model.type.TypeMirror;
     9.8  import org.netbeans.api.java.source.JavaSource;
     9.9  import org.netbeans.api.java.source.JavaSource.Phase;
    9.10  import org.netbeans.api.java.source.ModificationResult;
    9.11 @@ -200,7 +201,9 @@
    9.12                                  constraints.append(" && ");
    9.13                              }
    9.14                              parameters.append("$").append(count);
    9.15 -                            constraints.append("$").append(count).append(" instanceof ").append(parameter.getTrees().getTypeMirror(new TreePath(new TreePath(path, vt), vt.getType())));
    9.16 +                            TypeMirror type = parameter.getTrees().getTypeMirror(new TreePath(new TreePath(path, vt), vt.getType()));
    9.17 +                            type = parameter.getTypes().erasure(type);
    9.18 +                            constraints.append("$").append(count).append(" instanceof ").append(type);
    9.19                              count++;
    9.20                          }
    9.21  
    10.1 --- a/cmdline/compiler/src/org/netbeans/modules/jackpot30/compiler/HintsAnnotationProcessing.java	Tue Feb 08 23:16:16 2011 +0100
    10.2 +++ b/cmdline/compiler/src/org/netbeans/modules/jackpot30/compiler/HintsAnnotationProcessing.java	Fri Feb 11 22:33:43 2011 +0100
    10.3 @@ -40,7 +40,8 @@
    10.4  
    10.5  import java.io.File;
    10.6  import java.io.IOException;
    10.7 -import java.io.OutputStream;
    10.8 +import java.io.OutputStreamWriter;
    10.9 +import java.io.Writer;
   10.10  import java.util.Arrays;
   10.11  import java.util.Collection;
   10.12  import java.util.Collections;
   10.13 @@ -98,7 +99,7 @@
   10.14          EXTRA_HINTS
   10.15      )));
   10.16  
   10.17 -    private OutputStream diff;
   10.18 +    private Writer diff;
   10.19  
   10.20      @Override
   10.21      protected boolean initialize(ProcessingEnvironment processingEnv) {
   10.22 @@ -199,10 +200,10 @@
   10.23                  if (diff == null) {
   10.24                      FileObject upgradeDiffFO = processingEnv.getFiler().createResource(StandardLocation.SOURCE_OUTPUT, "", "META-INF/upgrade/upgrade.diff");
   10.25  
   10.26 -                    diff = upgradeDiffFO.openOutputStream();
   10.27 +                    diff = new OutputStreamWriter(upgradeDiffFO.openOutputStream());
   10.28                  }
   10.29  
   10.30 -                BatchUtilities.exportDiff(mr, diff);
   10.31 +                BatchUtilities.exportDiff(mr, null, diff);
   10.32              }
   10.33          } catch (IOException ex) {
   10.34              Exceptions.printStackTrace(ex);
    11.1 --- a/cmdline/tool/src/org/netbeans/modules/jackpot30/cmdline/Main.java	Tue Feb 08 23:16:16 2011 +0100
    11.2 +++ b/cmdline/tool/src/org/netbeans/modules/jackpot30/cmdline/Main.java	Fri Feb 11 22:33:43 2011 +0100
    11.3 @@ -40,11 +40,14 @@
    11.4  package org.netbeans.modules.jackpot30.cmdline;
    11.5  
    11.6  import java.io.BufferedOutputStream;
    11.7 +import java.io.BufferedWriter;
    11.8  import java.io.File;
    11.9  import java.io.FileOutputStream;
   11.10  import java.io.IOException;
   11.11  import java.io.OutputStream;
   11.12 +import java.io.OutputStreamWriter;
   11.13  import java.io.PrintStream;
   11.14 +import java.io.Writer;
   11.15  import java.net.URL;
   11.16  import java.util.ArrayList;
   11.17  import java.util.Collection;
   11.18 @@ -343,13 +346,13 @@
   11.19          Collection<ModificationResult> diffs = BatchUtilities.applyFixes(occurrences, w, new AtomicBoolean(), problems);
   11.20  
   11.21          if (out != null) {
   11.22 -            OutputStream outS = null;
   11.23 +            Writer outS = null;
   11.24  
   11.25              try {
   11.26 -                outS = new BufferedOutputStream(new FileOutputStream(out));
   11.27 +                outS = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(out)));
   11.28  
   11.29                  for (ModificationResult mr : diffs) {
   11.30 -                    BatchUtilities.exportDiff(mr, outS);
   11.31 +                    BatchUtilities.exportDiff(mr, null, outS);
   11.32                  }
   11.33              } finally {
   11.34                  try {
    12.1 --- a/file/src/org/netbeans/modules/jackpot30/file/DeclarativeHintRegistry.java	Tue Feb 08 23:16:16 2011 +0100
    12.2 +++ b/file/src/org/netbeans/modules/jackpot30/file/DeclarativeHintRegistry.java	Fri Feb 11 22:33:43 2011 +0100
    12.3 @@ -45,6 +45,7 @@
    12.4  import java.util.Collection;
    12.5  import java.util.Collections;
    12.6  import java.util.HashMap;
    12.7 +import java.util.HashSet;
    12.8  import java.util.LinkedHashMap;
    12.9  import java.util.LinkedList;
   12.10  import java.util.List;
   12.11 @@ -52,6 +53,7 @@
   12.12  import java.util.Map;
   12.13  import java.util.MissingResourceException;
   12.14  import java.util.ResourceBundle;
   12.15 +import java.util.Set;
   12.16  import java.util.logging.Level;
   12.17  import java.util.logging.Logger;
   12.18  import org.netbeans.api.annotations.common.NonNull;
   12.19 @@ -66,6 +68,7 @@
   12.20  import org.netbeans.modules.jackpot30.file.DeclarativeHintsParser.Result;
   12.21  import org.netbeans.modules.jackpot30.spi.ClassPathBasedHintProvider;
   12.22  import org.netbeans.modules.jackpot30.spi.HintDescription;
   12.23 +import org.netbeans.modules.jackpot30.spi.HintDescription.AdditionalQueryConstraints;
   12.24  import org.netbeans.modules.jackpot30.spi.HintDescription.PatternDescription;
   12.25  import org.netbeans.modules.jackpot30.spi.HintDescriptionFactory;
   12.26  import org.netbeans.modules.jackpot30.spi.HintMetadata;
   12.27 @@ -251,7 +254,7 @@
   12.28  
   12.29                  Instanceof i = (Instanceof) c;
   12.30  
   12.31 -                constraints.put(i.variable, i.constraint);
   12.32 +                constraints.put(i.variable, i.constraint.trim()); //TODO: may i.constraint contain comments? if so, they need to be removed
   12.33              }
   12.34  
   12.35              String imports = parsed.importsBlock != null ? spec.substring(parsed.importsBlock[0], parsed.importsBlock[1]) : "";
   12.36 @@ -297,6 +300,7 @@
   12.37  
   12.38              f = f.setWorker(new DeclarativeHintsWorker(displayName, hint.conditions, imports, fixes, options, primarySuppressWarningsKey));
   12.39              f = f.setMetadata(currentMeta);
   12.40 +            f = f.setAdditionalConstraints(new AdditionalQueryConstraints(new HashSet<String>(constraints.values())));
   12.41  
   12.42              Collection<HintDescription> hints = result.get(currentMeta);
   12.43  
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/file/test/unit/src/org/netbeans/modules/jackpot30/file/DeclarativeHintRegistryTest.java	Fri Feb 11 22:33:43 2011 +0100
    13.3 @@ -0,0 +1,73 @@
    13.4 +/*
    13.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    13.6 + *
    13.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
    13.8 + *
    13.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   13.10 + * Other names may be trademarks of their respective owners.
   13.11 + *
   13.12 + * The contents of this file are subject to the terms of either the GNU
   13.13 + * General Public License Version 2 only ("GPL") or the Common
   13.14 + * Development and Distribution License("CDDL") (collectively, the
   13.15 + * "License"). You may not use this file except in compliance with the
   13.16 + * License. You can obtain a copy of the License at
   13.17 + * http://www.netbeans.org/cddl-gplv2.html
   13.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   13.19 + * specific language governing permissions and limitations under the
   13.20 + * License.  When distributing the software, include this License Header
   13.21 + * Notice in each file and include the License file at
   13.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   13.23 + * particular file as subject to the "Classpath" exception as provided
   13.24 + * by Oracle in the GPL Version 2 section of the License file that
   13.25 + * accompanied this code. If applicable, add the following below the
   13.26 + * License Header, with the fields enclosed by brackets [] replaced by
   13.27 + * your own identifying information:
   13.28 + * "Portions Copyrighted [year] [name of copyright owner]"
   13.29 + *
   13.30 + * If you wish your version of this file to be governed by only the CDDL
   13.31 + * or only the GPL Version 2, indicate your decision by adding
   13.32 + * "[Contributor] elects to include this software in this distribution
   13.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
   13.34 + * single choice of license, a recipient has the option to distribute
   13.35 + * your version of this file under either the CDDL, the GPL Version 2 or
   13.36 + * to extend the choice of license to its licensees as provided above.
   13.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
   13.38 + * Version 2 license, then the option applies only if the new code is
   13.39 + * made subject to such option by the copyright holder.
   13.40 + *
   13.41 + * Contributor(s):
   13.42 + *
   13.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
   13.44 + */
   13.45 +
   13.46 +package org.netbeans.modules.jackpot30.file;
   13.47 +
   13.48 +import java.util.Arrays;
   13.49 +import java.util.Collection;
   13.50 +import java.util.HashSet;
   13.51 +import static org.junit.Assert.*;
   13.52 +import org.netbeans.junit.NbTestCase;
   13.53 +import org.netbeans.modules.jackpot30.spi.HintDescription;
   13.54 +
   13.55 +/**
   13.56 + *
   13.57 + * @author lahvac
   13.58 + */
   13.59 +public class DeclarativeHintRegistryTest extends NbTestCase {
   13.60 +
   13.61 +    public DeclarativeHintRegistryTest(String name) {
   13.62 +        super(name);
   13.63 +    }
   13.64 +
   13.65 +    public void testAdditionalConstraints() {
   13.66 +        Collection<Collection<? extends HintDescription>> allHints = DeclarativeHintRegistry.parseHints(null, "$1 :: $1 instanceof java.lang.String ;;").values();
   13.67 +
   13.68 +        assertEquals(1, allHints.size());
   13.69 +        assertEquals(1, allHints.iterator().next().size());
   13.70 +
   13.71 +        HintDescription hd = allHints.iterator().next().iterator().next();
   13.72 +
   13.73 +        assertEquals(new HashSet<String>(Arrays.asList("java.lang.String")), hd.getAdditionalConstraints().requiredErasedTypes);
   13.74 +    }
   13.75 +
   13.76 +}
   13.77 \ No newline at end of file