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

org.jetbrains.plugins.groovy.dgm.GdkMethodHolder 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.dgm;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.VolatileNotNullLazyValue;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.scope.NameHint;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
import com.intellij.util.containers.ConcurrentFactoryMap;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
import org.jetbrains.plugins.groovy.lang.psi.util.GdkMethodUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;

/**
 * @author Max Medvedev
 */
public class GdkMethodHolder {
  private static final Key> CACHED_NON_STATIC = Key.create("Cached instance gdk method holder");
  private static final Key> CACHED_STATIC = Key.create("Cached static gdk method holder");


  private final ConcurrentFactoryMap> myOriginalMethodsByNameAndType;
  private final NotNullLazyValue> myOriginalMethodByType;
  private final boolean myStatic;
  private final GlobalSearchScope myScope;
  private final PsiManager myPsiManager;

  private GdkMethodHolder(final PsiClass categoryClass, final boolean isStatic, final GlobalSearchScope scope) {
    myStatic = isStatic;
    myScope = scope;
    final MultiMap byName = new MultiMap();
    myPsiManager = categoryClass.getManager();
    for (PsiMethod m : categoryClass.getMethods()) {
      final PsiParameter[] params = m.getParameterList().getParameters();
      if (params.length == 0) continue;
      if (PsiUtil.isDGMMethod(m) && (PsiImplUtil.isDeprecatedByAnnotation(m) || PsiImplUtil.isDeprecatedByDocTag(m))) {
        continue;
      }
      byName.putValue(m.getName(), m);
    }
    this.myOriginalMethodByType = new VolatileNotNullLazyValue>() {
      @NotNull
      @Override
      protected MultiMap compute() {
        MultiMap map = new MultiMap();
        for (PsiMethod method : byName.values()) {
          if (!method.hasModifierProperty(PsiModifier.PUBLIC)) continue;
          map.putValue(getCategoryTargetType(method).getCanonicalText(), method);
        }
        return map;
      }
    };

    myOriginalMethodsByNameAndType = new ConcurrentFactoryMap>() {
      @Override
      protected MultiMap create(String name) {
        MultiMap map = new MultiMap();
        for (PsiMethod method : byName.get(name)) {
          map.putValue(getCategoryTargetType(method).getCanonicalText(), method);
        }
        return map;
      }
    };
  }

  private PsiType getCategoryTargetType(PsiMethod method) {
    final PsiType parameterType = method.getParameterList().getParameters()[0].getType();
    return TypesUtil.boxPrimitiveType(TypeConversionUtil.erasure(parameterType), myPsiManager, myScope);
  }

  public boolean processMethods(PsiScopeProcessor processor, @NotNull ResolveState state, PsiType qualifierType, Project project) {
    if (qualifierType == null) return true;

    NameHint nameHint = processor.getHint(NameHint.KEY);
    String name = nameHint == null ? null : nameHint.getName(state);
    final MultiMap map = name != null ? myOriginalMethodsByNameAndType.get(name) : myOriginalMethodByType.getValue();
    if (map.isEmpty()) {
      return true;
    }

    for (String superType : ResolveUtil.getAllSuperTypes(qualifierType, project).keySet()) {
      for (PsiMethod method : map.get(superType)) {
        String info = GdkMethodUtil.generateOriginInfo(method);
        GrGdkMethod gdk = GrGdkMethodImpl.createGdkMethod(method, myStatic, info);
        if (!processor.execute(gdk, state)) {
          return false;
        }
      }
    }

    return true;
  }

  public static GdkMethodHolder getHolderForClass(final PsiClass categoryClass, final boolean isStatic, final GlobalSearchScope scope) {
    final Project project = categoryClass.getProject();
    Key> key = isStatic ? CACHED_STATIC : CACHED_NON_STATIC;
    return CachedValuesManager.getManager(project).getCachedValue(categoryClass, key, new CachedValueProvider() {
      @Override
      public Result compute() {
        GdkMethodHolder result = new GdkMethodHolder(categoryClass, isStatic, scope);

        final ProjectRootManager rootManager = ProjectRootManager.getInstance(project);
        final VirtualFile vfile = categoryClass.getContainingFile().getVirtualFile();
        if (vfile != null && (rootManager.getFileIndex().isInLibraryClasses(vfile) || rootManager.getFileIndex().isInLibrarySource(vfile))) {
          return Result.create(result, rootManager);
        }

        return Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, rootManager);
      }
    }, false);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy