/* * Copyright 2013 Guidewire Software, Inc. */ package gw.plugin.ij.lang.psi.impl.expressions; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.PsiType; import com.intellij.util.IncorrectOperationException; import gw.lang.parser.IParsedElement; import gw.lang.parser.ISymbol; import gw.lang.parser.expressions.IIdentifierExpression; import gw.lang.parser.expressions.ITypeLiteralExpression; import gw.lang.reflect.IMetaType; import gw.lang.reflect.IType; import gw.lang.reflect.gs.IGosuClass; import gw.plugin.ij.lang.parser.GosuCompositeElement; import gw.plugin.ij.lang.psi.api.types.IGosuCodeReferenceElement; import gw.plugin.ij.lang.psi.api.types.IGosuTypeElement; import gw.plugin.ij.lang.psi.api.types.IGosuTypeParameterList; import gw.plugin.ij.lang.psi.impl.AbstractGosuClassFileImpl; import gw.plugin.ij.lang.psi.impl.GosuElementVisitor; import gw.plugin.ij.lang.psi.impl.resolvers.PsiFeatureResolver; import gw.plugin.ij.lang.psi.impl.resolvers.PsiTypeResolver; import gw.plugin.ij.util.ExecutionUtil; import gw.plugin.ij.util.SafeCallable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class GosuIdentifierExpressionImpl extends GosuReferenceExpressionImpl<IIdentifierExpression> implements IGosuCodeReferenceElement, IGosuTypeElement { public GosuIdentifierExpressionImpl(GosuCompositeElement node) { super(node); } @Nullable public PsiElement getReferenceNameElement() { // Return the psi identifier *token* PsiElement child = this; while (child.getFirstChild() != null) { child = child.getFirstChild(); } return child; } @Override public IGosuCodeReferenceElement getQualifier() { return null; } @Override public void setQualifier(IGosuCodeReferenceElement newQualifier) { throw new UnsupportedOperationException("Men at work"); } @Override public PsiType[] getTypeArguments() { return PsiType.EMPTY_ARRAY; } @Nullable public IGosuTypeParameterList getTypeParameterList() { return null; } @Override public PsiElement resolve() { return ExecutionUtil.execute(new SafeCallable<PsiElement>(this) { @Nullable public PsiElement execute() throws Exception { IParsedElement pe = getParsedElement(); if (pe == null) { return null; } if (pe instanceof ITypeLiteralExpression) { IMetaType metaType = ((ITypeLiteralExpression) pe).getType(); return PsiTypeResolver.resolveType(metaType.getType(), GosuIdentifierExpressionImpl.this); } if (pe instanceof IIdentifierExpression) { IIdentifierExpression parsedElement = (IIdentifierExpression) pe; ISymbol symbol = parsedElement.getSymbol(); PsiElement element = PsiFeatureResolver.resolveSymbol(symbol, symbol.getGosuClass(), GosuIdentifierExpressionImpl.this); if (element == null) { IGosuClass gsClass = parsedElement.getGosuClass(); if (symbol.isValueBoxed() && gsClass.isAnonymous()) { gsClass = (IGosuClass) gsClass.getEnclosingType(); } element = PsiFeatureResolver.resolveSymbol(symbol, gsClass, GosuIdentifierExpressionImpl.this); } return element; } return null; } }); } @NotNull public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { PsiElement elt = GosuTypeLiteralImpl.bindType(this, element, (AbstractGosuClassFileImpl) getContainingFile()); return elt != null ? elt : this; } @Nullable public static IType maybeUnwrapProxy(@Nullable IType type) { if (type != null && type.isParameterizedType()) { type = type.getGenericType(); } return type != null ? IGosuClass.ProxyUtil.getProxiedType(type) : null; } @Override public String toString() { return getText(); } @Override public void accept(@NotNull PsiElementVisitor visitor) { if( visitor instanceof GosuElementVisitor) { ((GosuElementVisitor)visitor).visitIdentifierExpression(this); } else { visitor.visitElement( this ); } } }