# HG changeset patch # User enebo@netbeans.org # Date 1386524356 21600 # Node ID 07958c1ff4025654702a7983750296e947657812 # Parent 32cac83e9ae773c198a53f90b195a50cb10537ed Too much stuff in one commit. Rename blocks now follows language semantics. Removal of more ASTPath consumers diff -r 32cac83e9ae7 -r 07958c1ff402 ruby/src/org/netbeans/modules/ruby/AstUtilities.java --- a/ruby/src/org/netbeans/modules/ruby/AstUtilities.java Sun Nov 24 15:46:13 2013 -0600 +++ b/ruby/src/org/netbeans/modules/ruby/AstUtilities.java Sun Dec 08 11:39:16 2013 -0600 @@ -1707,19 +1707,33 @@ } } + public static List getOutermostToInnerMostBlocks(Node leaf) { + Node scope = leaf.getInnermostIter(); + + if (scope == null) return Collections.emptyList(); + + List result = new ArrayList(); + while (scope != null) { + result.add(scope); + + scope = scope.getInnermostIter(); + } + + Collections.reverse(result); + + return result; + } + /** Return all the blocknodes that apply to the given node. The outermost block * is returned first. */ public static List getApplicableBlocks(AstPath path, boolean includeNested) { Node block = AstUtilities.findBlock(path); - if (block == null) { - // Use parent + if (block == null) { // Use parent block = path.leafParent(); - if (block == null) { - return Collections.emptyList(); - } + if (block == null) return Collections.emptyList(); } List result = new ArrayList(); @@ -1727,37 +1741,34 @@ // Skip the leaf node, we're going to add it unconditionally afterwards if (includeNested) { - if (it.hasNext()) { - it.next(); - } + if (it.hasNext()) it.next(); } Node leaf = path.root(); - while_loop: + while_loop: while (it.hasNext()) { Node n = it.next(); switch (n.getNodeType()) { - //case BLOCKNODE: - case ITERNODE: - leaf = n; - result.add(n); - break; - case DEFNNODE: - case DEFSNODE: - case CLASSNODE: - case SCLASSNODE: - case MODULENODE: - leaf = n; - break while_loop; + case ITERNODE: + leaf = n; + result.add(n); + break; + case DEFNNODE: + case DEFSNODE: + case CLASSNODE: + case SCLASSNODE: + case MODULENODE: + leaf = n; + break while_loop; } } if (includeNested) { - addNodesByType(leaf, new NodeType[] { /*NodeType.BLOCKNODE,*/ NodeType.ITERNODE }, result); + addNodesByType(leaf, new NodeType[] { NodeType.ITERNODE }, result); } - return result; + return result; } public static String guessName(Parser.Result result, OffsetRange lexRange, OffsetRange astRange) { diff -r 32cac83e9ae7 -r 07958c1ff402 ruby/src/org/netbeans/modules/ruby/RubyDeclarationFinder.java --- a/ruby/src/org/netbeans/modules/ruby/RubyDeclarationFinder.java Sun Nov 24 15:46:13 2013 -0600 +++ b/ruby/src/org/netbeans/modules/ruby/RubyDeclarationFinder.java Sun Dec 08 11:39:16 2013 -0600 @@ -82,6 +82,8 @@ import org.jrubyparser.ast.SymbolNode; import org.jrubyparser.ast.VCallNode; import org.jrubyparser.ast.INameNode; +import org.jrubyparser.ast.IParameterScope; +import org.jrubyparser.ast.IterNode; import org.jrubyparser.ast.NodeType; import org.jrubyparser.ast.SuperNode; import org.jrubyparser.ast.ZSuperNode; @@ -378,7 +380,7 @@ } AstPath path = new AstPath(root, astOffset); - Node closest = path.leaf(); + Node closest = AstUtilities.findNodeAtOffset(root, astOffset); if (closest == null) return; // See if the hyperlink is over a method reference in an rdoc comment @@ -404,23 +406,18 @@ closest instanceof CallNode) { // A method call String name = ((INameNode)closest).getName(); - Call call = Call.getCallType(doc, th, lexOffset); - RubyType type = call.getType(); String lhs = call.getLhs(); if (!type.isKnown() && lhs != null && call.isSimpleIdentifier()) { Node method = AstUtilities.findLocalScope(closest, path); - if (method != null) { - // TODO - if the lhs is "foo.bar." I need to split this - // up and do it a bit more cleverly - ContextKnowledge knowledge = new ContextKnowledge( - index, root, method, astOffset, lexOffset, parserResult); - RubyTypeInferencer inferencer = RubyTypeInferencer.create(knowledge); - type = inferencer.inferType(lhs); - } + // TODO - if the lhs is "foo.bar." I need to split this + // up and do it a bit more cleverly + ContextKnowledge knowledge = new ContextKnowledge( + index, root, method, astOffset, lexOffset, parserResult); + type = RubyTypeInferencer.create(knowledge).inferType(lhs); } // Constructors: "new" ends up calling "initialize". @@ -1346,37 +1343,28 @@ @SuppressWarnings("empty-statement") private DeclarationLocation findRDocMethod(ParserResult info, Document doc, int astOffset, int lexOffset, Node root, AstPath path, Node closest, RubyIndex index) { - TokenHierarchy th = TokenHierarchy.get(doc); +// TokenHierarchy th = TokenHierarchy.get(doc); + TokenSequence ts = LexUtilities.getRubyTokenSequence((BaseDocument)doc, lexOffset); - - if (ts == null) { - return DeclarationLocation.NONE; - } + if (ts == null) return DeclarationLocation.NONE; ts.move(lexOffset); - if (!ts.moveNext() && !ts.movePrevious()) { - return DeclarationLocation.NONE; - } + if (!ts.moveNext() && !ts.movePrevious()) return DeclarationLocation.NONE; Token token = ts.token(); - TokenSequence embedded = ts.embedded(); if (embedded != null) { - ts = embedded; - embedded.move(lexOffset); - if (!embedded.moveNext() && !embedded.movePrevious()) { - return DeclarationLocation.NONE; - } + if (!embedded.moveNext() && !embedded.movePrevious()) return DeclarationLocation.NONE; token = embedded.token(); } // Is this a comment? If so, possibly do rdoc-method reference jump - if ((token != null) && (token.id() == RubyCommentTokenId.COMMENT_LINK)) { + if (token != null && token.id() == RubyCommentTokenId.COMMENT_LINK) { // TODO - use findLinkedMethod String method = token.text().toString(); @@ -1385,20 +1373,13 @@ DeclarationLocation loc = findMethod(info, root, method, Arity.UNKNOWN); - // It looks like "#foo" can refer not just to methods (as rdoc suggested) - // but to attributes as well - in Rails' initializer.rb this is used - // in a number of places. - if (loc == DeclarationLocation.NONE) { - loc = findInstance(info, root, "@" + method, index); - } - - return loc; + // It looks like "#foo" can refer not just to methods (as rdoc suggested) but to + // attributes as well - in Rails' initializer.rb this is used in a number of places. + return loc != DeclarationLocation.NONE ? loc : findInstance(info, root, "@" + method, index); } else { // A URL such as http://netbeans.org - try to open it in a browser! try { - URL url = new URL(method); - - return new DeclarationLocation(url); + return new DeclarationLocation(new URL(method)); } catch (MalformedURLException mue) { // URL is from user source... don't complain with exception dialogs etc. ; @@ -1794,56 +1775,15 @@ private DeclarationLocation findLocal(ParserResult info, Node node, String name) { if (node instanceof LocalAsgnNode) { - if (((INameNode)node).getName().equals(name)) { - return getLocation(info, node); - } + if (((INameNode)node).getName().equals(name)) return getLocation(info, node); } else if (!ignoreAlias && node instanceof AliasNode) { String newName = AstUtilities.getNameOrValue(((AliasNode)node).getNewName()); - if (name.equals(newName)) { - return getLocation(info, node); - } - } else if (node instanceof ArgsNode) { - ArgsNode an = (ArgsNode)node; - if (an.getRequiredCount() > 0) { - List args = an.childNodes(); - - for (Node arg : args) { - if (arg instanceof ListNode) { - List args2 = arg.childNodes(); - - for (Node arg2 : args2) { - if (arg2 instanceof ArgumentNode) { - if (((ArgumentNode)arg2).getName().equals(name)) { - return getLocation(info, arg2); - } - } else if (arg2 instanceof LocalAsgnNode) { - if (((LocalAsgnNode)arg2).getName().equals(name)) { - return getLocation(info, arg2); - } - } - } - } - } - } - - // Rest args - if (an.getRest() != null) { - ArgumentNode bn = an.getRest(); - - if (bn.getName().equals(name)) { - return getLocation(info, bn); - } - } - - // Block args - if (an.getBlock() != null) { - BlockArgNode bn = an.getBlock(); - - if (bn.getName().equals(name)) { - return getLocation(info, bn); - } - } + if (name.equals(newName)) return getLocation(info, node); + } else if (node instanceof IParameterScope) { + ILocalVariable parameter = ((IParameterScope) node).getParameterNamed(name); + + return parameter != null ? getLocation(info, (Node) parameter) : DeclarationLocation.NONE; } List list = node.childNodes(); diff -r 32cac83e9ae7 -r 07958c1ff402 ruby/src/org/netbeans/modules/ruby/RubyParseResult.java --- a/ruby/src/org/netbeans/modules/ruby/RubyParseResult.java Sun Nov 24 15:46:13 2013 -0600 +++ b/ruby/src/org/netbeans/modules/ruby/RubyParseResult.java Sun Dec 08 11:39:16 2013 -0600 @@ -57,7 +57,6 @@ */ public class RubyParseResult extends org.netbeans.modules.csl.spi.ParserResult { - private final RubyParser parser; private final Node rootNode; private String source; @@ -69,9 +68,8 @@ private boolean commentsAdded; private List errors; - public RubyParseResult(RubyParser parser, Snapshot snapshot, Node rootNode) { + public RubyParseResult(Snapshot snapshot, Node rootNode) { super(snapshot); - this.parser = parser; this.rootNode = rootNode; this.errors = new ArrayList(); } @@ -90,15 +88,6 @@ this.errors = new ArrayList(errors); } - // XXX: CSL rewrite -// public ParserResult.AstTreeNode getAst() { -// return ast; -// } -// -// public void setAst(AstTreeNode ast) { -// this.ast = ast; -// } - /** The root node of the AST produced by the parser. * Later, rip out the getAst part etc. */ diff -r 32cac83e9ae7 -r 07958c1ff402 ruby/src/org/netbeans/modules/ruby/RubyParser.java --- a/ruby/src/org/netbeans/modules/ruby/RubyParser.java Sun Nov 24 15:46:13 2013 -0600 +++ b/ruby/src/org/netbeans/modules/ruby/RubyParser.java Sun Dec 08 11:39:16 2013 -0600 @@ -663,7 +663,7 @@ } protected RubyParseResult createParseResult(Snapshot snapshots, Node rootNode) { - return new RubyParseResult(this, snapshots, rootNode); + return new RubyParseResult(snapshots, rootNode); } public static RubyElement resolveHandle(org.netbeans.modules.csl.spi.ParserResult info, ElementHandle handle) { diff -r 32cac83e9ae7 -r 07958c1ff402 ruby/src/org/netbeans/modules/ruby/RubyRenameHandler.java --- a/ruby/src/org/netbeans/modules/ruby/RubyRenameHandler.java Sun Nov 24 15:46:13 2013 -0600 +++ b/ruby/src/org/netbeans/modules/ruby/RubyRenameHandler.java Sun Dec 08 11:39:16 2013 -0600 @@ -147,11 +147,14 @@ if (closest == null) return Collections.emptySet(); if (closest.isBlockParameter()) { - String name = ((INameNode) closest).getName(); + ILocalVariable blockParameter = (ILocalVariable) closest; - for (Node block : AstUtilities.getApplicableBlocks(path, true)) { - addDynamicVars(info, block, name, regions); - } + for (ILocalVariable occurrence: blockParameter.getOccurrences()) { + OffsetRange range = LexUtilities.getLexerOffsets(info, + AstUtilities.offsetRangeFor(occurrence.getLexicalNamePosition())); + + if (range != OffsetRange.NONE) regions.add(range); + } } else if (closest instanceof LocalVarNode || closest instanceof LocalAsgnNode) { // A local variable read or a parameter read, or an assignment to one of these String name = ((INameNode)closest).getName(); diff -r 32cac83e9ae7 -r 07958c1ff402 ruby/test/unit/data/testfiles/nestedblocks.rb.testRename7.rename --- a/ruby/test/unit/data/testfiles/nestedblocks.rb.testRename7.rename Sun Nov 24 15:46:13 2013 -0600 +++ b/ruby/test/unit/data/testfiles/nestedblocks.rb.testRename7.rename Sun Dec 08 11:39:16 2013 -0600 @@ -1,4 +1,2 @@ -1: [1,2,3].each { ||>outer<|| -2: puts |>outer<| 3: [4,5,6].each { ||>outer<|| 4: puts |>outer<| diff -r 32cac83e9ae7 -r 07958c1ff402 ruby/test/unit/src/org/netbeans/modules/ruby/AstUtilitiesTest.java --- a/ruby/test/unit/src/org/netbeans/modules/ruby/AstUtilitiesTest.java Sun Nov 24 15:46:13 2013 -0600 +++ b/ruby/test/unit/src/org/netbeans/modules/ruby/AstUtilitiesTest.java Sun Dec 08 11:39:16 2013 -0600 @@ -524,9 +524,7 @@ Parser.Result parserResult = getParserResult("testfiles/ape.rb"); String text = getText(parserResult); int caretOffset = getCaretOffset(text, "might_^fail(uri, requested_e_coll, requested_m_coll)"); - Node root = AstUtilities.getRoot(parserResult); - AstPath path = new AstPath(root, caretOffset); - Node call = path.leaf(); + Node call = AstUtilities.getRoot(parserResult).getNodeAt(caretOffset); assertTrue(AstUtilities.isCall(call)); caretOffset = getCaretOffset(text, "might_fail(^uri, requested_e_coll, requested_m_coll)"); @@ -557,9 +555,7 @@ //int caretOffset = 2755; // "new" call from failed earlier test int caretOffset = getCaretOffset(text, "MUTEX = Mutex.^new"); - Node root = AstUtilities.getRoot(parserResult); - AstPath path = new AstPath(root, caretOffset); - Node call = path.leaf(); + Node call = AstUtilities.getRoot(parserResult).getNodeAt(caretOffset); assertTrue(AstUtilities.isCall(call)); assertEquals(-1, AstUtilities.findArgumentIndex(call, caretOffset)); @@ -571,10 +567,7 @@ String text = getText(parserResult); //int caretOffset = 2755; // "new" call from failed earlier test int caretOffset = getCaretOffset(text, "Gem.ac^tivate(gem_name, *version_requirements)"); - - Node root = AstUtilities.getRoot(parserResult); - AstPath path = new AstPath(root, caretOffset); - Node call = path.leaf(); + Node call = AstUtilities.getRoot(parserResult).getNodeAt(caretOffset); assertTrue(AstUtilities.isCall(call)); caretOffset = getCaretOffset(text, "Gem.^activate(gem_name, *version_requirements)"); diff -r 32cac83e9ae7 -r 07958c1ff402 ruby/test/unit/src/org/netbeans/modules/ruby/RubyParserTest.java --- a/ruby/test/unit/src/org/netbeans/modules/ruby/RubyParserTest.java Sun Nov 24 15:46:13 2013 -0600 +++ b/ruby/test/unit/src/org/netbeans/modules/ruby/RubyParserTest.java Sun Dec 08 11:39:16 2013 -0600 @@ -103,8 +103,7 @@ } else { adjustedOffset = caretOffset; } - AstPath path = new AstPath(root, adjustedOffset); - Node closest = path.leaf(); + Node closest = root.getNodeAt(adjustedOffset); assertNotNull(closest); String leafName = closest.getClass().getName(); leafName = leafName.substring(leafName.lastIndexOf('.') + 1); diff -r 32cac83e9ae7 -r 07958c1ff402 ruby/test/unit/src/org/netbeans/modules/ruby/RubyTypeAnalyzerTest.java --- a/ruby/test/unit/src/org/netbeans/modules/ruby/RubyTypeAnalyzerTest.java Sun Nov 24 15:46:13 2013 -0600 +++ b/ruby/test/unit/src/org/netbeans/modules/ruby/RubyTypeAnalyzerTest.java Sun Dec 08 11:39:16 2013 -0600 @@ -82,13 +82,11 @@ enforceCaretOffset(source, caretOffset); } - BaseDocument doc = getDocument(fo); ParserResult parserResult = getParserResult(fo); Node root = AstUtilities.getRoot(parserResult); initializeRegistry(); RubyIndex index = RubyIndex.get(parserResult); - AstPath path = new AstPath(root, caretOffset); - Node node = path.leaf(); + Node node = root.getNodeAt(caretOffset); if (findMethod) { MethodDefNode method = AstUtilities.findMethodAtOffset(root, caretOffset);