/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.parser.optimizer; import gw.internal.gosu.parser.CannotExecuteGosuException; import gw.internal.gosu.parser.Expression; import gw.internal.gosu.parser.Statement; import gw.lang.reflect.INamespaceType; import gw.internal.gosu.parser.expressions.MemberAccess; import gw.internal.gosu.parser.expressions.ArrayAccess; import gw.internal.gosu.parser.statements.MemberAssignmentStatement; import gw.internal.gosu.parser.statements.ArrayAssignmentStatement; import gw.lang.parser.IExpressionRuntime; import gw.lang.parser.IParsedElement; import gw.lang.reflect.IUncacheableFeature; /** * Note this class really isn't an "expression runtime", it's real purpose is * to determine whether or not the corresponding member-access is in the lhs * of an assignment. This info can be useful to decide if null values in the * member path can be auto-assigned (see the gw.lang.Autocreate annotation) */ public class SinglePropertyMemberAccessRuntime implements IExpressionRuntime { private boolean _bNestedInLhs; public SinglePropertyMemberAccessRuntime( MemberAccess memberAccess ) { IParsedElement parent = memberAccess.getParent(); boolean bNested = parent instanceof MemberAccess || parent instanceof ArrayAccess; while( bNested && (parent != null) && !(parent instanceof Statement) ) { parent = parent.getParent(); } if( bNested ) { IParsedElement lhsRoot = null; if ( parent instanceof MemberAssignmentStatement ) { lhsRoot = ((MemberAssignmentStatement)parent).getRootExpression(); } else if ( parent instanceof ArrayAssignmentStatement ) { lhsRoot = ((ArrayAssignmentStatement)parent).getArrayAccessExpression(); } if ( lhsRoot != null ) { IParsedElement csr = memberAccess; while( csr instanceof Expression ) { if( lhsRoot == csr ) { _bNestedInLhs = bNested; break; } csr = csr.getParent(); } } } } public static boolean isConvertible( MemberAccess memberAccess ) { return memberAccess.getMemberExpression() == null && !(memberAccess.getRootType() instanceof INamespaceType) && !(memberAccess.getRootExpression() != null && memberAccess.getRootType().isArray()) && !(memberAccess.getPropertyInfo() instanceof IUncacheableFeature); } @Override public Object evaluate() { throw new CannotExecuteGosuException(); } public boolean isNestedInLhs() { return _bNestedInLhs; } }