[hg] main-silver: #224783:Rename Package Causes Phantom Error

  • From: Tomas Zezula < >
  • To:
  • Subject: [hg] main-silver: #224783:Rename Package Causes Phantom Error
  • Date: Tue, 15 Jan 2013 11:39:10 -0800

changeset 6376abf26a19 in main-silver ((none))
details: http://hg.netbeans.org/main-silver/rev/6376abf26a19
description:
        #224783:Rename Package Causes Phantom Error

diffstat:

 
parsing.api/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawler.java
               |  55 +++++++++-
 
parsing.api/test/unit/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawlerTest.java
 |  54 +++++++++-
 2 files changed, 102 insertions(+), 7 deletions(-)

diffs (193 lines):

diff --git 
a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawler.java
 
b/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawler.java
--- 
a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawler.java
+++ 
b/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawler.java
@@ -72,6 +72,7 @@
  */
 final class FileObjectCrawler extends Crawler {
 
+    private static final char SEPARATOR = '/';  //NOI18N
     private static final Logger LOG = 
Logger.getLogger(FileObjectCrawler.class.getName());
     /*test*/ static Map<Pair<File,File>,Boolean> mockLinkTypes;
 
@@ -113,19 +114,35 @@
 
         if (files != null) {
             if (files.length > 1) {
-                Map<FileObject, Set<FileObject>> clusters = new 
HashMap<FileObject, Set<FileObject>>();
-                for(FileObject f : files) {
+                final Map<FileObject, Set<FileObject>> clusters = new 
HashMap<FileObject, Set<FileObject>>();
+                final Map<FileObject, StringBuilder> relPaths = new 
HashMap<FileObject, StringBuilder>();
+NEXT_FILE:      for(FileObject f : files) {
                     FileObject parent = f.getParent();
                     Set<FileObject> cluster = clusters.get(parent);
                     if (cluster == null) {
+                        StringBuilder currentRelPath = getRelativePath(root, 
parent);
+                        for (Iterator<Map.Entry<FileObject,StringBuilder>> 
it = relPaths.entrySet().iterator(); it.hasNext();) {
+                            final Map.Entry<FileObject, StringBuilder> 
relPath = it.next();
+                            switch (getFileRelation(currentRelPath, 
relPath.getValue())) {
+                                case FIRST_IN_SECOND:
+                                    continue NEXT_FILE;
+                                case SECOND_IN_FIRST:
+                                    clusters.remove(relPath.getKey());
+                                    it.remove();
+                                    break;
+                                case EQUAL:
+                                    throw new IllegalStateException();
+                            }
+                        }
                         cluster = new HashSet<FileObject>();
                         clusters.put(parent, cluster);
+                        relPaths.put(parent, currentRelPath);
                     }
                     cluster.add(f);
                 }
                 for(FileObject parent : clusters.keySet()) {
                     Set<FileObject> cluster = clusters.get(parent);
-                    StringBuilder relativePath = getRelativePath(root, 
parent);
+                    StringBuilder relativePath = relPaths.get(parent);
                     if (relativePath != null) {
                         finished = collect(
                                 cluster.toArray(new 
FileObject[cluster.size()]),
@@ -218,7 +235,7 @@
 
             relativePathBuilder.append(fo.getNameExt());
             boolean folder = fo.isFolder();
-            if (folder) relativePathBuilder.append('/');
+            if (folder) relativePathBuilder.append(SEPARATOR);
             String relativePath = relativePathBuilder.toString();
             try {
                 if (entry != null && !entry.includes(relativePath)) {
@@ -267,7 +284,7 @@
         if (rp != null) {
             StringBuilder relativePath = new StringBuilder(rp);
             if (relativePath.length() > 0) {
-                relativePath.append('/'); //NOI18N
+                relativePath.append(SEPARATOR);
             }
             return relativePath;
         } else {
@@ -351,6 +368,27 @@
         return result;
     }
     
+    @NonNull
+    private static PathRelation getFileRelation (
+            @NonNull final StringBuilder firstPath,
+            @NonNull final StringBuilder secondPath) {
+        final int min = Math.min(firstPath.length(),secondPath.length());
+        for (int i=0; i<min; i++) {
+            if (firstPath.charAt(i) != firstPath.charAt(i)) {
+                return PathRelation.UNRELATED;
+            }
+        }
+        if (firstPath.length() > secondPath.length()) {
+            assert secondPath.length() == 0 || 
secondPath.charAt(secondPath.length()-1) == SEPARATOR;
+            return PathRelation.FIRST_IN_SECOND;
+        } else if (firstPath.length() < secondPath.length()) {
+            assert firstPath.length() == 0 || 
firstPath.charAt(firstPath.length()-1) == SEPARATOR;
+            return PathRelation.SECOND_IN_FIRST;
+        } else {
+            return PathRelation.EQUAL;
+        }
+    }
+    
     private static final class Stats {
         public int filesCount;
         public long linkCheckTime;
@@ -388,4 +426,11 @@
             }
         };
     } // End of Stats class
+
+    private enum PathRelation {
+        UNRELATED,
+        EQUAL,
+        FIRST_IN_SECOND,
+        SECOND_IN_FIRST
 }
+}
diff --git 
a/parsing.api/test/unit/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawlerTest.java
 
b/parsing.api/test/unit/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawlerTest.java
--- 
a/parsing.api/test/unit/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawlerTest.java
+++ 
b/parsing.api/test/unit/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawlerTest.java
@@ -46,11 +46,14 @@
 import java.io.File;
 import java.io.IOException;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.regex.Pattern;
@@ -303,17 +306,64 @@
                 "folder2/data3.txt");
     }
 
+    public void testDuplicateResults1() throws IOException {
+        File root = new File(getWorkDir(), "src");
+        String [] paths = new String [] {
+                "org/pckg1/file1.txt",
+                "org/pckg1/pckg2/file1.txt",
+                "org/pckg1/pckg2/file2.txt",
+        };
+
+        populateFolderStructure(root, paths);
+
+        FileObject rootFO = FileUtil.toFileObject(root);
+        FileObjectCrawler crawler = new FileObjectCrawler(rootFO, new 
FileObject[] {rootFO.getFileObject("org/pckg1/pckg2/file1.txt"), 
rootFO.getFileObject("org/pckg1/pckg2")}, 
EnumSet.<Crawler.TimeStampAction>of(Crawler.TimeStampAction.UPDATE), null, 
CR, SuspendSupport.NOP);
+        assertCollectedFiles("Wrong files collected", 
crawler.getResources(), new String[] {"org/pckg1/pckg2/file1.txt", 
"org/pckg1/pckg2/file2.txt"});
+    }
+
+    public void testDuplicateResults2() throws IOException {
+        File root = new File(getWorkDir(), "src");
+        String [] paths = new String [] {
+                "org/pckg1/file1.txt",
+                "org/pckg1/pckg2/file1.txt",
+                "org/pckg1/pckg2/file2.txt",
+        };
+
+        populateFolderStructure(root, paths);
+
+        FileObject rootFO = FileUtil.toFileObject(root);
+        FileObjectCrawler crawler = new FileObjectCrawler(rootFO, new 
FileObject[] {rootFO.getFileObject("org/pckg1/pckg2/file1.txt"), 
rootFO.getFileObject("org/pckg1/pckg2/file2.txt")}, 
EnumSet.<Crawler.TimeStampAction>of(Crawler.TimeStampAction.UPDATE), null, 
CR, SuspendSupport.NOP);
+        assertCollectedFiles("Wrong files collected", 
crawler.getResources(), new String[] {"org/pckg1/pckg2/file1.txt", 
"org/pckg1/pckg2/file2.txt"});
+    }
+
+    public void testDuplicateResults3() throws IOException {
+        File root = new File(getWorkDir(), "src");
+        String [] paths = new String [] {
+                "org/pckg1/file1.txt",
+                "org/pckg1/pckg2/file1.txt",
+                "org/pckg1/pckg2/file2.txt",
+        };
+
+        populateFolderStructure(root, paths);
+
+        FileObject rootFO = FileUtil.toFileObject(root);
+        FileObjectCrawler crawler = new FileObjectCrawler(rootFO, new 
FileObject[] {rootFO.getFileObject("org/pckg1/pckg2/file1.txt"), 
rootFO.getFileObject("org/pckg1/pckg2/file1.txt")}, 
EnumSet.<Crawler.TimeStampAction>of(Crawler.TimeStampAction.UPDATE), null, 
CR, SuspendSupport.NOP);
+        assertCollectedFiles("Wrong files collected", 
crawler.getResources(), new String[] {"org/pckg1/pckg2/file1.txt"});
+    }
+
     protected void assertCollectedFiles(String message, 
Collection<Indexable> resources, String... expectedPaths) throws IOException {
-        Set<String> collectedPaths = new HashSet<String>();
+        List<String> collectedPaths = new ArrayList<String>();
         for(Indexable ii : resources) {
             collectedPaths.add(ii.getRelativePath());
         }
-        Set<String> expectedPathsFiltered = new HashSet<String>();
+        List<String> expectedPathsFiltered = new ArrayList<String>();
         for(String path : expectedPaths) {
             if (!path.endsWith("/")) { // crawler only collects files
                 expectedPathsFiltered.add(path);
             }
         }
+        Collections.sort(collectedPaths);
+        Collections.sort(expectedPathsFiltered);
         assertEquals(message, expectedPathsFiltered, collectedPaths);
     }
 

[hg] main-silver: #224783:Rename Package Causes Phantom Error

Tomas Zezula 01/15/2013

<Possible follow-up(s)>

[hg] main-silver: #224783:Rename Package Causes Phantom Error

Tomas Zezula 01/16/2013

Project Features

About this Project

Editor was started in November 2009, is owned by Martin Ryzl, and has 147 members.
By use of this website, you agree to the NetBeans Policies and Terms of Use (revision 20131025.e7cbc9d). © 2013, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo
 
 
Close
loading
Please Confirm
Close