private static void putInMap(
     PsiClass aClass,
     Map<MethodSignature, HierarchicalMethodSignature> result,
     Map<MethodSignature, HierarchicalMethodSignatureImpl> map,
     HierarchicalMethodSignature hierarchicalMethodSignature,
     MethodSignature signature) {
   if (!PsiUtil.isAccessible(
       aClass.getProject(), hierarchicalMethodSignature.getMethod(), aClass, aClass)) return;
   HierarchicalMethodSignatureImpl existing = map.get(signature);
   if (existing == null) {
     HierarchicalMethodSignatureImpl copy = copy(hierarchicalMethodSignature);
     LOG.assertTrue(copy.getMethod().isValid());
     map.put(signature, copy);
   } else if (isReturnTypeIsMoreSpecificThan(hierarchicalMethodSignature, existing)
       && isSuperMethod(aClass, hierarchicalMethodSignature, existing)) {
     HierarchicalMethodSignatureImpl newSuper = copy(hierarchicalMethodSignature);
     mergeSupers(newSuper, existing);
     LOG.assertTrue(newSuper.getMethod().isValid());
     map.put(signature, newSuper);
   } else if (isSuperMethod(aClass, existing, hierarchicalMethodSignature)) {
     mergeSupers(existing, hierarchicalMethodSignature);
   }
   // just drop an invalid method declaration there - to highlight accordingly
   else if (!result.containsKey(signature)) {
     LOG.assertTrue(hierarchicalMethodSignature.getMethod().isValid());
     result.put(signature, hierarchicalMethodSignature);
   }
 }
Пример #2
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();
  }
  private static PsiSubstitutor obtainFinalSubstitutor(
      PsiClass superClass,
      PsiSubstitutor superSubstitutor,
      PsiSubstitutor derivedSubstitutor,
      boolean inRawContext) {
    if (inRawContext) {
      Set<PsiTypeParameter> typeParams = superSubstitutor.getSubstitutionMap().keySet();
      PsiElementFactory factory = JavaPsiFacade.getElementFactory(superClass.getProject());
      superSubstitutor =
          factory.createRawSubstitutor(
              derivedSubstitutor, typeParams.toArray(new PsiTypeParameter[typeParams.size()]));
    }
    Map<PsiTypeParameter, PsiType> map = null;
    for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(superClass)) {
      PsiType type = superSubstitutor.substitute(typeParameter);
      final PsiType t = derivedSubstitutor.substitute(type);
      if (map == null) {
        map = new THashMap<PsiTypeParameter, PsiType>();
      }
      map.put(typeParameter, t);
    }

    return map == null
        ? PsiSubstitutor.EMPTY
        : JavaPsiFacade.getInstance(superClass.getProject())
            .getElementFactory()
            .createSubstitutor(map);
  }
  private static CompoundInitialState createState(InferenceSession topLevelSession) {
    final PsiSubstitutor topInferenceSubstitutor =
        replaceVariables(topLevelSession.getInferenceVariables());
    final Map<PsiElement, InitialInferenceState> nestedStates =
        new LinkedHashMap<PsiElement, InitialInferenceState>();

    final InferenceSessionContainer copy =
        new InferenceSessionContainer() {
          @Override
          public PsiSubstitutor findNestedSubstitutor(
              PsiElement arg, @Nullable PsiSubstitutor defaultSession) {
            // for the case foo(bar(a -> m())): top level inference won't touch lambda "a -> m()"
            // for the case foo(a -> bar(b -> m())): top level inference would go till nested lambda
            // "b -> m()" and the state from top level could be found here by "bar(b -> m())"
            // but proceeding with additional constraints from saved point would produce new
            // expression constraints with different inference variables (could be found in
            // myNestedSessions)
            // which won't be found in the system if we won't reject stored sessions in such cases
            final PsiSubstitutor substitutor = super.findNestedSubstitutor(arg, null);
            if (substitutor != null) {
              return substitutor;
            }

            final InitialInferenceState state =
                nestedStates.get(PsiTreeUtil.getParentOfType(arg, PsiCall.class));
            if (state != null) {
              return state.getInferenceSubstitutor();
            }
            return super.findNestedSubstitutor(arg, defaultSession);
          }
        };
    final Map<PsiElement, InferenceSession> nestedSessions =
        topLevelSession.getInferenceSessionContainer().myNestedSessions;
    for (Map.Entry<PsiElement, InferenceSession> entry : nestedSessions.entrySet()) {
      nestedStates.put(
          entry.getKey(),
          entry
              .getValue()
              .createInitialState(
                  copy, topLevelSession.getInferenceVariables(), topInferenceSubstitutor));
    }

    PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
    for (InferenceVariable variable : topLevelSession.getInferenceVariables()) {
      final PsiType instantiation = variable.getInstantiation();
      if (instantiation != PsiType.NULL) {
        final PsiClass psiClass =
            PsiUtil.resolveClassInClassTypeOnly(topInferenceSubstitutor.substitute(variable));
        if (psiClass instanceof InferenceVariable) {
          substitutor = substitutor.put((PsiTypeParameter) psiClass, instantiation);
        }
      }
    }

    return new CompoundInitialState(substitutor, nestedStates);
  }
