/***** BEGIN LICENSE BLOCK ***** * Version: CPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Common Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/cpl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Mirko Stocker <me@misto.ch> * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the CPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the CPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.rubypeople.rdt.refactoring.util; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; import org.jruby.ast.Colon3Node; import org.jruby.ast.IterNode; import org.jruby.ast.MethodDefNode; import org.jruby.ast.NilImplicitNode; import org.jruby.ast.Node; import org.jruby.lexer.yacc.IDESourcePosition; import org.jruby.lexer.yacc.ISourcePosition; import org.jruby.parser.StaticScope; public class NodeUtil { public static boolean hasScope(Node node) { Method[] methods = node.getClass().getMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals("getScope") || methods[i].equals("getStaticScope")) { //$NON-NLS-1$ //$NON-NLS-2$ return true; } } return false; } public static Node getBody(Node node) { try { Method method = node.getClass().getMethod("getBodyNode", new Class[] {}); //$NON-NLS-1$ return (Node) method.invoke(node, new Object[] {}); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } public static StaticScope getScope(Node node) { String methodName = "getStaticScope"; //$NON-NLS-1$ if (node instanceof MethodDefNode || node instanceof IterNode) { methodName = "getScope"; //$NON-NLS-1$ } try { Method method = node.getClass().getMethod(methodName, new Class[] {}); return (StaticScope) method.invoke(node, new Object[] {}); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } public static boolean nodeAssignableFrom(Node n, Class... klasses) { if (n == null) { return false; } for (Class<?> klass : klasses) { if (klass.isAssignableFrom(n.getClass())) { return true; } } return false; } public static ISourcePosition subPositionUnion(Node node) { ISourcePosition enclosingPosition = node.getPosition(); try { enclosingPosition = node.getPositionIncludingComments(); } catch (Throwable t) { // ignore - may throw an unsupported exception... } List<Node> childList = node.childNodes(); for (Node currentChild : childList) { // combinePosition() is not yet available in JRuby (SourcePosition), hope it will we soon. // While waiting for this use the posUnion method. // enclosingPosition = SourcePosition.combinePosition(enclosingPosition, subPositionUnion(currentChild)); if (currentChild.equals(NilImplicitNode.NIL)) { continue; } enclosingPosition = posUnion(enclosingPosition, subPositionUnion(currentChild)); } return enclosingPosition; } private static ISourcePosition posUnion(ISourcePosition firstPos, ISourcePosition secondPos) { String fileName = firstPos.getFile(); int startOffset = firstPos.getStartOffset(); int endOffset = firstPos.getEndOffset(); int startLine = firstPos.getStartLine(); int endLine = firstPos.getEndLine(); if (startOffset > secondPos.getStartOffset()) { startOffset = secondPos.getStartOffset(); startLine = secondPos.getStartLine(); } if (endOffset < secondPos.getEndOffset()) { endOffset = secondPos.getEndOffset(); endLine = secondPos.getEndLine(); } return new IDESourcePosition(fileName, startLine, endLine, startOffset, endOffset); } public static boolean positionIsInNode(int offset, Colon3Node path) { return offset >= path.getPosition().getStartOffset() && offset <= path.getPosition().getEndOffset(); } }