All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
gw.util.GosuRefactorUtil Maven / Gradle / Ivy
/*
* Copyright 2014 Guidewire Software, Inc.
*/
package gw.util;
import gw.lang.parser.IExpression;
import gw.lang.parser.IParseTree;
import gw.lang.parser.IParsedElement;
import gw.lang.parser.IStatement;
import gw.lang.parser.statements.IClassStatement;
import gw.lang.parser.statements.IStatementList;
import gw.lang.parser.statements.IClassDeclaration;
import java.util.List;
public class GosuRefactorUtil
{
/**
* Finds a bounding parent of any of the possible types passed in from the list of locations, starting at the position
* given.
*/
public static IParsedElement boundingParent( List locations, int position, Class extends IParsedElement>... possibleTypes )
{
IParseTree location = IParseTree.Search.getDeepestLocation( locations, position, true );
IParsedElement pe = null;
if( location != null )
{
pe = location.getParsedElement();
while( pe != null && !isOneOfTypes( pe, possibleTypes ) )
{
pe = pe.getParent();
}
}
return pe;
}
private static boolean isOneOfTypes( IParsedElement pe, Class extends IParsedElement>[] possibleTypes )
{
for( Class extends IParsedElement> possibleType : possibleTypes )
{
if( possibleType.isAssignableFrom( pe.getClass() ) )
{
return true;
}
}
return false;
}
/**
* Given two parse tree positions, find the bounding pair that captures the start and end in one logical unit
*/
public static IParseTree[] findSpanningLogicalRange( IParseTree start, IParseTree end )
{
while( end != null )
{
IParseTree deepestAtStart = start;
while( deepestAtStart != null )
{
if( deepestAtStart.isSiblingOf( end ) )
{
IParseTree[] returnVal = new IParseTree[2];
if( deepestAtStart.getOffset() < end.getOffset() )
{
returnVal[0] = deepestAtStart;
}
else
{
returnVal[0] = end;
}
if( deepestAtStart.getExtent() > end.getExtent() )
{
returnVal[1] = deepestAtStart;
}
else
{
returnVal[1] = end;
}
return returnVal;
}
deepestAtStart = deepestAtStart.getParent();
}
end = end.getParent();
}
return null;
}
public static MoveInstruction getMoveUpInstruction( IParseTree elementToMoveBefore )
{
return findElementToMoveToBefore( elementToMoveBefore );
}
public static MoveInstruction getMoveDownInstruction( IParseTree elementToMoveAfter )
{
return findElementToMoveToAfter( elementToMoveAfter );
}
private static MoveInstruction findElementToMoveToBefore( IParseTree child )
{
IParseTree parent = child.getParent();
IParseTree precedingChild = parent.getChildBefore( child );
if( precedingChild == null )
{
//if this is a statement list, defer to the parent of this
if( parent.getParsedElement() instanceof IStatementList )
{
IParseTree previousSibling = parent.getPreviousSibling();
if( previousSibling != null && previousSibling.getParsedElement() instanceof IStatementList )
{
return new MoveInstruction( false, false, previousSibling.getExtent() );
}
else
{
//If there is no preceding list, we are just going to move above the parent of the statement list
parent = parent.getParent();
}
}
if( isClassElement( parent ) )
{
return null;
}
return new MoveInstruction( false, true, parent.getOffset() );
}
else {
if (precedingChild.getParsedElement() instanceof IClassDeclaration) {
return null;
}
IParseTree precedingStmtList = precedingChild.getLastChildWithParsedElementType(IStatementList.class);
if (precedingStmtList != null && !isClassElement(child)) {
return new MoveInstruction(true, false, precedingStmtList.getExtent());
} else {
return new MoveInstruction(false, false, precedingChild.getOffset());
}
}
}
public static boolean isClassElement( IParseTree parseTree )
{
return parseTree.getParsedElement() instanceof IClassStatement ||
parseTree.getParent() != null && parseTree.getParent().getParsedElement() instanceof IClassStatement;
}
public static MoveInstruction findElementToMoveToAfter( IParseTree child )
{
IParseTree parent = child.getParent();
IParseTree followingChild = parent.getChildAfter( child );
if( followingChild == null )
{
if( parent.getParsedElement() instanceof IStatementList )
{
IParseTree nextSibling = parent.getNextSibling();
if( nextSibling != null && nextSibling.getParsedElement() instanceof IStatementList )
{
return new MoveInstruction( false, false, nextSibling.getOffset() );
}
else
{
//If there is no preceding list, we are just going to move above the parent of the statement list
parent = parent.getParent();
}
}
if( isClassElement( parent ) )
{
return null;
}
return new MoveInstruction( false, true, parent.getExtent() );
}
else
{
IParseTree precedingStmtList = followingChild.getFirstChildWithParsedElementType( IStatementList.class );
if( precedingStmtList != null && !isClassElement( child ) )
{
return new MoveInstruction( true, false, precedingStmtList.getOffset() );
}
else
{
return new MoveInstruction( false, false, followingChild.getExtent() );
}
}
}
public static IParseTree findFirstStatementAtLine( int line, int position, List locations )
{
return findStatementAtLine( locations, position, line, true );
}
public static IParseTree findLastStatementAtLine( int line, int position, List locations )
{
return findStatementAtLine( locations, position, line, false );
}
private static IParseTree findStatementAtLine( List locations, int position, int line, boolean earliest )
{
for( IParseTree location : locations )
{
IParseTree deepestLocation = location.getDeepestLocation( position, true );
if( deepestLocation != null )
{
while( deepestLocation != null &&
!(deepestLocation.getParsedElement() instanceof IStatement) )
{
deepestLocation = deepestLocation.getParent();
}
if( deepestLocation != null )
{
if( deepestLocation.getLineNum() == line )
{
deepestLocation = deepestLocation.getParent();
}
List list = deepestLocation.getChildren();
IParseTree closestChildOnLine = null;
for( IParseTree parseTree : list )
{
//ignore statement lists and expressions
if( parseTree.getParsedElement() instanceof IStatementList ||
parseTree.getParsedElement() instanceof IExpression )
{
continue;
}
if( parseTree.getLineNum() == line )
{
if( closestChildOnLine == null )
{
closestChildOnLine = parseTree;
}
else if( earliest && parseTree.getOffset() < closestChildOnLine.getOffset() )
{
closestChildOnLine = parseTree;
}
else if( parseTree.getOffset() > closestChildOnLine.getOffset() )
{
closestChildOnLine = parseTree;
}
}
}
if( closestChildOnLine != null )
{
return closestChildOnLine;
}
else
{
if( deepestLocation.getParsedElement() instanceof IStatementList )
{
return deepestLocation.getParent();
}
else if( deepestLocation.getParsedElement() instanceof IClassStatement )
{
return null;
}
else
{
return deepestLocation;
}
}
}
}
}
return null;
}
public static class MoveInstruction
{
public boolean indent;
public boolean outdent;
public int position;
public MoveInstruction( boolean indent, boolean outdent, int position )
{
this.indent = indent;
this.outdent = outdent;
this.position = position;
}
}
}