Пример #5
0
 private void processInterface(PsiClass inheritor, PsiClass anInterface) {
   for (Iterator<PsiMethod> methodIterator = myRemainingMethods.iterator();
       methodIterator.hasNext(); ) {
     PsiMethod method = methodIterator.next();
     SiblingInfo info = findSibling(inheritor, anInterface, method);
     if (info != null) {
       myResult.put(method, info);
       methodIterator.remove();
     }
   }
 }
Пример #6
0
 @NotNull
 public Map<String, String> getLocalNamespaceDeclarations() {
   Map<String, String> namespaces = new THashMap<String, String>();
   for (final XmlAttribute attribute : getAttributes()) {
     if (!attribute.isNamespaceDeclaration() || attribute.getValue() == null) continue;
     // xmlns -> "", xmlns:a -> a
     final String localName = attribute.getLocalName();
     namespaces.put(localName.equals(attribute.getName()) ? "" : localName, attribute.getValue());
   }
   return namespaces;
 }
Пример #7
0
 private static boolean processAnnotationAttributes(
     @Nullable Map<String, Object> annotationAttributeValues, @NotNull PsiAnnotation annotation) {
   if (annotationAttributeValues != null) {
     final PsiAnnotationParameterList parameterList = annotation.getParameterList();
     final PsiNameValuePair[] attributes = parameterList.getAttributes();
     for (PsiNameValuePair attribute : attributes) {
       final String name = attribute.getName();
       if (annotationAttributeValues.containsKey(name)) {
         annotationAttributeValues.put(name, attribute.getValue());
       }
     }
   }
   return true;
 }
 private static PsiExpression getLiteralExpression(
     PsiExpression context, PsiManager manager, @NotNull String text) {
   Map<String, PsiExpression> cache = LITERAL_EXPRESSION_CACHE.get(manager);
   if (cache == null) {
     cache = new ConcurrentSoftValueHashMap<String, PsiExpression>();
     cache = manager.putUserDataIfAbsent(LITERAL_EXPRESSION_CACHE, cache);
   }
   PsiExpression expression = cache.get(text);
   if (expression == null) {
     expression =
         JavaPsiFacade.getElementFactory(manager.getProject())
             .createExpressionFromText(text, context);
     cache.put(text, expression);
   }
   return expression;
 }
  public FileIncludeManagerImpl(
      Project project,
      PsiManager psiManager,
      PsiFileFactory psiFileFactory,
      CachedValuesManager cachedValuesManager) {
    myProject = project;
    myPsiManager = psiManager;
    myPsiFileFactory = psiFileFactory;

    FileIncludeProvider[] providers = Extensions.getExtensions(FileIncludeProvider.EP_NAME);
    Map<String, FileIncludeProvider> providerMap =
        new HashMap<String, FileIncludeProvider>(providers.length);
    for (FileIncludeProvider provider : providers) {
      FileIncludeProvider old = providerMap.put(provider.getId(), provider);
      assert old == null;
    }
    myCachedValuesManager = cachedValuesManager;
  }
