Using double click for mark occurrences
authorjlahoda
Sun, 22 Jun 2014 22:07:56 +0200
changeset 987be50932fafbc
parent 986 cb079a0abad2
child 988 1ace99bbb77d
Using double click for mark occurrences
remoting/server/web/web.ui.frontend/public_html/index/ui/script.js
remoting/server/web/web.ui.frontend/public_html/index/ui/showCode.html
remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/UI.java
     1.1 --- a/remoting/server/web/web.ui.frontend/public_html/index/ui/script.js	Thu Dec 19 15:43:00 2013 +0100
     1.2 +++ b/remoting/server/web/web.ui.frontend/public_html/index/ui/script.js	Sun Jun 22 22:07:56 2014 +0200
     1.3 @@ -325,6 +325,31 @@
     1.4              }
     1.5          });
     1.6      };
     1.7 +    $scope.markOccurrencesAction = function ($event) {
     1.8 +        $scope.$parent.loading = true;
     1.9 +        var pos = $($event.target).attr("jpt30pos");
    1.10 +        $http.get('/index/ui/localUsages?path=' + path + '&relative=' + relative + '&position=' + pos).success(function(parsedData) {
    1.11 +            $scope.$parent.loading = false;
    1.12 +            addHighlights(parsedData);
    1.13 +
    1.14 +            if (parsedData.length > 0) {
    1.15 +                $scope.$parent.currentHighlight = -1;
    1.16 +
    1.17 +                for (var i = 0; i < parsedData.length; i++) {
    1.18 +                    if (parsedData[i][0] <= pos && pos <= parsedData[i][1]) {
    1.19 +                        break;
    1.20 +                    }
    1.21 +                    $scope.$parent.currentHighlight++;
    1.22 +                }
    1.23 +
    1.24 +                $scope.$parent.highlights = parsedData;
    1.25 +                $scope.$parent.nextOccurrence();
    1.26 +            } else {
    1.27 +                $scope.$parent.currentHighlight = 0;
    1.28 +                $scope.$parent.highlights = [];
    1.29 +            }
    1.30 +        });
    1.31 +    };
    1.32  
    1.33      $http.get("/index/source/cat?path=" + escape(path) + "&relative=" + escape(relative)).success(function(data) {
    1.34          var sourceCode = data.replace(/\r\n/g, '\n');
     2.1 --- a/remoting/server/web/web.ui.frontend/public_html/index/ui/showCode.html	Thu Dec 19 15:43:00 2013 +0100
     2.2 +++ b/remoting/server/web/web.ui.frontend/public_html/index/ui/showCode.html	Sun Jun 22 22:07:56 2014 +0200
     2.3 @@ -1,4 +1,4 @@
     2.4 -<pre id="code" ng-bind-html-unsafe="sourceCode" ng-click="gotoAction($event)">
     2.5 +<pre id="code" ng-bind-html-unsafe="sourceCode" ng-click="gotoAction($event)" ng-dblclick="markOccurrencesAction($event)">
     2.6  </pre>
     2.7  <div class="navbar navbar-fixed-bottom">
     2.8      <div class="navbar-inner">
     3.1 --- a/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/UI.java	Thu Dec 19 15:43:00 2013 +0100
     3.2 +++ b/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/UI.java	Sun Jun 22 22:07:56 2014 +0200
     3.3 @@ -358,12 +358,22 @@
     3.4      @GET
     3.5      @Path("/localUsages")
     3.6      @Produces("application/javascript")
     3.7 -    public String localUsages(@Context UriInfo uriInfo, @QueryParam("path") String segment, @QueryParam("relative") String relative, @QueryParam("signature") final String signature, @QueryParam("usages") boolean usages) throws URISyntaxException, IOException, InterruptedException {
     3.8 +    public String localUsages(@Context UriInfo uriInfo, @QueryParam("path") String segment, @QueryParam("relative") String relative, @QueryParam("signature")  String signature, @QueryParam("position") final long position, @QueryParam("usages") boolean usages) throws URISyntaxException, IOException, InterruptedException {
     3.9          List<long[]> result = new ArrayList<long[]>();
    3.10  
    3.11          if (relative.endsWith(".java")) {
    3.12              final CompilationInfo info = ResolveService.parse(segment, relative);
    3.13  
    3.14 +            if (signature == null) {
    3.15 +                ResolvedLocation location = resolveTarget(info, position, false);
    3.16 +
    3.17 +                signature = location.signature;
    3.18 +            }
    3.19 +
    3.20 +            if (signature == null) {
    3.21 +                return "[]";
    3.22 +            }
    3.23 +
    3.24              for (long[] span : ResolveService.usages(info, signature)) {
    3.25                  result.add(new long[] {span[2], span[3]});
    3.26              }
    3.27 @@ -614,96 +624,34 @@
    3.28  //    @Produces("text/html")
    3.29      public String target(@QueryParam("path") String segment, @QueryParam("relative") String relative, @QueryParam("position") final long position) throws URISyntaxException, IOException, InterruptedException {
    3.30          final CompilationInfo info = ResolveService.parse(segment, relative);
    3.31 -        final boolean[] declaration = new boolean[1];
    3.32 -        final long[] targetPosition = new long[] { -2 };
    3.33 -        final String[] signature = new String[1];
    3.34 -        final ElementKind[] kind = new ElementKind[1];
    3.35 -
    3.36 -        new TreePathScanner<Void, Void>() {
    3.37 -            @Override public Void visitIdentifier(IdentifierTree node, Void p) {
    3.38 -                handleUsage();
    3.39 -                return super.visitIdentifier(node, p);
    3.40 -            }
    3.41 -            @Override public Void visitMemberSelect(MemberSelectTree node, Void p) {
    3.42 -                handleUsage();
    3.43 -                return super.visitMemberSelect(node, p);
    3.44 -            }
    3.45 -            private void handleUsage() {
    3.46 -                Element el = info.getTrees().getElement(getCurrentPath());
    3.47 -
    3.48 -                if (el == null) return;
    3.49 -
    3.50 -                long[] span = ResolveService.nameSpan(info, getCurrentPath());
    3.51 -
    3.52 -                if (span[0] <= position && position <= span[1]) {
    3.53 -                    if (JavaUtils.SUPPORTED_KINDS.contains(el.getKind())) {
    3.54 -                        signature[0] = JavaUtils.serialize(ElementHandle.create(el));
    3.55 -                    }
    3.56 -
    3.57 -                    TreePath tp = info.getTrees().getPath(el);
    3.58 -
    3.59 -                    if (tp != null && tp.getCompilationUnit() == info.getCompilationUnit()) {
    3.60 -                        targetPosition[0] = info.getTrees().getSourcePositions().getStartPosition(tp.getCompilationUnit(), tp.getLeaf());
    3.61 -                    }
    3.62 -                }
    3.63 -            }
    3.64 -            @Override public Void visitClass(ClassTree node, Void p) {
    3.65 -                handleDeclaration();
    3.66 -                return super.visitClass(node, p);
    3.67 -            }
    3.68 -            @Override public Void visitMethod(MethodTree node, Void p) {
    3.69 -                handleDeclaration();
    3.70 -                return super.visitMethod(node, p);
    3.71 -            }
    3.72 -            @Override public Void visitVariable(VariableTree node, Void p) {
    3.73 -                handleDeclaration();
    3.74 -                return super.visitVariable(node, p);
    3.75 -            }
    3.76 -            private void handleDeclaration() {
    3.77 -                Element el = info.getTrees().getElement(getCurrentPath());
    3.78 -
    3.79 -                if (el == null) return;
    3.80 -
    3.81 -                long[] span = ResolveService.nameSpan(info, getCurrentPath());
    3.82 -
    3.83 -                if (span[2] <= position && position <= span[3]) {
    3.84 -                    if (JavaUtils.SUPPORTED_KINDS.contains(el.getKind())) {
    3.85 -                        signature[0] = JavaUtils.serialize(ElementHandle.create(el));
    3.86 -                    }
    3.87 -
    3.88 -                    declaration[0] = true;
    3.89 -                    kind[0] = el.getKind();
    3.90 -                }
    3.91 -            }
    3.92 -        }.scan(info.getCompilationUnit(), null);
    3.93 -
    3.94 +        ResolvedLocation location = resolveTarget(info, position, true);
    3.95          Map<String, Object> result = new HashMap<String, Object>();
    3.96  
    3.97 -        if (declaration[0]) {
    3.98 -            if (signature[0] != null) {
    3.99 +        if (location.declaration) {
   3.100 +            if (location.signature != null) {
   3.101                  List<Map<String, String>> menu = new ArrayList<Map<String, String>>();
   3.102  
   3.103 -                menu.add(menuMap("Usages in current project", "/index/ui/usages?path=" + escapeForQuery(segment) + "&signatures=" + escapeForQuery(signature[0])));
   3.104 -                menu.add(menuMap("Usages in all known projects", "/index/ui/usages?signatures=" + escapeForQuery(signature[0])));
   3.105 +                menu.add(menuMap("Usages in current project", "/index/ui/usages?path=" + escapeForQuery(segment) + "&signatures=" + escapeForQuery(location.signature)));
   3.106 +                menu.add(menuMap("Usages in all known projects", "/index/ui/usages?signatures=" + escapeForQuery(location.signature)));
   3.107  
   3.108 -                switch (kind[0]) {
   3.109 +                switch (location.kind) {
   3.110                      case METHOD:
   3.111 -                        menu.add(menuMap("Overriders in the current project", "/index/ui/implements?path=" + escapeForQuery(segment) + "&method=" + escapeForQuery(signature[0])));
   3.112 -                        menu.add(menuMap("Overriders in all known projects", "/index/ui/implements?method=" + escapeForQuery(signature[0])));
   3.113 +                        menu.add(menuMap("Overriders in the current project", "/index/ui/implements?path=" + escapeForQuery(segment) + "&method=" + escapeForQuery(location.signature)));
   3.114 +                        menu.add(menuMap("Overriders in all known projects", "/index/ui/implements?method=" + escapeForQuery(location.signature)));
   3.115                          break;
   3.116                      case CLASS: case INTERFACE: case ENUM: case ANNOTATION_TYPE:
   3.117 -                        menu.add(menuMap("Subtypes in the current project", "/index/ui/implements?path=" + escapeForQuery(segment) + "&type=" + escapeForQuery(signature[0])));
   3.118 -                        menu.add(menuMap("Subtypes in all known projects", "/index/ui/implements?type=" + escapeForQuery(signature[0])));
   3.119 +                        menu.add(menuMap("Subtypes in the current project", "/index/ui/implements?path=" + escapeForQuery(segment) + "&type=" + escapeForQuery(location.signature)));
   3.120 +                        menu.add(menuMap("Subtypes in all known projects", "/index/ui/implements?type=" + escapeForQuery(location.signature)));
   3.121                          break;
   3.122                  }
   3.123                  result.put("menu", menu);
   3.124 -                result.put("signature", signature[0]);
   3.125 +                result.put("signature", location.signature);
   3.126              }
   3.127          } else {
   3.128 -            if (targetPosition[0] != (-2)) {
   3.129 -                result.put("position", targetPosition[0]);
   3.130 -            } else if (signature[0] != null) {
   3.131 -                String targetSignature = signature[0];
   3.132 +            if (location.position != (-2)) {
   3.133 +                result.put("position", location.position);
   3.134 +            } else if (location.signature != null) {
   3.135 +                String targetSignature = location.signature;
   3.136                  String source = ResolveService.resolveSource(segment, relative, targetSignature);
   3.137  
   3.138                  result.put("signature", targetSignature);
   3.139 @@ -762,6 +710,75 @@
   3.140          return result;
   3.141      }
   3.142  
   3.143 +    private static ResolvedLocation resolveTarget(final CompilationInfo info, final long position, final boolean resolveTargetPosition) {
   3.144 +        final boolean[] declaration = new boolean[1];
   3.145 +        final long[] targetPosition = new long[] { -2 };
   3.146 +        final String[] signature = new String[1];
   3.147 +        final ElementKind[] kind = new ElementKind[1];
   3.148 +
   3.149 +        new TreePathScanner<Void, Void>() {
   3.150 +            @Override public Void visitIdentifier(IdentifierTree node, Void p) {
   3.151 +                handleUsage();
   3.152 +                return super.visitIdentifier(node, p);
   3.153 +            }
   3.154 +            @Override public Void visitMemberSelect(MemberSelectTree node, Void p) {
   3.155 +                handleUsage();
   3.156 +                return super.visitMemberSelect(node, p);
   3.157 +            }
   3.158 +            private void handleUsage() {
   3.159 +                Element el = info.getTrees().getElement(getCurrentPath());
   3.160 +
   3.161 +                if (el == null) return;
   3.162 +
   3.163 +                long[] span = ResolveService.nameSpan(info, getCurrentPath());
   3.164 +
   3.165 +                if (span[0] <= position && position <= span[1]) {
   3.166 +                    if (JavaUtils.SUPPORTED_KINDS.contains(el.getKind())) {
   3.167 +                        signature[0] = JavaUtils.serialize(ElementHandle.create(el));
   3.168 +                    }
   3.169 +
   3.170 +                    if (resolveTargetPosition) {
   3.171 +                        TreePath tp = info.getTrees().getPath(el);
   3.172 +
   3.173 +                        if (tp != null && tp.getCompilationUnit() == info.getCompilationUnit()) {
   3.174 +                            targetPosition[0] = info.getTrees().getSourcePositions().getStartPosition(tp.getCompilationUnit(), tp.getLeaf());
   3.175 +                        }
   3.176 +                    }
   3.177 +                }
   3.178 +            }
   3.179 +            @Override public Void visitClass(ClassTree node, Void p) {
   3.180 +                handleDeclaration();
   3.181 +                return super.visitClass(node, p);
   3.182 +            }
   3.183 +            @Override public Void visitMethod(MethodTree node, Void p) {
   3.184 +                handleDeclaration();
   3.185 +                return super.visitMethod(node, p);
   3.186 +            }
   3.187 +            @Override public Void visitVariable(VariableTree node, Void p) {
   3.188 +                handleDeclaration();
   3.189 +                return super.visitVariable(node, p);
   3.190 +            }
   3.191 +            private void handleDeclaration() {
   3.192 +                Element el = info.getTrees().getElement(getCurrentPath());
   3.193 +
   3.194 +                if (el == null) return;
   3.195 +
   3.196 +                long[] span = ResolveService.nameSpan(info, getCurrentPath());
   3.197 +
   3.198 +                if (span[2] <= position && position <= span[3]) {
   3.199 +                    if (JavaUtils.SUPPORTED_KINDS.contains(el.getKind())) {
   3.200 +                        signature[0] = JavaUtils.serialize(ElementHandle.create(el));
   3.201 +                    }
   3.202 +
   3.203 +                    declaration[0] = true;
   3.204 +                    kind[0] = el.getKind();
   3.205 +                }
   3.206 +            }
   3.207 +        }.scan(info.getCompilationUnit(), null);
   3.208 +
   3.209 +        return new ResolvedLocation(signature[0], kind[0], targetPosition[0], declaration[0]);
   3.210 +    }
   3.211 +
   3.212      @GET
   3.213      @Path("/declarationSpan")
   3.214  //    @Produces("text/html")
   3.215 @@ -775,4 +792,19 @@
   3.216  
   3.217          return Pojson.save(span);
   3.218      }
   3.219 +
   3.220 +    private static class ResolvedLocation {
   3.221 +
   3.222 +        private final String signature;
   3.223 +        private final ElementKind kind;
   3.224 +        private final long position;
   3.225 +        private final boolean declaration;
   3.226 +
   3.227 +        public ResolvedLocation(String signature, ElementKind kind, long position, boolean declaration) {
   3.228 +            this.signature = signature;
   3.229 +            this.kind = kind;
   3.230 +            this.position = position;
   3.231 +            this.declaration = declaration;
   3.232 +        }
   3.233 +    }
   3.234  }