Clicking on an element declaration should allow to search for its usages/overriders/implementors/subtypes
authorJan Lahoda <jlahoda@netbeans.org>
Sun, 02 Dec 2012 22:31:11 +0100
changeset 911779002b0d3d0
parent 910 6f17a7221863
child 912 4907f3e21a9c
Clicking on an element declaration should allow to search for its usages/overriders/implementors/subtypes
remoting/server/web/resolve.web.api/src/org/netbeans/modules/jackpot30/resolve/api/ResolveService.java
remoting/server/web/web.ui/nbproject/project.properties
remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/UI.java
remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/showCode.html
remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/ui-findType.html
     1.1 --- a/remoting/server/web/resolve.web.api/src/org/netbeans/modules/jackpot30/resolve/api/ResolveService.java	Fri Nov 30 22:05:42 2012 +0100
     1.2 +++ b/remoting/server/web/resolve.web.api/src/org/netbeans/modules/jackpot30/resolve/api/ResolveService.java	Sun Dec 02 22:31:11 2012 +0100
     1.3 @@ -91,43 +91,6 @@
     1.4          return javac.parse(relative);
     1.5      }
     1.6  
     1.7 -    /**Long or String*/
     1.8 -    public static Object resolveGoToTarget(final CompilationInfo info, final long pos) throws IOException, InterruptedException {
     1.9 -        final Object[] result = new Object[1];
    1.10 -
    1.11 -        new TreePathScanner<Void, Void>() {
    1.12 -            @Override public Void visitIdentifier(IdentifierTree node, Void p) {
    1.13 -                handle();
    1.14 -                return super.visitIdentifier(node, p);
    1.15 -            }
    1.16 -            @Override public Void visitMemberSelect(MemberSelectTree node, Void p) {
    1.17 -                handle();
    1.18 -                return super.visitMemberSelect(node, p);
    1.19 -            }
    1.20 -            private void handle() {
    1.21 -                Element el = info.getTrees().getElement(getCurrentPath());
    1.22 -
    1.23 -                if (el == null) return;
    1.24 -
    1.25 -                long[] span = nameSpan(info, getCurrentPath());
    1.26 -
    1.27 -                if (span[0] <= pos && pos <= span[1]) {
    1.28 -                    TreePath tp = info.getTrees().getPath(el);
    1.29 -
    1.30 -                    if (tp != null && tp.getCompilationUnit() == info.getCompilationUnit()) {
    1.31 -                        result[0] = info.getTrees().getSourcePositions().getStartPosition(tp.getCompilationUnit(), tp.getLeaf());
    1.32 -                    } else {
    1.33 -                        assert JavaUtils.SUPPORTED_KINDS.contains(el.getKind());
    1.34 -
    1.35 -                        result[0] = JavaUtils.serialize(ElementHandle.create(el));
    1.36 -                    }
    1.37 -                }
    1.38 -            }
    1.39 -        }.scan(info.getCompilationUnit(), null);
    1.40 -
    1.41 -        return result[0];
    1.42 -    }
    1.43 -
    1.44      public static String resolveSource(String segment, String relative, String signature) throws IOException, InterruptedException {
    1.45          String fqn = topLevelClassFromSignature(signature);
    1.46          SourceRoot sourceRoot = sourceRoot(CategoryStorage.forId(segment), relative);
    1.47 @@ -218,6 +181,10 @@
    1.48          switch (forTree.getLeaf().getKind()) {
    1.49              case IDENTIFIER: name = ((IdentifierTree) forTree.getLeaf()).getName(); break;
    1.50              case MEMBER_SELECT: name = ((MemberSelectTree) forTree.getLeaf()).getIdentifier(); break;
    1.51 +            case ANNOTATION_TYPE: case CLASS:
    1.52 +            case ENUM: case INTERFACE: name = ((ClassTree) forTree.getLeaf()).getSimpleName(); break;
    1.53 +            case METHOD: name = ((MethodTree) forTree.getLeaf()).getName(); break;
    1.54 +            case VARIABLE: name = ((VariableTree) forTree.getLeaf()).getName(); break;
    1.55          }
    1.56  
    1.57          if (name != null) {
    1.58 @@ -242,33 +209,26 @@
    1.59  
    1.60          new TreePathScanner<Void, Void>() {
    1.61              @Override public Void visitClass(ClassTree node, Void p) {
    1.62 -                handleDeclaration(node.getSimpleName());
    1.63 +                handleDeclaration();
    1.64                  return super.visitClass(node, p);
    1.65              }
    1.66              @Override public Void visitMethod(MethodTree node, Void p) {
    1.67 -                handleDeclaration(node.getName());
    1.68 +                handleDeclaration();
    1.69                  return super.visitMethod(node, p);
    1.70              }
    1.71              @Override public Void visitVariable(VariableTree node, Void p) {
    1.72 -                handleDeclaration(node.getName());
    1.73 +                handleDeclaration();
    1.74                  return super.visitVariable(node, p);
    1.75              }
    1.76 -            private void handleDeclaration(CharSequence name) {
    1.77 +            private void handleDeclaration() {
    1.78                  Element el = info.getTrees().getElement(getCurrentPath());
    1.79  
    1.80                  if (el == null/*how?*/ || !JavaUtils.SUPPORTED_KINDS.contains(el.getKind())) return ;
    1.81                  
    1.82                  String thisSignature = JavaUtils.serialize(ElementHandle.create(el));
    1.83 -                Tree node = getCurrentPath().getLeaf();
    1.84  
    1.85                  if (thisSignature.equals(signature)) {
    1.86 -                    long[] spans = new long[] {
    1.87 -                        info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), node),
    1.88 -                        info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), node),
    1.89 -                        ((JCTree) node).pos,
    1.90 -                        ((JCTree) node).pos + name.length()
    1.91 -                    };
    1.92 -                    result[0] = spans;
    1.93 +                    result[0] = nameSpan(info, getCurrentPath());
    1.94                  }
    1.95              }
    1.96          }.scan(info.getCompilationUnit(), null);
     2.1 --- a/remoting/server/web/web.ui/nbproject/project.properties	Fri Nov 30 22:05:42 2012 +0100
     2.2 +++ b/remoting/server/web/web.ui/nbproject/project.properties	Sun Dec 02 22:31:11 2012 +0100
     2.3 @@ -28,6 +28,7 @@
     2.4  endorsed.classpath=
     2.5  excludes=
     2.6  file.reference.org-netbeans-modules-java-lexer.jar=../../../../lib/org-netbeans-modules-java-lexer.jar
     2.7 +file.reference.org-netbeans-modules-java-source.jar=../../../../lib/org-netbeans-modules-java-source.jar
     2.8  file.reference.org-netbeans-modules-jumpto.jar=../../../../lib/org-netbeans-modules-jumpto.jar
     2.9  file.reference.org-netbeans-modules-lexer.jar=../../../../lib/org-netbeans-modules-lexer.jar
    2.10  file.reference.org-netbeans-modules-parsing-lucene.jar=../../../../lib/org-netbeans-modules-parsing-lucene.jar
    2.11 @@ -53,7 +54,8 @@
    2.12      ${file.reference.org-netbeans-modules-lexer.jar}:\
    2.13      ${file.reference.org-openide-util.jar}:\
    2.14      ${reference.resolve_web_api.jar}:\
    2.15 -    ${libs.javac.classpath}
    2.16 +    ${libs.javac.classpath}:\
    2.17 +    ${file.reference.org-netbeans-modules-java-source.jar}
    2.18  # Space-separated list of extra javac options
    2.19  javac.compilerargs=-Xbootclasspath/p:${libs.javac.classpath}
    2.20  javac.deprecation=false
     3.1 --- a/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/UI.java	Fri Nov 30 22:05:42 2012 +0100
     3.2 +++ b/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/UI.java	Sun Dec 02 22:31:11 2012 +0100
     3.3 @@ -42,6 +42,13 @@
     3.4  
     3.5  package org.netbeans.modules.jackpot30.backend.ui;
     3.6  
     3.7 +import com.sun.source.tree.ClassTree;
     3.8 +import com.sun.source.tree.IdentifierTree;
     3.9 +import com.sun.source.tree.MemberSelectTree;
    3.10 +import com.sun.source.tree.MethodTree;
    3.11 +import com.sun.source.tree.VariableTree;
    3.12 +import com.sun.source.util.TreePath;
    3.13 +import com.sun.source.util.TreePathScanner;
    3.14  import freemarker.template.TemplateException;
    3.15  import java.io.IOException;
    3.16  import java.net.URI;
    3.17 @@ -58,6 +65,8 @@
    3.18  import java.util.Map;
    3.19  import java.util.Map.Entry;
    3.20  import java.util.concurrent.atomic.AtomicBoolean;
    3.21 +import javax.lang.model.element.Element;
    3.22 +import javax.lang.model.element.ElementKind;
    3.23  import javax.ws.rs.GET;
    3.24  import javax.ws.rs.Path;
    3.25  import javax.ws.rs.Produces;
    3.26 @@ -66,6 +75,7 @@
    3.27  import javax.ws.rs.core.UriInfo;
    3.28  import org.codeviation.pojson.Pojson;
    3.29  import org.netbeans.api.java.lexer.JavaTokenId;
    3.30 +import org.netbeans.api.java.source.ElementHandle;
    3.31  import org.netbeans.api.lexer.Token;
    3.32  import org.netbeans.api.lexer.TokenHierarchy;
    3.33  import org.netbeans.api.lexer.TokenSequence;
    3.34 @@ -78,6 +88,7 @@
    3.35  import org.netbeans.modules.jackpot30.backend.ui.highlighting.SemanticHighlighter;
    3.36  import org.netbeans.modules.jackpot30.backend.ui.highlighting.TokenList;
    3.37  import org.netbeans.modules.jackpot30.resolve.api.CompilationInfo;
    3.38 +import org.netbeans.modules.jackpot30.resolve.api.JavaUtils;
    3.39  import org.netbeans.modules.jackpot30.resolve.api.ResolveService;
    3.40  
    3.41  /**
    3.42 @@ -304,7 +315,7 @@
    3.43          final String urlBase = URL_BASE_OVERRIDE != null ? URL_BASE_OVERRIDE : uriInfo.getBaseUri().toString();
    3.44          Map<String, Object> configurationData = usagesSubclassesImpl(urlBase, segment, signatures, "files", new ComputeSegmentData() {
    3.45              @Override public Object compute(String currentSegment) throws URISyntaxException, TemplateException, IOException {
    3.46 -                URI u = new URI(urlBase + "index/usages/search?path=" + escapeForQuery(currentSegment) + "&signatures=" + escapeForQuery(simplify(signatures)));
    3.47 +                URI u = new URI(urlBase + "index/usages/search?path=" + escapeForQuery(currentSegment) + "&signatures=" + escapeForQuery(signatures));
    3.48                  List<String> files = new ArrayList<String>(WebUtilities.requestStringArrayResponse(u));
    3.49                  Collections.sort(files);
    3.50                  return files;
    3.51 @@ -350,11 +361,10 @@
    3.52  
    3.53              configurationData.put("isSubtypes", true);
    3.54          } else {
    3.55 -            final String method = methodSignature.substring(0, methodSignature.length() - 1);
    3.56              configurationData = usagesSubclassesImpl(urlBase, segment, methodSignature, "implementors", new ComputeSegmentData() {
    3.57                  @Override
    3.58                  public Object compute(String currentSegment) throws URISyntaxException, TemplateException, IOException {
    3.59 -                    URI u = new URI(urlBase + "index/implements/search?path=" + escapeForQuery(currentSegment) + "&method=" + escapeForQuery(method));
    3.60 +                    URI u = new URI(urlBase + "index/implements/search?path=" + escapeForQuery(currentSegment) + "&method=" + escapeForQuery(methodSignature));
    3.61                      Map<String, List<Map<String, String>>> data = Pojson.load(HashMap.class, u);
    3.62                      List<Map<String, String>> implementors = new ArrayList<Map<String, String>>();
    3.63                      for (Entry<String, List<Map<String, String>>> relpath2ImplementorsE : data.entrySet()) {
    3.64 @@ -621,27 +631,6 @@
    3.65          return input;
    3.66      }
    3.67  
    3.68 -    static String simplify(String originalSignature) {
    3.69 -        if (   !originalSignature.startsWith("METHOD:")
    3.70 -            && !originalSignature.startsWith("CONSTRUCTOR:")) return originalSignature;
    3.71 -        StringBuilder target = new StringBuilder(originalSignature.length());
    3.72 -        int b = 0;
    3.73 -
    3.74 -        for (char c : originalSignature.toCharArray()) {
    3.75 -            if (c == '<') {
    3.76 -                b++;
    3.77 -            } else if (c == '>') {
    3.78 -                b--;
    3.79 -            } else if (b == '^') {
    3.80 -                return target.toString();
    3.81 -            } else if (b == 0) {
    3.82 -                target.append(c);
    3.83 -            }
    3.84 -        }
    3.85 -
    3.86 -        return target.delete(target.length() - 1, target.length()).toString();
    3.87 -    }
    3.88 -
    3.89      static String strip(String originalSignature, String... prefixesToStrip) {
    3.90          for (String strip : prefixesToStrip) {
    3.91              if (originalSignature.startsWith(strip)) {
    3.92 @@ -655,71 +644,166 @@
    3.93      @GET
    3.94      @Path("/target")
    3.95  //    @Produces("text/html")
    3.96 -    public String target(@QueryParam("path") String segment, @QueryParam("relative") String relative, @QueryParam("position") Long position, @QueryParam("signature") String signature) throws URISyntaxException, IOException, TemplateException, InterruptedException {
    3.97 -        CompilationInfo info = ResolveService.parse(segment, relative);
    3.98 -        Object target = null;
    3.99 +    public String target(@QueryParam("path") String segment, @QueryParam("relative") String relative, @QueryParam("position") final long position) throws URISyntaxException, IOException, TemplateException, InterruptedException {
   3.100 +        final CompilationInfo info = ResolveService.parse(segment, relative);
   3.101 +        final boolean[] declaration = new boolean[1];
   3.102 +        final long[] targetPosition = new long[] { -2 };
   3.103 +        final String[] signature = new String[1];
   3.104 +        final ElementKind[] kind = new ElementKind[1];
   3.105  
   3.106 -        if (signature != null) {
   3.107 -            long[] span = ResolveService.declarationSpans(info, signature);
   3.108 +        new TreePathScanner<Void, Void>() {
   3.109 +            @Override public Void visitIdentifier(IdentifierTree node, Void p) {
   3.110 +                handleUsage();
   3.111 +                return super.visitIdentifier(node, p);
   3.112 +            }
   3.113 +            @Override public Void visitMemberSelect(MemberSelectTree node, Void p) {
   3.114 +                handleUsage();
   3.115 +                return super.visitMemberSelect(node, p);
   3.116 +            }
   3.117 +            private void handleUsage() {
   3.118 +                Element el = info.getTrees().getElement(getCurrentPath());
   3.119  
   3.120 -            if (span != null) {
   3.121 -                target = span[2];
   3.122 +                if (el == null) return;
   3.123 +
   3.124 +                long[] span = ResolveService.nameSpan(info, getCurrentPath());
   3.125 +
   3.126 +                if (span[0] <= position && position <= span[1]) {
   3.127 +                    if (JavaUtils.SUPPORTED_KINDS.contains(el.getKind())) {
   3.128 +                        signature[0] = JavaUtils.serialize(ElementHandle.create(el));
   3.129 +                    }
   3.130 +
   3.131 +                    TreePath tp = info.getTrees().getPath(el);
   3.132 +
   3.133 +                    if (tp != null && tp.getCompilationUnit() == info.getCompilationUnit()) {
   3.134 +                        targetPosition[0] = info.getTrees().getSourcePositions().getStartPosition(tp.getCompilationUnit(), tp.getLeaf());
   3.135 +                    }
   3.136 +                }
   3.137              }
   3.138 -        } else {
   3.139 -            target = ResolveService.resolveGoToTarget(info, position);
   3.140 -        }
   3.141 +            @Override public Void visitClass(ClassTree node, Void p) {
   3.142 +                handleDeclaration();
   3.143 +                return super.visitClass(node, p);
   3.144 +            }
   3.145 +            @Override public Void visitMethod(MethodTree node, Void p) {
   3.146 +                handleDeclaration();
   3.147 +                return super.visitMethod(node, p);
   3.148 +            }
   3.149 +            @Override public Void visitVariable(VariableTree node, Void p) {
   3.150 +                handleDeclaration();
   3.151 +                return super.visitVariable(node, p);
   3.152 +            }
   3.153 +            private void handleDeclaration() {
   3.154 +                Element el = info.getTrees().getElement(getCurrentPath());
   3.155 +
   3.156 +                if (el == null) return;
   3.157 +
   3.158 +                long[] span = ResolveService.nameSpan(info, getCurrentPath());
   3.159 +
   3.160 +                if (span[0] <= position && position <= span[1]) {
   3.161 +                    if (JavaUtils.SUPPORTED_KINDS.contains(el.getKind())) {
   3.162 +                        signature[0] = JavaUtils.serialize(ElementHandle.create(el));
   3.163 +                    }
   3.164 +
   3.165 +                    declaration[0] = true;
   3.166 +                    kind[0] = el.getKind();
   3.167 +                }
   3.168 +            }
   3.169 +        }.scan(info.getCompilationUnit(), null);
   3.170  
   3.171          Map<String, Object> result = new HashMap<String, Object>();
   3.172  
   3.173 -        if (target instanceof Long) {
   3.174 -            result.put("position", target);
   3.175 -        } else if (target instanceof String) {
   3.176 -            String targetSignature = (String) target;
   3.177 -            String source = ResolveService.resolveSource(segment, relative, targetSignature);
   3.178 +        if (declaration[0]) {
   3.179 +            if (signature[0] != null) {
   3.180 +                List<Map<String, String>> menu = new ArrayList<Map<String, String>>();
   3.181  
   3.182 -            result.put("signature", targetSignature);
   3.183 -            
   3.184 -            if (source != null) {
   3.185 -                result.put("path", segment);
   3.186 -                result.put("source", source);
   3.187 -            } else {
   3.188 -                String singleSource = null;
   3.189 -                String singleSourceSegment = null;
   3.190 -                boolean multipleSources = false;
   3.191 -                List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
   3.192 +                menu.add(menuMap("Usages in current project", "/index/ui/usages?path=" + escapeForQuery(segment) + "&signatures=" + escapeForQuery(signature[0])));
   3.193 +                menu.add(menuMap("Usages in all known projects", "/index/ui/usages?signatures=" + escapeForQuery(signature[0])));
   3.194  
   3.195 -                for (Entry<? extends CategoryStorage, ? extends Iterable<? extends String>> e : ResolveService.findSourcesContaining(targetSignature).entrySet()) {
   3.196 -                    Map<String, Object> categoryData = new HashMap<String, Object>();
   3.197 +                switch (kind[0]) {
   3.198 +                    case METHOD:
   3.199 +                        menu.add(menuMap("Overriders in the current project", "/index/ui/implements?path=" + escapeForQuery(segment) + "&method=" + escapeForQuery(signature[0])));
   3.200 +                        menu.add(menuMap("Overriders in all known projects", "/index/ui/implements?method=" + escapeForQuery(signature[0])));
   3.201 +                        break;
   3.202 +                    case CLASS: case INTERFACE: case ENUM: case ANNOTATION_TYPE:
   3.203 +                        menu.add(menuMap("Subtypes in the current project", "/index/ui/implements?path=" + escapeForQuery(segment) + "&type=" + escapeForQuery(signature[0])));
   3.204 +                        menu.add(menuMap("Subtypes in all known projects", "/index/ui/implements?type=" + escapeForQuery(signature[0])));
   3.205 +                        break;
   3.206 +                }
   3.207 +                result.put("menu", menu);
   3.208 +            }
   3.209 +        } else {
   3.210 +            if (targetPosition[0] != (-2)) {
   3.211 +                result.put("position", targetPosition[0]);
   3.212 +            } else if (signature[0] != null) {
   3.213 +                String targetSignature = signature[0];
   3.214 +                String source = ResolveService.resolveSource(segment, relative, targetSignature);
   3.215  
   3.216 -                    categoryData.put("rootDisplayName", e.getKey().getDisplayName());
   3.217 -                    categoryData.put("rootPath", e.getKey().getId());
   3.218 -                    categoryData.put("files", e.getValue());
   3.219 +                result.put("signature", targetSignature);
   3.220  
   3.221 -                    if (!multipleSources) {
   3.222 -                        Iterator<? extends String> fIt = e.getValue().iterator();
   3.223 +                if (source != null) {
   3.224 +                    result.put("path", segment);
   3.225 +                    result.put("source", source);
   3.226 +                } else {
   3.227 +                    String singleSource = null;
   3.228 +                    String singleSourceSegment = null;
   3.229 +                    boolean multipleSources = false;
   3.230 +                    List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
   3.231  
   3.232 -                        if (fIt.hasNext()) {
   3.233 -                            singleSource = fIt.next();
   3.234 -                            singleSourceSegment = e.getKey().getId();
   3.235 +                    for (Entry<? extends CategoryStorage, ? extends Iterable<? extends String>> e : ResolveService.findSourcesContaining(targetSignature).entrySet()) {
   3.236 +                        Map<String, Object> categoryData = new HashMap<String, Object>();
   3.237 +
   3.238 +                        categoryData.put("rootDisplayName", e.getKey().getDisplayName());
   3.239 +                        categoryData.put("rootPath", e.getKey().getId());
   3.240 +                        categoryData.put("files", e.getValue());
   3.241 +
   3.242 +                        if (!multipleSources) {
   3.243 +                            Iterator<? extends String> fIt = e.getValue().iterator();
   3.244 +
   3.245 +                            if (fIt.hasNext()) {
   3.246 +                                singleSource = fIt.next();
   3.247 +                                singleSourceSegment = e.getKey().getId();
   3.248 +                            }
   3.249 +
   3.250 +                            if (fIt.hasNext())
   3.251 +                                multipleSources = true;
   3.252                          }
   3.253 -                        
   3.254 -                        if (fIt.hasNext())
   3.255 -                            multipleSources = true;
   3.256 +
   3.257 +                        results.add(categoryData);
   3.258                      }
   3.259  
   3.260 -                    results.add(categoryData);
   3.261 -                }
   3.262 -
   3.263 -                if (singleSource != null && !multipleSources) {
   3.264 -                    //TODO: will automatically jump to the single known target - correct
   3.265 -                    result.put("path", singleSourceSegment);
   3.266 -                    result.put("source", singleSource);
   3.267 -                } else if (!results.isEmpty()) {
   3.268 -                    result.put("targets", results);
   3.269 +                    if (singleSource != null && !multipleSources) {
   3.270 +                        //TODO: will automatically jump to the single known target - correct?
   3.271 +                        result.put("path", singleSourceSegment);
   3.272 +                        result.put("source", singleSource);
   3.273 +                    } else if (!results.isEmpty()) {
   3.274 +                        result.put("targets", results);
   3.275 +                    }
   3.276                  }
   3.277              }
   3.278          }
   3.279  
   3.280          return Pojson.save(result);
   3.281      }
   3.282 +
   3.283 +    private static Map<String, String> menuMap(String displayName, String url) {
   3.284 +        Map<String, String> result = new HashMap<String, String>();
   3.285 +
   3.286 +        result.put("displayName", displayName);
   3.287 +        result.put("url", url);
   3.288 +
   3.289 +        return result;
   3.290 +    }
   3.291 +
   3.292 +    @GET
   3.293 +    @Path("/declarationSpan")
   3.294 +//    @Produces("text/html")
   3.295 +    public String declarationSpan(@QueryParam("path") String segment, @QueryParam("relative") String relative, @QueryParam("signature") String signature) throws URISyntaxException, IOException, TemplateException, InterruptedException {
   3.296 +        CompilationInfo info = ResolveService.parse(segment, relative);
   3.297 +        long[] span = ResolveService.declarationSpans(info, signature);
   3.298 +
   3.299 +        if (span == null) {
   3.300 +            span = new long[] {-1, -1, -1, -1};
   3.301 +        }
   3.302 +
   3.303 +        return Pojson.save(span);
   3.304 +    }
   3.305  }
     4.1 --- a/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/showCode.html	Fri Nov 30 22:05:42 2012 +0100
     4.2 +++ b/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/showCode.html	Sun Dec 02 22:31:11 2012 +0100
     4.3 @@ -23,10 +23,10 @@
     4.4  
     4.5                  for (var i = 0; i < $params.length; i++) {
     4.6                      if ($params[i].indexOf("signature=") !== (-1)) {
     4.7 -                        $.get('/index/ui/target?path=${path}&relative=${relative}&signature=' + unescape($params[i].substring("signature=".length)), function(data) {
     4.8 +                        $.get('/index/ui/declarationSpan?path=${path}&relative=${relative}&signature=' + unescape($params[i].substring("signature=".length)), function(data) {
     4.9                              var parsedData = $.parseJSON(data);
    4.10 -                            if ("position" in parsedData) {
    4.11 -                                window.location.hash = "#p" + parsedData.position;
    4.12 +                            if (parsedData[2] !== (-1)) {
    4.13 +                                window.location.hash = "#p" + parsedData[2];
    4.14                              }
    4.15  
    4.16                          });
    4.17 @@ -66,6 +66,18 @@
    4.18                                          title: 'Show',
    4.19                                          width: 800 //XXX: hardcoded size
    4.20                                      });
    4.21 +                } else if ("menu" in parsedData) {
    4.22 +                    var menuDef = parsedData.menu;
    4.23 +                    var popupContent = "";
    4.24 +                    for (var i = 0; i < menuDef.length; i++) {
    4.25 +                        var menuItem = menuDef[i];
    4.26 +                        popupContent += '<a href="' + menuItem.url + '">' + menuItem.displayName + '</a><br>';
    4.27 +                        $('#popup').html(popupContent)
    4.28 +                                        .dialog({
    4.29 +                                            title: 'Show',
    4.30 +                                            width: 800 //XXX: hardcoded size
    4.31 +                                        });
    4.32 +                    }
    4.33                  } else if ("signature" in parsedData) {
    4.34                      alert("Cannot find source file for class: " + parsedData.signature.split(":")[1]);
    4.35                  } else {
     5.1 --- a/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/ui-findType.html	Fri Nov 30 22:05:42 2012 +0100
     5.2 +++ b/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/ui-findType.html	Sun Dec 02 22:31:11 2012 +0100
     5.3 @@ -5,7 +5,7 @@
     5.4      <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/base/jquery-ui.css" rel="stylesheet" type="text/css">
     5.5      <script type="text/javascript">
     5.6          function methodPopup(relativePath, resultFile, signature) {
     5.7 -            $('#popup').html('<a href="/index/ui/show?path=' + relativePath + '&relative=' + resultFile + '">Source Code</a><br>' +
     5.8 +            $('#popup').html('<a href="/index/ui/show?path=' + relativePath + '&relative=' + resultFile + '&signatures=' + signature + '">Source Code</a><br>' +
     5.9                               '<a href="/index/ui/usages?path=' + relativePath + '&signatures=' + signature + '">Usages in the defining project</a><br>' +
    5.10                               '<a href="/index/ui/usages?signatures=' + signature + '">Usages in all known projects</a><br>' +
    5.11                               '<a href="/index/ui/implements?path=' + relativePath + '&method=' + signature + '">Overriders in the defining project</a><br>' +
    5.12 @@ -16,7 +16,7 @@
    5.13                              });
    5.14          }
    5.15          function classPopup(relativePath, resultFile, signature) {
    5.16 -            $('#popup').html('<a href="/index/ui/show?path=' + relativePath + '&relative=' + resultFile + '">Source Code</a><br>' +
    5.17 +            $('#popup').html('<a href="/index/ui/show?path=' + relativePath + '&relative=' + resultFile + '&signatures=' + signature + '">Source Code</a><br>' +
    5.18                               '<a href="/index/ui/usages?path=' + relativePath + '&signatures=' + signature + '">Usages in the defining project</a><br>' +
    5.19                               '<a href="/index/ui/usages?signatures=' + signature + '">Usages in all known projects</a><br>' +
    5.20                               '<a href="/index/ui/implements?path=' + relativePath + '&type=' + signature + '">Subtypes in the defining project</a><br>' +
    5.21 @@ -27,7 +27,7 @@
    5.22                              });
    5.23          }
    5.24          function otherPopup(relativePath, resultFile, signature) {
    5.25 -            $('#popup').html('<a href="/index/ui/show?path=' + relativePath + '&relative=' + resultFile + '">Source Code</a><br>' +
    5.26 +            $('#popup').html('<a href="/index/ui/show?path=' + relativePath + '&relative=' + resultFile + '&signatures=' + signature + '">Source Code</a><br>' +
    5.27                               '<a href="/index/ui/usages?path=' + relativePath + '&signatures=' + signature + '">Usages in the defining project</a><br>' +
    5.28                               '<a href="/index/ui/usages?signatures=' + signature + '">Usages in all known projects</a><br>')
    5.29                              .dialog({
    5.30 @@ -75,7 +75,7 @@
    5.31                  <nobr>
    5.32                  <img src="/index/icons/${result.icon}" alt="${result.kind}"/>
    5.33                  <#if result.kind == "METHOD">
    5.34 -                    <a href="javascript: methodPopup('${result.segment.segment}', '${result.file}', '${result.kind}:${result.enclosingFQN}:${result.simpleName}:${result.vmsignature};')">
    5.35 +                    <a href="javascript: methodPopup('${result.segment.segment}', '${result.file}', '${result.kind}:${result.enclosingFQN}:${result.simpleName}:${result.vmsignature}')">
    5.36                  <#elseif result.kind == "CLASS" || result.kind == "INTERFACE" || result.kind == "ENUM" || result.kind == "ANNOTATION_TYPE">
    5.37                      <a href="javascript: classPopup('${result.segment.segment}', '${result.file}', '${result.kind}:${result.fqn}')">
    5.38                  <#else>