Package com.intellij.coldFusion.model.psi

Source Code of com.intellij.coldFusion.model.psi.CfmlArgumentNameReference

/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.coldFusion.model.psi;

import com.intellij.codeInsight.TailType;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.codeInsight.lookup.TailTypeDecorator;
import com.intellij.coldFusion.UI.CfmlLookUpItemUtil;
import com.intellij.coldFusion.model.CfmlUtil;
import com.intellij.coldFusion.model.info.CfmlFunctionDescription;
import com.intellij.coldFusion.model.info.CfmlLangInfo;
import com.intellij.coldFusion.model.lexer.CfmlTokenTypes;
import com.intellij.coldFusion.model.lexer.CfscriptTokenTypes;
import com.intellij.coldFusion.model.psi.impl.CfmlNamedAttributeImpl;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementResolveResult;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.ResolveResult;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.LinkedList;

public class CfmlArgumentNameReference extends CfmlReferenceExpression implements PsiElement {
  public CfmlArgumentNameReference(@NotNull final ASTNode node) {
    super(node);
  }

  public String getFunctionName() {
    CfmlFunctionCallExpression parentOfType = PsiTreeUtil.getParentOfType(this, CfmlFunctionCallExpression.class);
    if (parentOfType != null) {
      return parentOfType.getFunctionName();
    }
    return "";
  }

  // ColdFusion does not allow dublicates in functions' names
  @Nullable
  private CfmlFunction resolveToFunction() {
    CfmlFunctionCallExpression parentOfType = PsiTreeUtil.getParentOfType(this, CfmlFunctionCallExpression.class);
    if (parentOfType != null) {
      CfmlReference referenceExpression = parentOfType.getReferenceExpression();
      PsiElement resolve = referenceExpression.resolve();
      if (resolve instanceof CfmlNamedAttributeImpl) {
        resolve = resolve.getParent();
      }
      if (resolve instanceof CfmlFunction) {
        return ((CfmlFunction)resolve);
      }
    }
    return null;
  }

  @Nullable
  private CfmlParameter[] getFunctionParameters() {
    CfmlFunction cfmlFunction = resolveToFunction();
    if (cfmlFunction != null) {
      return cfmlFunction.getParameters();
    }
    return null;
  }

  @Override
  protected ResolveResult[] resolveInner() {
    PsiElement nextSibling = getNextSibling();
    while (nextSibling instanceof PsiWhiteSpace) {
      nextSibling = nextSibling.getNextSibling();
    }
    if (nextSibling != null && nextSibling.getNode().getElementType() != CfmlTokenTypes.ASSIGN) {
      return super.resolveInner();
    }
    CfmlParameter[] functionParameters = getFunctionParameters();
    if (functionParameters != null) {
      Collection<ResolveResult> result = new LinkedList<ResolveResult>();
      String referenceName = getReferenceName();
      for (CfmlParameter param : functionParameters) {
        if (referenceName.equals(param.getName())) {
          result.add(new PsiElementResolveResult(param));
        }
      }
      return result.toArray(ResolveResult.EMPTY_ARRAY);
    }
    return ResolveResult.EMPTY_ARRAY;
  }

  @NotNull
  @Override
  protected CfmlReferenceExpression parseReference(String newText) {
    return CfmlPsiUtil.createReferenceExpression(newText, getProject());
  }

  @Override
  protected PsiElement getSeparator() {
    return findChildByType(CfscriptTokenTypes.POINT);
  }

  @NotNull
  @Override
  public String getReferenceName() {
    PsiElement referenceNameElement = getReferenceNameElement();
    if (referenceNameElement != null) {
      return referenceNameElement.getText();
    }
    return "";
  }

  @Override
  protected PsiElement getReferenceNameElement() {
    return findChildByType(CfscriptTokenTypes.IDENTIFIER);
  }

  @NotNull
  @Override
  public Object[] getVariants() {
    Collection<LookupElement> result = new LinkedList<LookupElement>();
    Object[] superResult = ArrayUtil.EMPTY_OBJECT_ARRAY;

    String functionName = getFunctionName();
    if (CfmlUtil.isPredefinedFunction(functionName, getProject())) {
      CfmlFunctionDescription cfmlFunctionDescription =
        CfmlLangInfo.getInstance(getProject()).getFunctionParameters().get(functionName.toLowerCase());
      for (CfmlFunctionDescription.CfmlParameterDescription param : cfmlFunctionDescription.getParameters()) {
        result.add(TailTypeDecorator.withTail(
          LookupElementBuilder.create(param.getName()).withCaseSensitivity(false),
          TailType.createSimpleTailType('=')));
      }
    }
    else {
      CfmlArgumentList parentArgumentsList = PsiTreeUtil.getParentOfType(this, CfmlArgumentList.class);
      if (parentArgumentsList != null) {
        CfmlExpression[] arguments = parentArgumentsList.getArguments();
        if (arguments.length == 1) {
          result.add(LookupElementBuilder.create("argumentCollection").withCaseSensitivity(false));
        }
      }
    }

    PsiElement nextSibling = getNextSibling();
    while (nextSibling instanceof PsiWhiteSpace) {
      nextSibling = nextSibling.getNextSibling();
    }
    if (nextSibling != null && nextSibling.getNode().getElementType() != CfmlTokenTypes.ASSIGN) {
      superResult = super.getVariants();
    }

    CfmlParameter[] functionParameters = getFunctionParameters();
    if (functionParameters != null) {
      for (CfmlParameter param : functionParameters) {
        result.add(CfmlLookUpItemUtil.namedElementToLookupItem(param, null));
      }
    }

    if (!result.isEmpty() || superResult.length > 0) {
      return ArrayUtil.mergeArrays(superResult, ContainerUtil.map2Array(result, Object.class, new Function<LookupElement, Object>() {
        @Override
        public Object fun(LookupElement lookupElement) {
          return lookupElement;
        }
      }));
    }
    return ArrayUtil.EMPTY_OBJECT_ARRAY;
  }

  @NotNull
  @Override
  public String getName() {
    PsiElement referenceNameElement = getReferenceNameElement();
    return referenceNameElement != null ? referenceNameElement.getText() : "";
  }

  public String toString() {
    return "Argument " + getName();
  }
}
TOP

Related Classes of com.intellij.coldFusion.model.psi.CfmlArgumentNameReference

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.