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); } }
/** * @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); }
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(); } } }
@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; }
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; }
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; }
@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; }
protected void cacheOneAttributeValue( String name, String value, final Map<String, String> attributesValueMap) { attributesValueMap.put(name, value); }