/*
 * Copyright 2014 Guidewire Software, Inc.
 */

package gw.internal.gosu.ir.nodes;

import gw.lang.reflect.IType;
import gw.lang.reflect.IRelativeTypeInfo;
import gw.lang.parser.IDynamicPropertySymbol;
import gw.lang.ir.IRType;
import gw.internal.gosu.parser.DynamicPropertySymbol;
import gw.internal.gosu.parser.ParameterizedDynamicPropertySymbol;
import gw.internal.gosu.parser.TypeLord;
import gw.internal.gosu.ir.transform.util.AccessibilityUtil;
import gw.internal.gosu.ir.transform.util.IRTypeResolver;

public class IRPropertyFromDynamicPropertySymbol implements IRProperty {

  private DynamicPropertySymbol _dps;

  public IRPropertyFromDynamicPropertySymbol(DynamicPropertySymbol dps) {
    _dps = dps;
  }

  public DynamicPropertySymbol getDps() {
    return _dps;
  }

  @Override
  public IRType getType() {
    return IRTypeResolver.getDescriptor( getBoundedPropertyType( _dps ) );
  }

  @Override
  public String getName() {
    return _dps.getName();
  }

  @Override
  public boolean isField() {
    return false;
  }

  @Override
  public boolean isCaptured() {
    return false;
  }

  @Override
  public IRMethod getGetterMethod() {
    return new IRMethodForDPSGetter( this );
  }

  @Override
  public IRMethod getSetterMethod() {
    return new IRMethodForDPSSetter( this );
  }

  @Override
  public IRType getOwningIRType() {
    return IRTypeResolver.getDescriptor( _dps.getGosuClass() );
  }

  @Override
  public IType getOwningIType() {
    return _dps.getGosuClass();
  }

  @Override
  public IRelativeTypeInfo.Accessibility getAccessibility() {
    return AccessibilityUtil.forSymbol( _dps );
  }

  @Override
  public boolean isStatic() {
    return _dps.isStatic();
  }

  @Override
  public IRType getTargetRootIRType() {
    return getOwningIRType();
  }

  @Override
  public boolean isBytecodeProperty() {
    return true;
  }

  public IType getBoundedPropertyType( IDynamicPropertySymbol dps )
  {
    while( dps instanceof ParameterizedDynamicPropertySymbol)
    {
      ParameterizedDynamicPropertySymbol pdfs = (ParameterizedDynamicPropertySymbol)dps;
      dps = pdfs.getDelegate();
    }
    return TypeLord.getDefaultParameterizedTypeWithTypeVars( dps.getType() );
  }
}

@@ -504,16 +504,237 @@
 esolver;
+%0Aimport gw.lang.reflect.gs.IGosuClass;%0Aimport gw.lang.reflect.java.IJavaClassInfo;%0Aimport gw.lang.reflect.java.IJavaPropertyDescriptor;%0Aimport gw.lang.reflect.java.IJavaPropertyInfo;%0Aimport gw.lang.reflect.java.IJavaType;
 %0A%0Apublic
@@ -1053,38 +1053,8 @@
 turn
- IRTypeResolver.getDescriptor(
  get
@@ -1078,18 +1078,16 @@
 pe( _dps
- )
  );%0A  %7D%0A
@@ -2055,32 +2055,33 @@
 %0A  %7D%0A%0A  public I
+R
 Type getBoundedP
@@ -2325,83 +2325,1128 @@
   %7D%0A
-    return TypeLord.getDefaultParameterizedTypeWithTypeVars( dps.getType() 
+%0A    if( dps.getGosuClass() != null && IGosuClass.ProxyUtil.isProxy( dps.getGosuClass() ) )%0A    %7B%0A      return getBoundedReturnTypeFromProxiedClass( dps );%0A    %7D%0A%0A    return IRTypeResolver.getDescriptor( TypeLord.getDefaultParameterizedTypeWithTypeVars( dps.getType() ) );%0A  %7D%0A%0A  private IRType getBoundedReturnTypeFromProxiedClass( IDynamicPropertySymbol dps )%0A  %7B%0A    IJavaPropertyDescriptor pd = getJavaPropertyFromProxy( dps );%0A    IJavaClassInfo type = pd.getReadMethod() != null%0A                          ? pd.getReadMethod().getReturnClassInfo()%0A                          : pd.getPropertyClassInfo();%0A    return JavaClassIRType.get( type );%0A  %7D%0A%0A  private IJavaPropertyDescriptor getJavaPropertyFromProxy( IDynamicPropertySymbol dps )%0A  %7B%0A    IType proxyType = dps.getGosuClass();%0A    IJavaType javaType = (IJavaType) IGosuClass.ProxyUtil.getProxiedType( proxyType );%0A%0A    javaType = (IJavaType)TypeLord.getDefaultParameterizedType( javaType );%0A    IJavaPropertyInfo jpi = (IJavaPropertyInfo)((IRelativeTypeInfo)javaType.getTypeInfo()).getProperty( javaType, dps.getName() );%0A    return jpi.getPropertyDescriptor(
 );%0A 

Use bounded super type of inherited property