2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
6 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 * Other names may be trademarks of their respective owners.
9 * The contents of this file are subject to the terms of either the GNU
10 * General Public License Version 2 only ("GPL") or the Common
11 * Development and Distribution License("CDDL") (collectively, the
12 * "License"). You may not use this file except in compliance with the
13 * License. You can obtain a copy of the License at
14 * http://www.netbeans.org/cddl-gplv2.html
15 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 * specific language governing permissions and limitations under the
17 * License. When distributing the software, include this License Header
18 * Notice in each file and include the License file at
19 * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 * particular file as subject to the "Classpath" exception as provided
21 * by Oracle in the GPL Version 2 section of the License file that
22 * accompanied this code. If applicable, add the following below the
23 * License Header, with the fields enclosed by brackets [] replaced by
24 * your own identifying information:
25 * "Portions Copyrighted [year] [name of copyright owner]"
29 * The Original Software is NetBeans. The Initial Developer of the Original
30 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
31 * Microsystems, Inc. All Rights Reserved.
33 * If you wish your version of this file to be governed by only the CDDL
34 * or only the GPL Version 2, indicate your decision by adding
35 * "[Contributor] elects to include this software in this distribution
36 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37 * single choice of license, a recipient has the option to distribute
38 * your version of this file under either the CDDL, the GPL Version 2 or
39 * to extend the choice of license to its licensees as provided above.
40 * However, if you add GPL Version 2 code and therefore, elected the GPL
41 * Version 2 license, then the option applies only if the new code is
42 * made subject to such option by the copyright holder.
44 package org.netbeans.modules.ruby;
46 import java.util.Collections;
47 import java.util.HashSet;
50 import org.jrubyparser.ast.Node;
51 import org.jrubyparser.ast.ILocalVariable;
52 import org.netbeans.modules.csl.api.InstantRenamer;
53 import org.netbeans.modules.csl.api.OffsetRange;
54 import org.netbeans.modules.csl.spi.ParserResult;
55 import org.netbeans.modules.ruby.lexer.LexUtilities;
56 import org.openide.util.NbBundle;
59 * Handle renaming of local elements
60 * @todo I should be able to rename top-level methods as well since they
62 * @todo Rename |j| in the following will only rename "j" inside the block!
73 * @todo When you fix, make sure BlockarReuse is also fixed!
74 * @todo Try renaming "hello" in the exception here; my code is confused
75 * about what I'm renaming (aliases method name) and the refactoring dialog
76 * name is wrong! This is happening because it's also changing GlobalAsgnNode for $!
77 * but its parent is LocalAsgnNode, and -its- -grand- parent is a RescueBodyNode!
78 * I should special case this!
85 rescue Exception => hello
94 public class RubyRenameHandler implements InstantRenamer {
96 public RubyRenameHandler() {
100 public boolean isRenameAllowed(ParserResult info, int caretOffset, String[] explanationRetValue) {
101 Node root = AstUtilities.getRoot(info);
104 explanationRetValue[0] = NbBundle.getMessage(RubyRenameHandler.class, "NoRenameWithErrors");
108 Node closest = root.getNodeAt(AstUtilities.getAstOffset(info, caretOffset));
109 if (closest == null) return false;
110 if (closest instanceof ILocalVariable) return true; // All local block/method vars can be renamed
112 switch (closest.getNodeType()) {
113 case INSTASGNNODE: case INSTVARNODE: case CLASSVARDECLNODE: case CLASSVARNODE: case CLASSVARASGNNODE:
114 case GLOBALASGNNODE: case GLOBALVARNODE: case CONSTDECLNODE: case CONSTNODE: case DEFNNODE: case DEFSNODE:
115 case FCALLNODE: case CALLNODE: case VCALLNODE: case COLON2NODE: case COLON3NODE: case ALIASNODE:
116 case SYMBOLNODE: // TODO - what about the string arguments in an alias node? Gotta check those
124 public Set<OffsetRange> getRenameRegions(ParserResult info, int caretOffset) {
125 Node closest = AstUtilities.findNodeAtOffset(info, caretOffset);
126 if (closest == null || !(closest instanceof ILocalVariable)) return Collections.emptySet();
128 ILocalVariable variable = (ILocalVariable) closest;
129 Set<OffsetRange> regions = new HashSet<OffsetRange>();
131 for (ILocalVariable occurrence: variable.getOccurrences()) {
132 OffsetRange range = LexUtilities.getLexerOffsets(info,
133 AstUtilities.offsetRangeFor(occurrence.getNamePosition()));
135 if (range != OffsetRange.NONE) regions.add(range);
142 // quick tip renaming
144 // occurrences marking
146 // live code templates
147 // ...anyone else who calls findBlock
149 // Test both parent blocks, sibling blocks and descendant blocks
150 // Make sure the "isUsed" detection is smarter too.