ruby/src/org/netbeans/modules/ruby/RubyDeclarationFinder.java
changeset 4554 07958c1ff402
parent 4553 32cac83e9ae7
     1.1 --- a/ruby/src/org/netbeans/modules/ruby/RubyDeclarationFinder.java	Sun Nov 24 15:46:13 2013 -0600
     1.2 +++ b/ruby/src/org/netbeans/modules/ruby/RubyDeclarationFinder.java	Sun Dec 08 11:39:16 2013 -0600
     1.3 @@ -82,6 +82,8 @@
     1.4  import org.jrubyparser.ast.SymbolNode;
     1.5  import org.jrubyparser.ast.VCallNode;
     1.6  import org.jrubyparser.ast.INameNode;
     1.7 +import org.jrubyparser.ast.IParameterScope;
     1.8 +import org.jrubyparser.ast.IterNode;
     1.9  import org.jrubyparser.ast.NodeType;
    1.10  import org.jrubyparser.ast.SuperNode;
    1.11  import org.jrubyparser.ast.ZSuperNode;
    1.12 @@ -378,7 +380,7 @@
    1.13                          }
    1.14  
    1.15                          AstPath path = new AstPath(root, astOffset);
    1.16 -                        Node closest = path.leaf();
    1.17 +                        Node closest = AstUtilities.findNodeAtOffset(root, astOffset);
    1.18                          if (closest == null) return;
    1.19  
    1.20                          // See if the hyperlink is over a method reference in an rdoc comment
    1.21 @@ -404,23 +406,18 @@
    1.22                                  closest instanceof CallNode) {
    1.23                              // A method call
    1.24                              String name = ((INameNode)closest).getName();
    1.25 -
    1.26                              Call call = Call.getCallType(doc, th, lexOffset);
    1.27 -
    1.28                              RubyType type = call.getType();
    1.29                              String lhs = call.getLhs();
    1.30  
    1.31                              if (!type.isKnown() && lhs != null && call.isSimpleIdentifier()) {
    1.32                                  Node method = AstUtilities.findLocalScope(closest, path);
    1.33  
    1.34 -                                if (method != null) {
    1.35 -                                    // TODO - if the lhs is "foo.bar." I need to split this
    1.36 -                                    // up and do it a bit more cleverly
    1.37 -                                    ContextKnowledge knowledge = new ContextKnowledge(
    1.38 -                                            index, root, method, astOffset, lexOffset, parserResult);
    1.39 -                                    RubyTypeInferencer inferencer = RubyTypeInferencer.create(knowledge);
    1.40 -                                    type = inferencer.inferType(lhs);
    1.41 -                                }
    1.42 +                                // TODO - if the lhs is "foo.bar." I need to split this
    1.43 +                                // up and do it a bit more cleverly
    1.44 +                                ContextKnowledge knowledge = new ContextKnowledge(
    1.45 +                                        index, root, method, astOffset, lexOffset, parserResult);
    1.46 +                                type = RubyTypeInferencer.create(knowledge).inferType(lhs);
    1.47                              }
    1.48  
    1.49                              // Constructors: "new" ends up calling "initialize".
    1.50 @@ -1346,37 +1343,28 @@
    1.51      @SuppressWarnings("empty-statement")
    1.52      private DeclarationLocation findRDocMethod(ParserResult info, Document doc, int astOffset, int lexOffset,
    1.53              Node root, AstPath path, Node closest, RubyIndex index) {
    1.54 -        TokenHierarchy<Document> th = TokenHierarchy.get(doc);
    1.55 +//        TokenHierarchy<Document> th = TokenHierarchy.get(doc);
    1.56 +
    1.57          TokenSequence<?> ts = LexUtilities.getRubyTokenSequence((BaseDocument)doc, lexOffset);
    1.58 -
    1.59 -        if (ts == null) {
    1.60 -            return DeclarationLocation.NONE;
    1.61 -        }
    1.62 +        if (ts == null) return DeclarationLocation.NONE;
    1.63  
    1.64          ts.move(lexOffset);
    1.65  
    1.66 -        if (!ts.moveNext() && !ts.movePrevious()) {
    1.67 -            return DeclarationLocation.NONE;
    1.68 -        }
    1.69 +        if (!ts.moveNext() && !ts.movePrevious()) return DeclarationLocation.NONE;
    1.70  
    1.71          Token<?> token = ts.token();
    1.72 -
    1.73          TokenSequence<?> embedded = ts.embedded();
    1.74  
    1.75          if (embedded != null) {
    1.76 -            ts = embedded;
    1.77 -
    1.78              embedded.move(lexOffset);
    1.79  
    1.80 -            if (!embedded.moveNext() && !embedded.movePrevious()) {
    1.81 -                return DeclarationLocation.NONE;
    1.82 -            }
    1.83 +            if (!embedded.moveNext() && !embedded.movePrevious()) return DeclarationLocation.NONE;
    1.84  
    1.85              token = embedded.token();
    1.86          }
    1.87  
    1.88          // Is this a comment? If so, possibly do rdoc-method reference jump
    1.89 -        if ((token != null) && (token.id() == RubyCommentTokenId.COMMENT_LINK)) {
    1.90 +        if (token != null && token.id() == RubyCommentTokenId.COMMENT_LINK) {
    1.91              // TODO - use findLinkedMethod
    1.92              String method = token.text().toString();
    1.93  
    1.94 @@ -1385,20 +1373,13 @@
    1.95  
    1.96                  DeclarationLocation loc = findMethod(info, root, method, Arity.UNKNOWN);
    1.97  
    1.98 -                // It looks like "#foo" can refer not just to methods (as rdoc suggested)
    1.99 -                // but to attributes as well - in Rails' initializer.rb this is used
   1.100 -                // in a number of places.
   1.101 -                if (loc == DeclarationLocation.NONE) {
   1.102 -                    loc = findInstance(info, root, "@" + method, index);
   1.103 -                }
   1.104 -
   1.105 -                return loc;
   1.106 +                // It looks like "#foo" can refer not just to methods (as rdoc suggested) but to 
   1.107 +                // attributes as well - in Rails' initializer.rb this is used in a number of places.
   1.108 +                return loc != DeclarationLocation.NONE ? loc : findInstance(info, root, "@" + method, index);
   1.109              } else {
   1.110                  // A URL such as http://netbeans.org - try to open it in a browser!
   1.111                  try {
   1.112 -                    URL url = new URL(method);
   1.113 -
   1.114 -                    return new DeclarationLocation(url);
   1.115 +                    return new DeclarationLocation(new URL(method));
   1.116                  } catch (MalformedURLException mue) {
   1.117                      // URL is from user source... don't complain with exception dialogs etc.
   1.118                      ;
   1.119 @@ -1794,56 +1775,15 @@
   1.120  
   1.121      private DeclarationLocation findLocal(ParserResult info, Node node, String name) {
   1.122          if (node instanceof LocalAsgnNode) {
   1.123 -            if (((INameNode)node).getName().equals(name)) {
   1.124 -                return getLocation(info, node);
   1.125 -            }
   1.126 +            if (((INameNode)node).getName().equals(name)) return getLocation(info, node);
   1.127          } else if (!ignoreAlias && node instanceof AliasNode) {
   1.128              String newName = AstUtilities.getNameOrValue(((AliasNode)node).getNewName());
   1.129 -            if (name.equals(newName)) {
   1.130 -                return getLocation(info, node);
   1.131 -            }
   1.132 -        } else if (node instanceof ArgsNode) {
   1.133 -            ArgsNode an = (ArgsNode)node;
   1.134  
   1.135 -            if (an.getRequiredCount() > 0) {
   1.136 -                List<Node> args = an.childNodes();
   1.137 -
   1.138 -                for (Node arg : args) {
   1.139 -                    if (arg instanceof ListNode) {
   1.140 -                        List<Node> args2 = arg.childNodes();
   1.141 -
   1.142 -                        for (Node arg2 : args2) {
   1.143 -                            if (arg2 instanceof ArgumentNode) {
   1.144 -                                if (((ArgumentNode)arg2).getName().equals(name)) {
   1.145 -                                    return getLocation(info, arg2);
   1.146 -                                }
   1.147 -                            } else if (arg2 instanceof LocalAsgnNode) {
   1.148 -                                if (((LocalAsgnNode)arg2).getName().equals(name)) {
   1.149 -                                    return getLocation(info, arg2);
   1.150 -                                }
   1.151 -                            }
   1.152 -                        }
   1.153 -                    }
   1.154 -                }
   1.155 -            }
   1.156 -
   1.157 -            // Rest args
   1.158 -            if (an.getRest() != null) {
   1.159 -                ArgumentNode bn = an.getRest();
   1.160 -
   1.161 -                if (bn.getName().equals(name)) {
   1.162 -                    return getLocation(info, bn);
   1.163 -                }
   1.164 -            }
   1.165 -
   1.166 -            // Block args
   1.167 -            if (an.getBlock() != null) {
   1.168 -                BlockArgNode bn = an.getBlock();
   1.169 -
   1.170 -                if (bn.getName().equals(name)) {
   1.171 -                    return getLocation(info, bn);
   1.172 -                }
   1.173 -            }
   1.174 +            if (name.equals(newName)) return getLocation(info, node);
   1.175 +        } else if (node instanceof IParameterScope) {
   1.176 +            ILocalVariable parameter = ((IParameterScope) node).getParameterNamed(name);
   1.177 +            
   1.178 +            return parameter != null ? getLocation(info, (Node) parameter) : DeclarationLocation.NONE;
   1.179          }
   1.180  
   1.181          List<Node> list = node.childNodes();