예제 #1
0
  /**
   * @return true, if the element contains a reference to a different class than fullyQualifiedName
   *     but which has the same class name
   */
  public static boolean containsConflictingReference(PsiFile element, String fullyQualifiedName) {
    final Map<String, Boolean> cachedValue =
        CachedValuesManager.getManager(element.getProject())
            .getCachedValue(
                element,
                new CachedValueProvider<Map<String, Boolean>>() {
                  @Nullable
                  @Override
                  public Result<Map<String, Boolean>> compute() {
                    return new Result<Map<String, Boolean>>(
                        Collections.synchronizedMap(new HashMap<String, Boolean>()),
                        PsiModificationTracker.MODIFICATION_COUNT);
                  }
                });
    Boolean conflictingRef = cachedValue.get(fullyQualifiedName);
    if (conflictingRef != null) {
      return conflictingRef.booleanValue();
    }

    final ConflictingClassReferenceVisitor visitor =
        new ConflictingClassReferenceVisitor(fullyQualifiedName);
    element.accept(visitor);
    conflictingRef = visitor.isConflictingReferenceFound();
    cachedValue.put(fullyQualifiedName, conflictingRef);

    return conflictingRef.booleanValue();
  }
  public static GdkMethodHolder getHolderForClass(
      final PsiClass categoryClass, final boolean isStatic, final GlobalSearchScope scope) {
    final Project project = categoryClass.getProject();
    Key<CachedValue<GdkMethodHolder>> key = isStatic ? CACHED_STATIC : CACHED_NON_STATIC;
    return CachedValuesManager.getManager(project)
        .getCachedValue(
            categoryClass,
            key,
            new CachedValueProvider<GdkMethodHolder>() {
              @Override
              public Result<GdkMethodHolder> 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);
  }
예제 #3
0
 public static boolean hasTest(PsiModifierListOwner element) {
   return CachedValuesManager.getCachedValue(
       element,
       () ->
           CachedValueProvider.Result.create(
               hasTest(element, true), PsiModificationTracker.MODIFICATION_COUNT));
 }
예제 #4
0
 @Override
 @Nullable
 public PsiModifierList getAnnotationList() {
   if (myAnnotationList == null) {
     myAnnotationList =
         CachedValuesManager.getManager(myManager.getProject())
             .createCachedValue(new PackageAnnotationValueProvider());
   }
   return myAnnotationList.getValue();
 }
 @NotNull
 @Override
 public GrReflectedMethod[] getReflectedMethods() {
   return CachedValuesManager.getCachedValue(
       this,
       new CachedValueProvider<GrReflectedMethod[]>() {
         @Override
         public Result<GrReflectedMethod[]> compute() {
           return Result.create(
               GrReflectedMethodImpl.createReflectedMethods(GrMethodBaseImpl.this),
               PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
         }
       });
 }
예제 #6
0
 @NotNull
 public static PsiExpression getToplevelExpression(
     @NotNull final Project project, @NotNull final PsiExpression expression) {
   if (expression instanceof PsiBinaryExpression
       || expression.getParent() instanceof PsiBinaryExpression) { // can be large, cache
     return CachedValuesManager.getManager(project)
         .getParameterizedCachedValue(
             expression,
             TOP_LEVEL_EXPRESSION,
             TOP_LEVEL_PROVIDER,
             true,
             Pair.create(project, expression));
   }
   return getTopLevel(project, expression);
 }
 @NotNull
 private static ParameterizedCachedValue<MembersMap, PsiClass> getValues(
     @NotNull PsiClass aClass) {
   ParameterizedCachedValue<MembersMap, PsiClass> value = aClass.getUserData(MAP_IN_CLASS_KEY);
   if (value == null) {
     value =
         CachedValuesManager.getManager(aClass.getProject())
             .createParameterizedCachedValue(ByNameCachedValueProvider.INSTANCE, false);
     // Do not cache for nonphysical elements
     if (aClass.isPhysical()) {
       value = ((UserDataHolderEx) aClass).putUserDataIfAbsent(MAP_IN_CLASS_KEY, value);
     }
   }
   return value;
 }
  private CachedValue<ElementNames> createCachedValue(final PsiFile file) {
    return CachedValuesManager.getManager(file.getProject())
        .createCachedValue(
            new CachedValueProvider<ElementNames>() {
              public Result<ElementNames> compute() {
                final ElementNames names = new ElementNames();
                final PsiFile[] associations =
                    myFileAssociationsManager.getAssociationsFor(
                        file, FileAssociationsManager.XML_FILES);

                if (associations.length == 0) {
                  fillFromSchema(file, names);
                } else {
                  names.validateNames = true;
                  //noinspection unchecked
                  ContainerUtil.addAll(names.dependencies, associations);
                }
                //noinspection unchecked
                names.dependencies.add(myFileAssociationsManager);

                for (PsiFile file : associations) {
                  if (!(file instanceof XmlFile)) continue;
                  file.accept(
                      new XmlRecursiveElementVisitor() {
                        @Override
                        public void visitXmlTag(XmlTag tag) {
                          names.elementNames.add(QNameUtil.createQName(tag));
                          super.visitXmlTag(tag);
                        }

                        @Override
                        public void visitXmlAttribute(XmlAttribute attribute) {
                          if (!attribute.isNamespaceDeclaration()) {
                            names.attributeNames.add(QNameUtil.createQName(attribute));
                          }
                          super.visitXmlAttribute(attribute);
                        }
                      });
                }

                //noinspection unchecked
                return new Result<ElementNames>(names, ArrayUtil.toObjectArray(names.dependencies));
              }
            },
            false);
  }
 @NotNull
 public static PsiMethod[] getAllMethods(final GrTypeDefinition grType) {
   return CachedValuesManager.getCachedValue(
       grType,
       new CachedValueProvider<PsiMethod[]>() {
         @Nullable
         @Override
         public Result<PsiMethod[]> compute() {
           List<PsiMethod> list = ContainerUtil.newArrayList();
           getAllMethodsInner(grType, list, new HashSet<PsiClass>());
           return Result.create(
               list.toArray(new PsiMethod[list.size()]),
               PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT,
               grType);
         }
       });
 }
 private static Set<String> collectDevPatternClassNames(@NotNull final Project project) {
   CachedValue<Set<String>> cachedValue = project.getUserData(PATTERN_CLASSES);
   if (cachedValue == null) {
     cachedValue =
         CachedValuesManager.getManager(project)
             .createCachedValue(
                 new CachedValueProvider<Set<String>>() {
                   @Nullable
                   @Override
                   public Result<Set<String>> compute() {
                     return Result.create(
                         calcDevPatternClassNames(project),
                         PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
                   }
                 },
                 false);
     project.putUserData(PATTERN_CLASSES, cachedValue);
   }
   return cachedValue.getValue();
 }
예제 #11
0
 @NotNull
 private CachedValue<Collection<PsiDirectory>> createCachedDirectories(
     final boolean includeLibrarySources) {
   return CachedValuesManager.getManager(myManager.getProject())
       .createCachedValue(
           new CachedValueProvider<Collection<PsiDirectory>>() {
             @Override
             public Result<Collection<PsiDirectory>> compute() {
               final CommonProcessors.CollectProcessor<PsiDirectory> processor =
                   new CommonProcessors.CollectProcessor<PsiDirectory>();
               getFacade()
                   .processPackageDirectories(
                       PsiPackageImpl.this, allScope(), processor, includeLibrarySources);
               return Result.create(
                   processor.getResults(),
                   PsiPackageImplementationHelper.getInstance()
                       .getDirectoryCachedValueDependencies(PsiPackageImpl.this));
             }
           },
           false);
 }
 /**
  * Returns all annotations for <code>listOwner</code>, possibly walking up the method hierarchy.
  *
  * @see com.intellij.codeInsight.AnnotationUtil#isAnnotated(com.intellij.psi.PsiModifierListOwner,
  *     java.lang.String, boolean)
  */
 private static PsiAnnotation[] getAnnotations(
     @NotNull final PsiModifierListOwner listOwner, final boolean inHierarchy) {
   final PsiModifierList modifierList = listOwner.getModifierList();
   if (modifierList == null) {
     return PsiAnnotation.EMPTY_ARRAY;
   }
   if (!inHierarchy) {
     return modifierList.getAnnotations();
   }
   return CachedValuesManager.getCachedValue(
       listOwner,
       new CachedValueProvider<PsiAnnotation[]>() {
         @Nullable
         @Override
         public Result<PsiAnnotation[]> compute() {
           return Result.create(
               getHierarchyAnnotations(listOwner, modifierList),
               PsiModificationTracker.MODIFICATION_COUNT);
         }
       });
 }
예제 #13
0
  @NotNull
  public XmlTag[] getSubTags() {
    return CachedValuesManager.getManager(getProject())
        .getCachedValue(
            this,
            new CachedValueProvider<XmlTag[]>() {
              @Override
              public Result<XmlTag[]> compute() {
                final List<XmlTag> result = new ArrayList<XmlTag>();

                fillSubTags(result);

                final int s = result.size();
                XmlTag[] tags = s > 0 ? ContainerUtil.toArray(result, new XmlTag[s]) : EMPTY;
                return Result.create(
                    tags,
                    PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT,
                    getContainingFile());
              }
            });
  }
 @NotNull
 public static HierarchicalMethodSignature getHierarchicalMethodSignature(final PsiMethod method) {
   return CachedValuesManager.getCachedValue(
       method,
       new CachedValueProvider<HierarchicalMethodSignature>() {
         @Nullable
         @Override
         public Result<HierarchicalMethodSignature> compute() {
           PsiClass aClass = method.getContainingClass();
           HierarchicalMethodSignature result = null;
           if (aClass != null) {
             result = getSignaturesMap(aClass).get(method.getSignature(PsiSubstitutor.EMPTY));
           }
           if (result == null) {
             result =
                 new HierarchicalMethodSignatureImpl(
                     (MethodSignatureBackedByPsiMethod) method.getSignature(PsiSubstitutor.EMPTY));
           }
           return Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
         }
       });
 }
 @Override
 protected Collection<PsiDirectory> getAllDirectories() {
   if (myDirectories == null) {
     myDirectories =
         CachedValuesManager.getManager(myManager.getProject())
             .createCachedValue(
                 new CachedValueProvider<Collection<PsiDirectory>>() {
                   @Override
                   public Result<Collection<PsiDirectory>> compute() {
                     final CommonProcessors.CollectProcessor<PsiDirectory> processor =
                         new CommonProcessors.CollectProcessor<PsiDirectory>();
                     getFacade()
                         .processPackageDirectories(PsiPackageImpl.this, allScope(), processor);
                     return Result.create(
                         processor.getResults(),
                         PsiPackageImplementationHelper.getInstance()
                             .getDirectoryCachedValueDependencies(PsiPackageImpl.this));
                   }
                 },
                 false);
   }
   return myDirectories.getValue();
 }
예제 #16
0
  private Map<String, CachedValue<XmlNSDescriptor>> initializeSchema(
      final String namespace,
      final String version,
      final String fileLocation,
      Map<String, CachedValue<XmlNSDescriptor>> map) {
    if (map == null) map = new THashMap<String, CachedValue<XmlNSDescriptor>>();

    // We put cached value in any case to cause its value update on e.g. mapping change
    map.put(
        namespace,
        CachedValuesManager.getManager(getManager().getProject())
            .createCachedValue(
                new CachedValueProvider<XmlNSDescriptor>() {
                  public Result<XmlNSDescriptor> compute() {
                    XmlNSDescriptor descriptor = getImplicitNamespaceDescriptor(fileLocation);
                    if (descriptor != null) {
                      return new Result<XmlNSDescriptor>(
                          descriptor,
                          ArrayUtil.append(descriptor.getDependences(), XmlTagImpl.this));
                    }

                    XmlFile currentFile = retrieveFile(fileLocation, version);
                    if (currentFile == null) {
                      final XmlDocument document =
                          XmlUtil.getContainingFile(XmlTagImpl.this).getDocument();
                      if (document != null) {
                        final String uri = XmlUtil.getDtdUri(document);
                        if (uri != null) {
                          final XmlFile containingFile = XmlUtil.getContainingFile(document);
                          final XmlFile xmlFile = XmlUtil.findNamespace(containingFile, uri);
                          descriptor =
                              xmlFile == null
                                  ? null
                                  : (XmlNSDescriptor) xmlFile.getDocument().getMetaData();
                        }

                        // We want to get fixed xmlns attr from dtd and check its default with
                        // requested namespace
                        if (descriptor instanceof XmlNSDescriptorImpl) {
                          final XmlElementDescriptor elementDescriptor =
                              descriptor.getElementDescriptor(XmlTagImpl.this);
                          if (elementDescriptor != null) {
                            final XmlAttributeDescriptor attributeDescriptor =
                                elementDescriptor.getAttributeDescriptor("xmlns", XmlTagImpl.this);
                            if (attributeDescriptor != null && attributeDescriptor.isFixed()) {
                              final String defaultValue = attributeDescriptor.getDefaultValue();
                              if (defaultValue != null && defaultValue.equals(namespace)) {
                                return new Result<XmlNSDescriptor>(
                                    descriptor,
                                    descriptor.getDependences(),
                                    XmlTagImpl.this,
                                    ExternalResourceManager.getInstance());
                              }
                            }
                          }
                        }
                      }
                    }
                    PsiMetaOwner currentOwner = retrieveOwner(currentFile, namespace);
                    if (currentOwner != null) {
                      descriptor = (XmlNSDescriptor) currentOwner.getMetaData();
                      if (descriptor != null) {
                        return new Result<XmlNSDescriptor>(
                            descriptor,
                            descriptor.getDependences(),
                            XmlTagImpl.this,
                            ExternalResourceManager.getInstance());
                      }
                    }
                    return new Result<XmlNSDescriptor>(
                        null, XmlTagImpl.this, currentFile, ExternalResourceManager.getInstance());
                  }
                },
                false));

    return map;
  }
  static PsiSubstitutor infer(
      @NotNull PsiTypeParameter[] typeParameters,
      @NotNull PsiParameter[] parameters,
      @NotNull PsiExpression[] arguments,
      @NotNull PsiSubstitutor partialSubstitutor,
      @NotNull final PsiElement parent,
      @NotNull final ParameterTypeInferencePolicy policy) {
    if (parent instanceof PsiCall) {
      final PsiExpressionList argumentList = ((PsiCall) parent).getArgumentList();
      final MethodCandidateInfo.CurrentCandidateProperties properties =
          MethodCandidateInfo.getCurrentMethod(argumentList);
      // overload resolution can't depend on outer call => should not traverse to top
      if (properties != null
          && !properties.isApplicabilityCheck()
          &&
          // in order to to avoid caching of candidates's errors on parent (!) , so check for
          // overload resolution is left here
          // But overload resolution can depend on type of lambda parameter. As it can't depend on
          // lambda body,
          // traversing down would stop at lambda level and won't take into account overloaded
          // method
          !MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argumentList)) {
        final PsiCall topLevelCall =
            PsiResolveHelper.ourGraphGuard.doPreventingRecursion(
                parent,
                false,
                new Computable<PsiCall>() {
                  @Override
                  public PsiCall compute() {
                    if (parent instanceof PsiExpression
                        && !PsiPolyExpressionUtil.isPolyExpression((PsiExpression) parent)) {
                      return null;
                    }
                    return LambdaUtil.treeWalkUp(parent);
                  }
                });
        if (topLevelCall != null) {

          InferenceSession session;
          if (MethodCandidateInfo.isOverloadCheck()
              || !PsiDiamondType.ourDiamondGuard.currentStack().isEmpty()
              || LambdaUtil.isLambdaParameterCheck()) {
            session = startTopLevelInference(topLevelCall, policy);
          } else {
            session =
                CachedValuesManager.getCachedValue(
                    topLevelCall,
                    new CachedValueProvider<InferenceSession>() {
                      @Nullable
                      @Override
                      public Result<InferenceSession> compute() {
                        return new Result<InferenceSession>(
                            startTopLevelInference(topLevelCall, policy),
                            PsiModificationTracker.MODIFICATION_COUNT);
                      }
                    });

            if (session != null) {
              // reject cached top level session if it was based on wrong candidate: check nested
              // session if candidate (it's type parameters) are the same
              // such situations are avoided when overload resolution is performed
              // (MethodCandidateInfo.isOverloadCheck above)
              // but situations when client code iterates through
              // PsiResolveHelper.getReferencedMethodCandidates or similar are impossible to guess
              final Map<PsiElement, InferenceSession> sessions =
                  session.getInferenceSessionContainer().myNestedSessions;
              final InferenceSession childSession = sessions.get(parent);
              if (childSession != null) {
                for (PsiTypeParameter parameter : typeParameters) {
                  if (!childSession
                      .getInferenceSubstitution()
                      .getSubstitutionMap()
                      .containsKey(parameter)) {
                    session = startTopLevelInference(topLevelCall, policy);
                    break;
                  }
                }
              }
            }
          }

          if (session != null) {
            final PsiSubstitutor childSubstitutor =
                inferNested(
                    typeParameters,
                    parameters,
                    arguments,
                    partialSubstitutor,
                    (PsiCall) parent,
                    policy,
                    properties,
                    session);
            if (childSubstitutor != null) return childSubstitutor;
          } else if (topLevelCall instanceof PsiMethodCallExpression) {
            return new InferenceSession(
                    typeParameters, partialSubstitutor, parent.getManager(), parent, policy)
                .prepareSubstitution();
          }
        }
      }
    }

    final InferenceSession inferenceSession =
        new InferenceSession(
            typeParameters, partialSubstitutor, parent.getManager(), parent, policy);
    inferenceSession.initExpressionConstraints(parameters, arguments, parent);
    return inferenceSession.infer(parameters, arguments, parent);
  }
  private static MultiHostRegistrarImpl probeElementsUp(
      @NotNull PsiElement element, @NotNull PsiFile hostPsiFile, boolean probeUp) {
    PsiManager psiManager = hostPsiFile.getManager();
    final Project project = psiManager.getProject();
    InjectedLanguageManagerImpl injectedManager =
        InjectedLanguageManagerImpl.getInstanceImpl(project);
    if (injectedManager == null) {
      return null; // for tests
    }
    MultiHostRegistrarImpl registrar = null;
    PsiElement current = element;
    nextParent:
    while (current != null && current != hostPsiFile) {
      ProgressManager.checkCanceled();
      if ("EL".equals(current.getLanguage().getID())) break;
      ParameterizedCachedValue<MultiHostRegistrarImpl, PsiElement> data =
          current.getUserData(INJECTED_PSI);
      if (data == null) {
        registrar =
            InjectedPsiCachedValueProvider.doCompute(
                current, injectedManager, project, hostPsiFile);
      } else {
        registrar = data.getValue(current);
      }

      current = current.getParent(); // cache no injection for current

      if (registrar != null) {
        List<Pair<Place, PsiFile>> places = registrar.getResult();
        // check that injections found intersect with queried element
        TextRange elementRange = element.getTextRange();
        for (Pair<Place, PsiFile> pair : places) {
          Place place = pair.first;
          for (PsiLanguageInjectionHost.Shred shred : place) {
            if (shred.getHost().getTextRange().intersects(elementRange)) {
              if (place.isValid()) break nextParent;
            }
          }
        }
      }
      if (!probeUp) {
        break;
      }
    }

    if (probeUp) {
      // cache only if we walked all parents
      for (PsiElement e = element;
          e != current && e != null && e != hostPsiFile;
          e = e.getParent()) {
        ProgressManager.checkCanceled();
        if (registrar == null) {
          e.putUserData(INJECTED_PSI, null);
        } else {
          ParameterizedCachedValue<MultiHostRegistrarImpl, PsiElement> cachedValue =
              CachedValuesManager.getManager(project)
                  .createParameterizedCachedValue(INJECTED_PSI_PROVIDER, false);

          CachedValueProvider.Result<MultiHostRegistrarImpl> result =
              CachedValueProvider.Result.create(
                  registrar, PsiModificationTracker.MODIFICATION_COUNT, registrar);
          ((PsiParameterizedCachedValue<MultiHostRegistrarImpl, PsiElement>) cachedValue)
              .setValue(result);

          e.putUserData(INJECTED_PSI, cachedValue);
        }
      }
    }
    return registrar;
  }