All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.plugins.groovy.dsl.dsltop.GroovyDslDefaultMembers Maven / Gradle / Ivy

Go to download

A packaging of the IntelliJ Community Edition groovy-psi library. This is release number 1 of trunk branch 142.

The newest version!
/*
 * Copyright 2000-2014 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 org.jetbrains.plugins.groovy.dsl.dsltop;

import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.dsl.GdslMembersHolderConsumer;
import org.jetbrains.plugins.groovy.dsl.holders.DelegatedMembersHolder;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.resolve.processors.CompletionProcessor;
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;

/**
 * @author ilyas
 */
@SuppressWarnings({"MethodMayBeStatic", "UnusedDeclaration"})
public class GroovyDslDefaultMembers implements GdslMembersProvider {

  /**
   * Find a class by its full-qualified name
   *
   * @param fqn
   * @return
   */
  @Nullable
  public PsiClass findClass(String fqn, GdslMembersHolderConsumer consumer) {
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(consumer.getProject());
    return facade.findClass(fqn, GlobalSearchScope.allScope(consumer.getProject()));
  }

  /**
   * **********************************************************************************
   * Methods and properties of the GroovyDSL language
   * **********************************************************************************
   */

  public void delegatesTo(@Nullable PsiElement elem, GdslMembersHolderConsumer consumer) {
    if (elem instanceof PsiClass) {
      final PsiClass clazz = (PsiClass)elem;
      final DelegatedMembersHolder holder = new DelegatedMembersHolder();

      if (clazz instanceof GrTypeDefinition) {
        final PsiClassType type = JavaPsiFacade.getElementFactory(consumer.getProject()).createType(clazz);
        final ResolverProcessor processor = CompletionProcessor.createPropertyCompletionProcessor(clazz);
        final GroovyPsiElement context = (GroovyPsiElement)clazz;
        ResolveUtil.processAllDeclarations(type, processor, ResolveState.initial(), context);
        for (GroovyResolveResult result : processor.getCandidates()) {
          final PsiElement element = result.getElement();
          if (element instanceof PsiMethod && !((PsiMethod)element).isConstructor() || element instanceof PsiField) {
            holder.addMember((PsiMember)element);
          }
        }
      }
      else {
        for (PsiMethod method : clazz.getAllMethods()) {
          if (!method.isConstructor()) holder.addMember(method);
        }
        for (PsiField field : clazz.getAllFields()) {
          holder.addMember(field);
        }
      }
      consumer.addMemberHolder(holder);
    }
    else if (elem instanceof GrExpression) {
      GrExpression expr = (GrExpression)elem;
      final PsiType type = expr.getType();
      if (type instanceof PsiClassType) {
        PsiClassType ctype = (PsiClassType)type;
        delegatesTo(ctype.resolve(), consumer);
      }
    }
  }

  /**
   * Add a member to a context's ctype
   *
   * @param member
   */
  public PsiMember add(PsiMember member, GdslMembersHolderConsumer consumer) {
    final DelegatedMembersHolder holder = new DelegatedMembersHolder();
    holder.addMember(member);
    consumer.addMemberHolder(holder);
    return member;
  }

  /**
   * Returns enclosing method call of a given context's place
   */
  @Nullable
  public GrCall enclosingCall(String name, GdslMembersHolderConsumer consumer) {
    final PsiElement place = consumer.getPlace();
    if (place == null) return null;
    GrCall call = PsiTreeUtil.getParentOfType(place, GrCall.class, true);
    if (call == null) return null;
    while (call != null && !name.equals(getInvokedMethodName(call))) {
      call = PsiTreeUtil.getParentOfType(call, GrCall.class, true);
    }
    if (call == null) return null;

    final GrArgumentList argumentList = call.getArgumentList();
    if (argumentList != null) {
      for (GrExpression arg : argumentList.getExpressionArguments()) {
        if (arg instanceof GrClosableBlock && PsiTreeUtil.findCommonParent(place, arg) == arg) {
          return call;
        }
      }
    }

    if (call instanceof GrMethodCallExpression) {
      for (GrExpression arg : call.getClosureArguments()) {
        if (arg instanceof GrClosableBlock && PsiTreeUtil.findCommonParent(place, arg) == arg) {
          return call;
        }
      }
    }
    return null;
  }

  @Nullable
  public PsiMethod enclosingMethod(GdslMembersHolderConsumer consumer) {
    final PsiElement place = consumer.getPlace();
    if (place == null) return null;
    return PsiTreeUtil.getParentOfType(place, PsiMethod.class, true);
  }

  @Nullable
  public PsiMember enclosingMember(GdslMembersHolderConsumer consumer) {
    final PsiElement place = consumer.getPlace();
    if (place == null) return null;
    final PsiMember member = PsiTreeUtil.getParentOfType(place, PsiMember.class, true);
    if (member instanceof PsiClass) return null;
    return member;
  }

  @Nullable
  public PsiClass enclosingClass(GdslMembersHolderConsumer consumer) {
    final PsiElement place = consumer.getPlace();
    if (place == null) return null;
    return PsiTreeUtil.getParentOfType(place, PsiClass.class, true);
  }

  @Nullable
  private static String getInvokedMethodName(GrCall call) {
    if (call instanceof GrMethodCall) {
      final GrExpression expr = ((GrMethodCall)call).getInvokedExpression();
      if (expr instanceof GrReferenceExpression) {
        return ((GrReferenceExpression)expr).getReferenceName();
      }
    }
    return null;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy