/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.internal.gosu.parser;
import gw.lang.parser.IDynamicFunctionSymbol;
import gw.lang.parser.IDynamicPropertySymbol;
import gw.lang.parser.IReducedDynamicPropertySymbol;
import gw.lang.parser.IScriptPartId;
import gw.lang.parser.ISymbol;
import gw.lang.reflect.IPropertyInfo;
import gw.lang.reflect.IRelativeTypeInfo;
import gw.lang.reflect.IType;
import gw.lang.reflect.ITypeInfo;
import gw.lang.reflect.gs.IGosuClass;
import java.util.List;
/**
*/
public class DynamicPropertySymbol extends AbstractDynamicSymbol implements IDynamicPropertySymbol
{
private DynamicPropertySymbol _dpsParent;
DynamicFunctionSymbol _dfsGetter;
DynamicFunctionSymbol _dfsSetter;
private String _varIdentifier;
public DynamicPropertySymbol( DynamicFunctionSymbol dfsGetterOrSetter, boolean bGetter )
{
super( dfsGetterOrSetter.getSymbolTable(),
dfsGetterOrSetter.getDisplayName().substring( 1 ),
bGetter
? dfsGetterOrSetter.getReturnType()
: dfsGetterOrSetter.getArgs().size() > 0
? dfsGetterOrSetter.getArgs().get( 0 ).getType()
: ErrorType.getInstance() );
_dfsGetter = bGetter ? dfsGetterOrSetter : null;
_dfsSetter = bGetter ? null : dfsGetterOrSetter;
setModifierInfo( dfsGetterOrSetter.getModifierInfo() );
setClassMember( true );
setName( (String)getName() );
_scriptPartId = dfsGetterOrSetter._scriptPartId;
}
public DynamicPropertySymbol( DynamicPropertySymbol dps )
{
super( dps.getSymbolTable(), dps.getName(), dps.getType() );
_dfsGetter = dps._dfsGetter;
_dfsSetter = dps._dfsSetter;
replaceModifierInfo(dps.getModifierInfo());
setClassMember( true );
_scriptPartId = dps._scriptPartId;
}
public ISymbol getLightWeightReference()
{
return this;
}
public Object getValue()
{
if( getGetterDfs() == null )
{
throw new IllegalStateException( "No getter available." );
}
return getGetterDfs().invoke( null );
}
public Object getValueDirectly()
{
return getValue();
}
public void setValue( Object value )
{
if( getSetterDfs() == null )
{
throw new IllegalStateException( "No setter available." );
}
getSetterDfs().invoke( new Object[]{value} );
}
public void setValueDirectly( Object value )
{
setValue( value );
}
public boolean isReadable()
{
return getGetterDfs() != null;
}
public boolean isWritable()
{
return getSetterDfs() != null;
}
public void clearDebugInfo()
{
super.clearDebugInfo();
if( _dfsGetter != null )
{
_dfsGetter.clearDebugInfo();
}
if( _dfsSetter != null )
{
_dfsSetter.clearDebugInfo();
}
if( _dpsParent != null &&
_dpsParent.getGosuClass() == getGosuClass() )
{
_dpsParent.clearDebugInfo();
}
}
public boolean isPublic()
{
return getGetterDfs() == null
? super.isPublic()
: getGetterDfs().isPublic();
}
public boolean isPrivate()
{
return getGetterDfs() == null
? super.isPrivate()
: getGetterDfs().isPrivate();
}
public boolean isInternal()
{
return getGetterDfs() == null
? super.isInternal()
: getGetterDfs().isInternal();
}
public boolean isProtected()
{
return getGetterDfs() == null
? super.isProtected()
: getGetterDfs().isProtected();
}
public boolean isStatic()
{
return getGetterDfs() == null
? super.isStatic()
: getGetterDfs().isStatic();
}
public boolean isAbstract()
{
return getGetterDfs() == null
? super.isAbstract()
: getGetterDfs().isAbstract();
}
public boolean isFinal()
{
return getGetterDfs() == null
? super.isFinal()
: getGetterDfs().isFinal();
}
public void setGetterDfs( IDynamicFunctionSymbol dfsGetter )
{
_dfsGetter = (DynamicFunctionSymbol) dfsGetter;
setModifierInfo( dfsGetter.getModifierInfo() );
setInternal( _dfsGetter.isInternal() );
setPrivate( _dfsGetter.isPrivate() );
setProtected( _dfsGetter.isProtected() );
setPublic( _dfsGetter.isPublic() );
}
public DynamicFunctionSymbol getGetterDfs()
{
return _dfsGetter == null
? _dpsParent != null
? _dpsParent.getGetterDfs()
: null
: _dfsGetter;
}
protected DynamicFunctionSymbol getImmediateGetterDfs()
{
return _dfsGetter;
}
public void setSetterDfs( IDynamicFunctionSymbol dfsSetter )
{
_dfsSetter = (DynamicFunctionSymbol) dfsSetter;
}
public DynamicFunctionSymbol getSetterDfs()
{
return _dfsSetter == null
? _dpsParent != null
? _dpsParent.getSetterDfs()
: null
: _dfsSetter;
}
protected DynamicFunctionSymbol getImmediateSetterDfs()
{
return _dfsSetter;
}
protected void setParent( DynamicPropertySymbol dpsParent )
{
_dpsParent = dpsParent;
}
public DynamicPropertySymbol getParent()
{
return _dpsParent;
}
public DynamicFunctionSymbol getFunction( String strFunctionName )
{
if( functionNamesEqual( _dfsGetter, strFunctionName ) )
{
return _dfsGetter;
}
if( functionNamesEqual( _dfsSetter, strFunctionName ) )
{
return _dfsSetter;
}
return null;
}
private boolean functionNamesEqual( DynamicFunctionSymbol dfs, String strFunctionName )
{
return dfs != null &&
(dfs.getName().equals( strFunctionName ) ||
dfs.getName().toLowerCase().contains( "_duplicate_" + strFunctionName.toLowerCase() ) );
}
public void addMemberSymbols( ICompilableTypeInternal gsClass )
{
gsClass.getParseInfo().addMemberProperty( this );
if( _dfsGetter != null && _dfsGetter.getGosuClass() == gsClass )
{
gsClass.getParseInfo().addMemberFunction( _dfsGetter );
}
if( _dfsSetter != null && _dfsSetter.getGosuClass() == gsClass )
{
gsClass.getParseInfo().addMemberFunction( _dfsSetter );
}
}
public void setVarIdentifier( String varIdentifier )
{
_varIdentifier = varIdentifier;
}
public String getVarIdentifier()
{
return _varIdentifier;
}
public String getFullDescription()
{
return getModifierInfo() == null ? "" : getModifierInfo().getDescription();
}
public DynamicPropertySymbol getParameterizedVersion( IGosuClass gsClass )
{
return new ParameterizedDynamicPropertySymbol( this, (IGosuClassInternal)gsClass );
}
public void clearDefn() {
if (_dfsGetter != null) {
_dfsGetter.clearDefn();
}
if (_dfsSetter != null) {
_dfsSetter.clearDefn();
}
}
/*
* We must copy the annotation information down to the getter and setter, since those annotations
* need to head out to bytecode land
*/
public void updateAnnotations(List<IGosuAnnotation> annotations) {
getModifierInfo().setAnnotations(annotations);
if (_dfsGetter != null) {
_dfsGetter.getModifierInfo().setAnnotations(annotations);
}
if (_dfsSetter != null) {
_dfsSetter.getModifierInfo().setAnnotations(annotations);
}
}
public IReducedDynamicPropertySymbol createReducedSymbol() {
return new ReducedDynamicPropertySymbol( this );
}
@Override
public IPropertyInfo getPropertyInfo()
{
IScriptPartId scriptPart = getScriptPart();
IType declaringType = scriptPart == null ? null : scriptPart.getContainingType();
if( declaringType == null )
{
return null;
}
ITypeInfo typeInfo = declaringType.getTypeInfo();
List<? extends IPropertyInfo> properties;
if( typeInfo instanceof IRelativeTypeInfo )
{
properties = ((IRelativeTypeInfo)typeInfo).getProperties( declaringType );
}
else
{
properties = typeInfo.getProperties();
}
for( IPropertyInfo pi : properties )
{
if( pi.getName().equals( this.getName() ) )
{
return pi;
}
}
return null;
}
}