Пример #10
0
 private PsiClass[] getCachedClassInDumbMode(String name) {
   Map<String, PsiClass[]> map = SoftReference.dereference(myClassCache);
   if (map == null) {
     map = new HashMap<String, PsiClass[]>();
     for (PsiClass psiClass : getClasses(new EverythingGlobalScope(getProject()))) {
       String psiClassName = psiClass.getName();
       if (psiClassName != null) {
         PsiClass[] existing = map.get(psiClassName);
         map.put(
             psiClassName,
             existing == null ? new PsiClass[] {psiClass} : ArrayUtil.append(existing, psiClass));
       }
     }
     myClassCache = new SoftReference<Map<String, PsiClass[]>>(map);
   }
   PsiClass[] classes = map.get(name);
   return classes == null ? PsiClass.EMPTY_ARRAY : classes;
 }
Пример #11
0
  @NotNull
  private PsiClass[] getCachedClassesByName(@NotNull String name) {
    if (DumbService.getInstance(getProject()).isDumb()) {
      return getCachedClassInDumbMode(name);
    }

    Map<String, PsiClass[]> map = SoftReference.dereference(myClassCache);
    if (map == null) {
      myClassCache =
          new SoftReference<Map<String, PsiClass[]>>(
              map = new ConcurrentSoftValueHashMap<String, PsiClass[]>());
    }
    PsiClass[] classes = map.get(name);
    if (classes != null) {
      return classes;
    }

    final String qName = getQualifiedName();
    final String classQName = !qName.isEmpty() ? qName + "." + name : name;
    map.put(
        name,
        classes = getFacade().findClasses(classQName, new EverythingGlobalScope(getProject())));
    return classes;
  }
 public void registerNestedSession(InferenceSession session) {
   myNestedSessions.put(session.getContext(), session);
   myNestedSessions.putAll(session.getInferenceSessionContainer().myNestedSessions);
 }
  private static Map<MethodSignature, HierarchicalMethodSignature> buildMethodHierarchy(
      PsiClass aClass,
      PsiSubstitutor substitutor,
      final boolean includePrivates,
      final Set<PsiClass> visited,
      boolean isInRawContext) {
    Map<MethodSignature, HierarchicalMethodSignature> result =
        new LinkedHashMap<MethodSignature, HierarchicalMethodSignature>();
    final Map<MethodSignature, List<PsiMethod>> sameParameterErasureMethods =
        new THashMap<MethodSignature, List<PsiMethod>>(
            MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY);

    Map<MethodSignature, HierarchicalMethodSignatureImpl> map =
        new THashMap<MethodSignature, HierarchicalMethodSignatureImpl>(
            new TObjectHashingStrategy<MethodSignature>() {
              @Override
              public int computeHashCode(MethodSignature signature) {
                return MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY.computeHashCode(
                    signature);
              }

              @Override
              public boolean equals(MethodSignature o1, MethodSignature o2) {
                if (!MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY.equals(o1, o2))
                  return false;
                List<PsiMethod> list = sameParameterErasureMethods.get(o1);
                boolean toCheckReturnType = list != null && list.size() > 1;
                if (!toCheckReturnType) return true;
                PsiType returnType1 =
                    ((MethodSignatureBackedByPsiMethod) o1).getMethod().getReturnType();
                PsiType returnType2 =
                    ((MethodSignatureBackedByPsiMethod) o2).getMethod().getReturnType();
                if (returnType1 == null && returnType2 == null) return true;
                if (returnType1 == null || returnType2 == null) return false;

                PsiType erasure1 =
                    TypeConversionUtil.erasure(o1.getSubstitutor().substitute(returnType1));
                PsiType erasure2 =
                    TypeConversionUtil.erasure(o2.getSubstitutor().substitute(returnType2));
                return erasure1.equals(erasure2);
              }
            });

    for (PsiMethod method : aClass.getMethods()) {
      if (!method.isValid()) {
        throw new PsiInvalidElementAccessException(
            method, "class.valid=" + aClass.isValid() + "; name=" + method.getName());
      }
      if (!includePrivates && method.hasModifierProperty(PsiModifier.PRIVATE)) continue;
      final MethodSignatureBackedByPsiMethod signature =
          MethodSignatureBackedByPsiMethod.create(method, substitutor, isInRawContext);
      HierarchicalMethodSignatureImpl newH = new HierarchicalMethodSignatureImpl(signature);

      List<PsiMethod> list = sameParameterErasureMethods.get(signature);
      if (list == null) {
        list = new SmartList<PsiMethod>();
        sameParameterErasureMethods.put(signature, list);
      }
      list.add(method);

      LOG.assertTrue(newH.getMethod().isValid());
      result.put(signature, newH);
      map.put(signature, newH);
    }

    for (PsiClassType superType : aClass.getSuperTypes()) {
      PsiClassType.ClassResolveResult superTypeResolveResult = superType.resolveGenerics();
      PsiClass superClass = superTypeResolveResult.getElement();
      if (superClass == null) continue;
      if (!visited.add(superClass)) continue; // cyclic inheritance
      final PsiSubstitutor superSubstitutor = superTypeResolveResult.getSubstitutor();
      PsiSubstitutor finalSubstitutor =
          obtainFinalSubstitutor(superClass, superSubstitutor, substitutor, isInRawContext);

      final boolean isInRawContextSuper =
          (isInRawContext || PsiUtil.isRawSubstitutor(superClass, superSubstitutor))
              && superClass.getTypeParameters().length != 0;
      Map<MethodSignature, HierarchicalMethodSignature> superResult =
          buildMethodHierarchy(superClass, finalSubstitutor, false, visited, isInRawContextSuper);
      visited.remove(superClass);

      List<Pair<MethodSignature, HierarchicalMethodSignature>> flattened =
          new ArrayList<Pair<MethodSignature, HierarchicalMethodSignature>>();
      for (Map.Entry<MethodSignature, HierarchicalMethodSignature> entry : superResult.entrySet()) {
        HierarchicalMethodSignature hms = entry.getValue();
        MethodSignature signature = entry.getKey();
        PsiClass containingClass = hms.getMethod().getContainingClass();
        List<HierarchicalMethodSignature> supers =
            new ArrayList<HierarchicalMethodSignature>(hms.getSuperSignatures());
        for (HierarchicalMethodSignature aSuper : supers) {
          PsiClass superContainingClass = aSuper.getMethod().getContainingClass();
          if (containingClass != null
              && superContainingClass != null
              && !containingClass.isInheritor(superContainingClass, true)) {
            // methods must be inherited from unrelated classes, so flatten hierarchy here
            // class C implements SAM1, SAM2 { void methodimpl() {} }
            // hms.getSuperSignatures().remove(aSuper);
            flattened.add(
                new Pair<MethodSignature, HierarchicalMethodSignature>(signature, aSuper));
          }
        }
        putInMap(aClass, result, map, hms, signature);
      }
      for (Pair<MethodSignature, HierarchicalMethodSignature> pair : flattened) {
        putInMap(aClass, result, map, pair.second, pair.first);
      }
    }

    for (Map.Entry<MethodSignature, HierarchicalMethodSignatureImpl> entry : map.entrySet()) {
      HierarchicalMethodSignatureImpl hierarchicalMethodSignature = entry.getValue();
      MethodSignature methodSignature = entry.getKey();
      if (result.get(methodSignature) == null
          && PsiUtil.isAccessible(
              aClass.getProject(), hierarchicalMethodSignature.getMethod(), aClass, aClass)) {
        LOG.assertTrue(hierarchicalMethodSignature.getMethod().isValid());
        result.put(methodSignature, hierarchicalMethodSignature);
      }
    }

    return result;
  }
Пример #14
0
 protected void cacheOneAttributeValue(
     String name, String value, final Map<String, String> attributesValueMap) {
   attributesValueMap.put(name, value);
 }