/* * Copyright 2013 Guidewire Software, Inc. */ package gw.plugin.ij.completion.handlers; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionResultSet; import com.intellij.psi.PsiElement; import com.intellij.psi.impl.source.tree.LeafPsiElement; import gw.config.CommonServices; import gw.lang.parser.IExpression; import gw.lang.parser.IHasArguments; import gw.lang.parser.IParsedElement; import gw.lang.parser.expressions.IIntervalExpression; import gw.lang.parser.expressions.IMemberAccessExpression; import gw.lang.parser.expressions.IParenthesizedExpression; import gw.lang.reflect.IAttributedFeatureInfo; import gw.lang.reflect.IErrorType; import gw.lang.reflect.IFeatureInfo; import gw.lang.reflect.IMetaType; import gw.lang.reflect.INamespaceType; import gw.lang.reflect.IType; import gw.lang.reflect.java.JavaTypes; import gw.plugin.ij.completion.model.BeanInfoModel; import gw.plugin.ij.lang.parser.GosuRawPsiElement; import gw.plugin.ij.lang.psi.impl.GosuBaseElementImpl; import gw.util.IFeatureFilter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class MemberPathCompletionHandler extends AbstractPathCompletionHandler { private IType _rootType; public MemberPathCompletionHandler(@NotNull CompletionParameters params, @NotNull CompletionResultSet results) { super(params.getOriginalFile().getProject(), params, results.getPrefixMatcher(), results); } public void handleCompletePath() { // head back to the other side of the dot PsiElement element = getContext().getPosition().getPrevSibling(); if (element == null || element.getPrevSibling() == null) { return; } String text = ""; while (element instanceof LeafPsiElement) { text = element.getText() + text; element = element.getPrevSibling(); } text = text.trim(); boolean starDot = text.equals("*."); while (element instanceof GosuRawPsiElement && ((GosuRawPsiElement) element).getParsedElement() instanceof IParenthesizedExpression) { element = element.getFirstChild(); while (element != null && element instanceof LeafPsiElement) { element = element.getNextSibling(); } } IExpression expr = null; if (element instanceof GosuBaseElementImpl) { GosuBaseElementImpl gosuRefExpr = (GosuBaseElementImpl) element; IParsedElement pe = gosuRefExpr.getParsedElement(); if( pe instanceof IExpression ) { expr = (IExpression)pe; } else { return; } } else { return; } IParsedElement parentExpr = expr.getParent(); while (parentExpr instanceof IParenthesizedExpression) { parentExpr = parentExpr.getParent(); } String strMemberPath = ""; if (parentExpr instanceof IMemberAccessExpression) { if (parentExpr instanceof IHasArguments) { // if(getContext().getInvocationOffset() >= ((IHasArguments)expr).getArgPosition()) { // return null; // } } _rootType = expr.getType(); if (_rootType instanceof IErrorType || _rootType instanceof INamespaceType || (_rootType instanceof IMetaType && ((IMetaType) _rootType).getType() instanceof IErrorType)) { return; } // IFeatureFilter filter = null; // if (expr.getParent() instanceof IFieldAccessExpression && IQueryPathExpression.Util.isQueryPathExpressionPart((IFieldAccessExpression) expr.getParent())) { // filter = CommonServices.getEntityAccess().getQueryExpressionFeatureFilter(); // } IType type = expr.getType(); if (starDot) { IType componentType = JavaTypes.OBJECT(); if (type.isArray()) { componentType = type.getComponentType(); } else if (JavaTypes.COLLECTION().isAssignableFrom(type)) { IType asCollection = CommonServices.getTypeSystem().findParameterizedType(type, JavaTypes.COLLECTION()); if (asCollection != null) { IType[] typeParams = asCollection.getTypeParameters(); if (typeParams != null && typeParams.length == 1) { componentType = typeParams[0]; } } } type = componentType; } BeanInfoModel beanInfoModel = new BeanInfoModel(type, "", expr.getGosuClass(), expr.getGosuClass().getTypeLoader().getModule(), new IFeatureFilter() { @Override public boolean acceptFeature(IType beanType, @NotNull IFeatureInfo fi) { if (fi instanceof IAttributedFeatureInfo) { if (_rootType instanceof IMetaType) { return ((IAttributedFeatureInfo) fi).isStatic(); } else { return !((IAttributedFeatureInfo) fi).isStatic(); } } else { return true; } } }); makeProposals(beanInfoModel); } else if (parentExpr instanceof IIntervalExpression) { strMemberPath = "."; BeanInfoModel beanInfoModel = new BeanInfoModel(expr.getReturnType(), strMemberPath, expr.getGosuClass(), expr.getGosuClass().getTypeLoader().getModule()); makeProposals(beanInfoModel); } } @Nullable @Override public String getStatusMessage() { return _rootType == null ? null : _rootType.getName(); } }