/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.internal.gosu.ir.transform.util;
import gw.internal.gosu.parser.*;
import gw.lang.parser.IDynamicFunctionSymbol;
import gw.lang.parser.IReducedDynamicFunctionSymbol;
import gw.lang.reflect.IType;
import gw.lang.reflect.IPropertyInfo;
import gw.lang.reflect.PropertyInfoBuilder;
import gw.lang.reflect.IPropertyInfoDelegate;
import gw.lang.reflect.gs.IGosuClass;
import gw.lang.reflect.java.IJavaType;
import gw.lang.reflect.java.JavaTypes;
import gw.lang.reflect.java.IJavaPropertyInfo;
import gw.lang.reflect.java.IJavaPropertyDescriptor;
import gw.lang.reflect.java.IJavaClassMethod;
import gw.lang.parser.Keyword;
import gw.lang.reflect.java.JavaTypes;
public class NameResolver {
public static String getGetterName( IPropertyInfo pi )
{
if( pi instanceof GosuPropertyInfo)
{
//## todo: in parser make compilation error for case where a getFoo method is defined in the presence of a Foo property
ReducedDynamicPropertySymbol dps = ((GosuPropertyInfo)pi).getDps();
return getGetterNameForDPS( dps );
}
else if( pi.getClass() == JavaPropertyInfo.class )
{
return ((JavaPropertyInfo)pi).getPropertyDescriptor().getReadMethod().getName();
}
else if( pi instanceof PropertyInfoBuilder.BuiltPropertyInfo )
{
if( pi.getAccessor() instanceof JavaPropertyInfo.PropertyAccessorAdaptor )
{
return ((JavaPropertyInfo.PropertyAccessorAdaptor)pi.getAccessor()).getGetterMethod().getName();
}
else
{
PropertyInfoBuilder.BuiltPropertyInfo bpi = (PropertyInfoBuilder.BuiltPropertyInfo)pi;
if( bpi.getJavaMethodName() != null )
{
return bpi.getJavaMethodName();
}
return "get" + bpi.getName();
}
}
else if( pi instanceof IPropertyInfoDelegate)
{
return getGetterName( ((IPropertyInfoDelegate)pi).getSource() );
}
throw new IllegalArgumentException( "Unexpected property type: " + pi.getClass() );
}
public static String getGetterNameForDPS( ReducedDynamicPropertySymbol dps )
{
return getFunctionName(dps.getGetterDfs());
}
public static String getGetterNameForDPS( DynamicPropertySymbol dps )
{
return getFunctionName(dps.getGetterDfs());
}
public static String getSetterName( IPropertyInfo pi )
{
if( pi instanceof GosuPropertyInfo)
{
//## todo: in parser make compilation error for case where a getFoo method is defined in the presence of a Foo property
ReducedDynamicPropertySymbol dps = ((GosuPropertyInfo)pi).getDps();
return getSetterNameForDPS( dps );
}
else if( pi.getClass() == JavaPropertyInfo.class )
{
return ((JavaPropertyInfo)pi).getPropertyDescriptor().getWriteMethod().getName();
}
else if( pi instanceof PropertyInfoBuilder.BuiltPropertyInfo )
{
if( pi.getAccessor() instanceof JavaPropertyInfo.PropertyAccessorAdaptor )
{
return ((JavaPropertyInfo.PropertyAccessorAdaptor)pi.getAccessor()).getSetterMethod().getName();
}
else
{
PropertyInfoBuilder.BuiltPropertyInfo bpi = (PropertyInfoBuilder.BuiltPropertyInfo)pi;
if( bpi.getJavaMethodName() != null )
{
return bpi.getJavaMethodName();
}
return "set" + bpi.getName();
}
}
else if( pi instanceof IPropertyInfoDelegate)
{
return getSetterName( ((IPropertyInfoDelegate)pi).getSource() );
}
throw new IllegalArgumentException( "Unexpected property type: " + pi.getClass() );
}
public static String getSetterNameForDPS( ReducedDynamicPropertySymbol dps )
{
return getFunctionName( dps.getSetterDfs() );
}
public static String getSetterNameForDPS( DynamicPropertySymbol dps )
{
return getFunctionName( dps.getSetterDfs() );
}
public static String getFunctionName( ReducedDynamicFunctionSymbol dfs )
{
String strName = dfs.getDisplayName();
if( strName.startsWith( "@" ) )
{
final IType returnType = dfs.getReturnType();
if( returnType == JavaTypes.pVOID() )
{
strName = Keyword.KW_set + strName.substring( 1 );
}
else
{
strName = resolveCorrectGetterMethodPrefixForBooleanDFS( dfs ) + strName.substring( 1 );
}
}
return strName;
}
public static String getFunctionName( DynamicFunctionSymbol dfs )
{
String strName = dfs.getDisplayName();
if( strName.startsWith( "@" ) )
{
final IType returnType = dfs.getReturnType();
if( returnType == JavaTypes.pVOID() )
{
strName = Keyword.KW_set + strName.substring( 1 );
}
else
{
strName = resolveCorrectGetterMethodPrefixForBooleanDFS( dfs ) + strName.substring( 1 );
}
}
return strName;
}
private static String resolveCorrectGetterMethodPrefixForBooleanDFS( IDynamicFunctionSymbol dfs )
{
while( dfs.getBackingDfs() != null && dfs.getBackingDfs() != dfs )
{
dfs = dfs.getBackingDfs();
}
IType returnType = dfs.getReturnType();
if (returnType == JavaTypes.pBOOLEAN() || returnType == JavaTypes.BOOLEAN()) {
IDynamicFunctionSymbol rootDFS = dfs;
while (rootDFS.getSuperDfs() != null) {
rootDFS = rootDFS.getSuperDfs();
while( rootDFS.getBackingDfs() != null && rootDFS.getBackingDfs() != rootDFS )
{
rootDFS = rootDFS.getBackingDfs();
}
}
if (rootDFS.getGosuClass() != null &&
IGosuClass.ProxyUtil.isProxy(rootDFS.getGosuClass())) {
IType proxiedType = IGosuClass.ProxyUtil.getProxiedType(rootDFS.getGosuClass());
IPropertyInfo propertyInfo = proxiedType.getTypeInfo().getProperty(dfs.getDisplayName().substring(1));
if (propertyInfo instanceof IJavaPropertyInfo) {
IJavaPropertyDescriptor propertyDescriptor = ((IJavaPropertyInfo) propertyInfo).getPropertyDescriptor();
IJavaClassMethod readMethod = propertyDescriptor.getReadMethod();
if (readMethod != null) {
if (readMethod.getName().startsWith("is")) {
return "is";
} else {
assert(readMethod.getName().startsWith("get"));
return "get";
}
}
}
}
// default to "is" for other boolean properties
return "is";
} else {
// Everything else defaults to "get"
return "get";
}
}
private static String resolveCorrectGetterMethodPrefixForBooleanDFS( IReducedDynamicFunctionSymbol dfs )
{
while( dfs.getBackingDfs() != null && dfs.getBackingDfs() != dfs )
{
dfs = dfs.getBackingDfs();
}
IType returnType = dfs.getReturnType();
if (returnType == JavaTypes.pBOOLEAN() || returnType == JavaTypes.BOOLEAN()) {
IReducedDynamicFunctionSymbol rootDFS = dfs;
while (rootDFS.getSuperDfs() != null) {
rootDFS = rootDFS.getSuperDfs();
}
if (rootDFS.getGosuClass() != null &&
IGosuClass.ProxyUtil.isProxy(rootDFS.getGosuClass())) {
IType proxiedType = IGosuClass.ProxyUtil.getProxiedType(rootDFS.getGosuClass());
IPropertyInfo propertyInfo = proxiedType.getTypeInfo().getProperty(dfs.getDisplayName().substring(1));
if (propertyInfo instanceof IJavaPropertyInfo) {
IJavaPropertyDescriptor propertyDescriptor = ((IJavaPropertyInfo) propertyInfo).getPropertyDescriptor();
IJavaClassMethod readMethod = propertyDescriptor.getReadMethod();
if (readMethod != null) {
if (readMethod.getName().startsWith("is")) {
return "is";
} else {
assert(readMethod.getName().startsWith("get"));
return "get";
}
}
}
}
// default to "is" for other boolean properties
return "is";
} else {
// Everything else defaults to "get"
return "get";
}
}
}