/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.parser; import gw.internal.gosu.parser.statements.VarStatement; import gw.lang.parser.GlobalScope; import gw.lang.parser.TypeVarToTypeMap; import gw.lang.parser.expressions.INewExpression; import gw.lang.parser.expressions.IVarStatement; import gw.lang.reflect.*; import gw.lang.reflect.gs.IGosuVarPropertyInfo; import gw.lang.reflect.gs.IGosuClass; import gw.lang.reflect.java.JavaTypes; import java.util.Collections; import java.util.List; import java.lang.reflect.Field; /** */ public class GosuVarPropertyInfo extends GosuBaseAttributedFeatureInfo implements IGosuVarPropertyInfo { private String _strIdentifer; private IType _actualType; private boolean _bStatic; private boolean _bPublic; private boolean _bProtected; private boolean _bInternal; private boolean _bPrivate; private IPropertyAccessor _accessor; private String _fullDescription; private boolean _hasProperty; private boolean _isScopedField; private IGosuClass _gosuClass; private boolean _isFinal; private IType _symbolType; private String _symbolScopeString; private String _symbolAttributeName; private int _modifiers; GosuVarPropertyInfo( IFeatureInfo container, IVarStatement varStmt ) { super( container ); _strIdentifer = varStmt.getIdentifierName(); _actualType = assignActualType(varStmt.getType()); _bStatic = varStmt.isStatic(); _bPublic = varStmt.isPublic(); _bProtected = varStmt.isProtected(); _bInternal = varStmt.isInternal(); _bPrivate = varStmt.isPrivate(); _fullDescription = varStmt.getFullDescription(); _hasProperty = varStmt.hasProperty(); _isScopedField = varStmt.getScope() == GlobalScope.REQUEST || varStmt.getScope() == GlobalScope.SESSION; _symbolType = varStmt.getSymbol().getType(); if (_isScopedField) { ScopedDynamicSymbol symbol = (ScopedDynamicSymbol) varStmt.getSymbol(); _symbolScopeString = symbol.getScope().toString(); _symbolAttributeName = symbol.getAttributeName(); } _gosuClass = varStmt.getParent() != null ? varStmt.getParent().getGosuClass() : null; _isFinal = varStmt.isFinal(); ModifierInfo modifierInfo = ((VarStatement) varStmt).getModifierInfo(); _modifiers = modifierInfo.getModifiers(); ((GosuClassTypeInfo)getOwnersType().getTypeInfo()).setModifierInfo( this, modifierInfo ); } public GosuVarPropertyInfo(GosuClassTypeInfo container, GosuVarPropertyInfo pi) { super( container ); _strIdentifer = pi._strIdentifer; _actualType = assignActualType( pi._actualType ); _bStatic = pi._bStatic; _bPublic = pi._bPublic; _bProtected = pi._bProtected; _bInternal = pi._bInternal; _bPrivate = pi._bPrivate; _fullDescription = pi._fullDescription; _hasProperty = pi._hasProperty; _isScopedField = pi._isScopedField; _symbolScopeString = pi._symbolScopeString; _symbolAttributeName = pi._symbolAttributeName; _symbolType = pi._symbolType; _gosuClass = pi._gosuClass; _isFinal = pi._isFinal; _modifiers = pi._modifiers; GosuClassTypeInfo ti = (GosuClassTypeInfo)getOwnersType().getTypeInfo(); ti.setModifierInfo( this, ti.getModifierInfo( pi ) ); } public String getName() { return _strIdentifer == null ? null : _strIdentifer.toString(); } public IType getFeatureType() { if( _actualType == JavaTypes.pVOID() ) { getOwnersType().isValid(); _actualType = assignActualType( _actualType ); } return _actualType; } public boolean isStatic() { return _bStatic; } public boolean isPrivate() { return _bPrivate; } public boolean isInternal() { return _bInternal; } public boolean isProtected() { return _bProtected; } @Override public boolean isFinal() { return _isFinal; } public boolean isPublic() { return _bPublic || (!isPrivate() && !isInternal() && !isProtected()); } protected List<IGosuAnnotation> getGosuAnnotations() { IModifierInfo modifierInfo = ((GosuClassTypeInfo)getOwnersType().getTypeInfo()).getModifierInfo( this ); return modifierInfo != null ? modifierInfo.getAnnotations() : Collections.<IGosuAnnotation>emptyList(); } public boolean isReadable() { return true; } public boolean isWritable(IType whosAskin) { return !isFinal(); } public boolean isWritable() { return isWritable( null ) && !isFinal(); } public IPropertyAccessor getAccessor() { if( _accessor != null ) { return _accessor; } return _accessor = new VarPropertyAccessor(); } public IPresentationInfo getPresentationInfo() { return IPresentationInfo.Default.GET; } public IType assignActualType(IType type) { if( _actualType == null || _actualType == JavaTypes.pVOID() ) { _actualType = getActualTypeInContainer( this, type ); } return _actualType; } public void assignSymbolType( IType type ) { if( _symbolType == null || _symbolType == JavaTypes.pVOID() ) { _symbolType = type; } } public boolean hasDeclaredProperty() { return _hasProperty; } @Override public boolean isScopedField() { return _isScopedField; } @Override public IType getScopedSymbolType() { return _symbolType; } @Override public String getSymbolScopeString() { return _symbolScopeString; } @Override public String getSymbolAttributeName() { return _symbolAttributeName; } public GenericTypeVariable[] getTypeVariables() { return GenericTypeVariable.EMPTY_TYPEVARS; } public IType getParameterizedReturnType( IType... typeParams ) { return null; } public IType[] getParameterizedParameterTypes( IType... typeParams ) { return IType.EMPTY_ARRAY; } public IType[] getParameterizedParameterTypes2( IGosuClass ownersType, IType... typeParams ) { return IType.EMPTY_ARRAY; } public TypeVarToTypeMap inferTypeParametersFromArgumentTypes( IType... argTypes ) { return null; } @Override public TypeVarToTypeMap inferTypeParametersFromArgumentTypes2( IGosuClass owningParameterizedType, IType... argTypes ) { return null; } @Override public boolean isCompileTimeConstantValue() { return getCompileTimeConstantExpression() != null; } @Override public Object doCompileTimeEvaluation() { Expression expr = getCompileTimeConstantExpression(); return expr instanceof INewExpression ? getName() // Enum constant field name : expr.evaluate(); } private Expression getCompileTimeConstantExpression() { // Must be static constant if( !isStatic() || !isFinal() ) { return null; } IType type = getFeatureType(); // Must be either primitive, String, or Enum constant if( type != JavaTypes.STRING() && !type.isPrimitive() && !type.isEnum() ) { return null; } // // Field must be initialized directly // if( getOwnersType().isDeclarationsCompiled() ) { getOwnersType().isValid(); // barf } for( VarStatement varStmt : getOwnersType().getParseInfo().getStaticFields().values() ) { // barf if( varStmt.getIdentifierName().toString().equals( getName() ) ) { Expression initiazerExpr = varStmt.getAsExpression(); if( initiazerExpr != null ) { return varStmt.isEnumConstant() || initiazerExpr.isCompileTimeConstant() ? initiazerExpr : null; } } } return null; } private class VarPropertyAccessor implements IPropertyAccessor { public Object getValue( Object ctx ) { IGosuClass gsClass = (IGosuClass)getContainer().getOwnersType(); try { Field field = gsClass.getBackingClass().getDeclaredField( _strIdentifer ); field.setAccessible( true ); return field.get( ctx ); } catch( Exception e ) { throw new RuntimeException( e ); } } public void setValue( Object ctx, Object value ) { IGosuClass gsClass = _gosuClass; try { Field field = gsClass.getBackingClass().getDeclaredField( _strIdentifer ); field.setAccessible( true ); field.set( ctx, value ); } catch( Exception e ) { throw new RuntimeException( e ); } } } public String getDescription() { return _fullDescription; } }