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); }
/** * @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 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); } }
private static void fillFromSchema(PsiFile file, ElementNames names) { if (!(file instanceof XmlFile)) return; final XmlFile f = (XmlFile) file; final XmlDocument d = f.getDocument(); if (d == null) return; final XmlTag rootTag = d.getRootTag(); if (rootTag == null) return; //noinspection unchecked names.dependencies.add(new NSDeclTracker(rootTag)); try { final Map<String, String> namespaceDeclarations = rootTag.getLocalNamespaceDeclarations(); final Collection<String> prefixes = namespaceDeclarations.keySet(); //noinspection unchecked final Set<XmlElementDescriptor> history = new THashSet<XmlElementDescriptor>(); final XmlElementFactory ef = XmlElementFactory.getInstance(file.getProject()); int noSchemaNamespaces = 0; for (String prefix : prefixes) { final String namespace = namespaceDeclarations.get(prefix); if (isIgnoredNamespace(prefix, namespace)) continue; final XmlTag tag = ef.createTagFromText("<dummy-tag xmlns='" + namespace + "' />", XMLLanguage.INSTANCE); final XmlDocument document = PsiTreeUtil.getParentOfType(tag, XmlDocument.class); final XmlNSDescriptor rootDescriptor = tag.getNSDescriptor(tag.getNamespace(), true); if (rootDescriptor == null || (rootDescriptor instanceof XmlNSDescriptorImpl && ((XmlNSDescriptorImpl) rootDescriptor).getTag() == null) || !rootDescriptor.getDeclaration().isPhysical()) { final QName any = QNameUtil.createAnyLocalName(namespace); names.elementNames.add(any); names.attributeNames.add(any); noSchemaNamespaces++; continue; } //noinspection unchecked names.dependencies.add(rootDescriptor.getDescriptorFile()); final XmlElementDescriptor[] e = rootDescriptor.getRootElementsDescriptors(document); for (XmlElementDescriptor descriptor : e) { processElementDescriptors(descriptor, tag, names, history); } } names.validateNames = names.elementNames.size() > noSchemaNamespaces; // final QName any = QNameUtil.createAnyLocalName(""); // names.elementNames.add(any); // names.attributeNames.add(any); } catch (IncorrectOperationException e) { Logger.getInstance(XsltContextProvider.class.getName()).error(e); } }
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); }
public static PsiField[] getAllFields(GrTypeDefinition grType) { Map<String, CandidateInfo> fieldsMap = CollectClassMembersUtil.getAllFields(grType); return ContainerUtil.map2Array( fieldsMap.values(), PsiField.class, new Function<CandidateInfo, PsiField>() { public PsiField fun(CandidateInfo entry) { return (PsiField) entry.getElement(); } }); }
@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; }
public String getAttributeValue(String qname) { // todo ? Map<String, String> map = myAttributeValueMap; while (map == null) { getAttributes(); map = myAttributeValueMap; if (map == null) { myAttributes = null; } } return map.get(qname); }
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; }
@Nullable public static PsiClass findInnerClassByName( GrTypeDefinition grType, String name, boolean checkBases) { if (!checkBases) { for (PsiClass inner : grType.getInnerClasses()) { if (name.equals(inner.getName())) return inner; } return null; } else { Map<String, CandidateInfo> innerClasses = CollectClassMembersUtil.getAllInnerClasses(grType, true); final CandidateInfo info = innerClasses.get(name); return info == null ? null : (PsiClass) info.getElement(); } }
// uses hierarchy signature tree if available, traverses class structure by itself otherwise public static boolean processDirectSuperMethodsSmart( @NotNull PsiMethod method, @NotNull Processor<PsiMethod> superMethodProcessor) { // boolean old = PsiSuperMethodUtil.isSuperMethod(method, superMethod); PsiClass aClass = method.getContainingClass(); if (aClass == null) return false; if (!canHaveSuperMethod(method, true, false)) return false; Map<MethodSignature, HierarchicalMethodSignature> cachedMap = SIGNATURES_KEY.getCachedValueOrNull(aClass); if (cachedMap != null) { HierarchicalMethodSignature signature = cachedMap.get(method.getSignature(PsiSubstitutor.EMPTY)); if (signature != null) { List<HierarchicalMethodSignature> superSignatures = signature.getSuperSignatures(); for (HierarchicalMethodSignature superSignature : superSignatures) { if (!superMethodProcessor.process(superSignature.getMethod())) return false; } return true; } } PsiClassType[] directSupers = aClass.getSuperTypes(); for (PsiClassType directSuper : directSupers) { PsiClassType.ClassResolveResult resolveResult = directSuper.resolveGenerics(); if (resolveResult.getSubstitutor() != PsiSubstitutor.EMPTY) { // generics break; } PsiClass directSuperClass = resolveResult.getElement(); if (directSuperClass == null) continue; PsiMethod[] candidates = directSuperClass.findMethodsBySignature(method, false); for (PsiMethod candidate : candidates) { if (PsiUtil.canBeOverriden(candidate)) { if (!superMethodProcessor.process(candidate)) return false; } } return true; } List<HierarchicalMethodSignature> superSignatures = method.getHierarchicalMethodSignature().getSuperSignatures(); for (HierarchicalMethodSignature superSignature : superSignatures) { if (!superMethodProcessor.process(superSignature.getMethod())) return false; } return true; }
@Contract("_, !null -> !null") public PsiSubstitutor findNestedSubstitutor( PsiElement arg, @Nullable PsiSubstitutor defaultSession) { InferenceSession session = myNestedSessions.get(PsiTreeUtil.getParentOfType(arg, PsiCall.class)); return session == null ? defaultSession : session.getInferenceSubstitution(); }
@Nullable public static PsiField findFieldByName( GrTypeDefinition grType, String name, boolean checkBases, boolean includeSynthetic) { if (!checkBases) { for (PsiField field : CollectClassMembersUtil.getFields(grType, includeSynthetic)) { if (name.equals(field.getName())) return field; } return null; } Map<String, CandidateInfo> fieldsMap = CollectClassMembersUtil.getAllFields(grType, includeSynthetic); final CandidateInfo info = fieldsMap.get(name); return info == null ? null : (PsiField) info.getElement(); }
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; }
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 static Map<PsiMethod, SiblingInfo> getSiblingInheritanceInfos( @NotNull final Collection<PsiMethod> methods) { MultiMap<PsiClass, PsiMethod> byClass = MultiMap.create(); for (PsiMethod method : methods) { PsiClass containingClass = method.getContainingClass(); if (canHaveSiblingSuper(method, containingClass)) { byClass.putValue(containingClass, method); } } Map<PsiMethod, SiblingInfo> result = new HashMap<>(); for (PsiClass psiClass : byClass.keySet()) { SiblingInheritorSearcher searcher = new SiblingInheritorSearcher(byClass.get(psiClass), psiClass); ClassInheritorsSearch.search(psiClass, psiClass.getUseScope(), true, true, false) .forEach(searcher); result.putAll(searcher.getResult()); } return result; }
@Override public PsiFileSystemItem resolveFileInclude(final FileIncludeInfo info, final PsiFile context) { if (true) return doResolve(info, context); Map<String, PsiFileSystemItem> value = myCachedValuesManager.getCachedValue( context, RESOLVE_CACHE_KEY, new CachedValueProvider<Map<String, PsiFileSystemItem>>() { @Override public Result<Map<String, PsiFileSystemItem>> compute() { Map<String, PsiFileSystemItem> map = new FactoryMap<String, PsiFileSystemItem>() { @Override protected PsiFileSystemItem create(String key) { return doResolve(info, context); } }; return Result.create(map, context, VirtualFileManager.getInstance()); } }, false); return value.get(info.path); }
@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; }
@Nullable private PyType analyzeCallType( @Nullable PyType type, @Nullable PyExpression receiver, @NotNull Map<PyExpression, PyNamedParameter> parameters, @NotNull TypeEvalContext context) { if (PyTypeChecker.hasGenerics(type, context)) { final Map<PyGenericType, PyType> substitutions = PyTypeChecker.unifyGenericCall(receiver, parameters, context); if (substitutions != null) { type = PyTypeChecker.substitute(type, substitutions, context); } else { type = null; } } if (receiver != null) { type = replaceSelf(type, receiver, context); } if (type != null && isDynamicallyEvaluated(parameters.values(), context)) { type = PyUnionType.createWeakType(type); } return type; }
protected void cacheOneAttributeValue( String name, String value, final Map<String, String> attributesValueMap) { attributesValueMap.put(name, value); }
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; }
public static boolean processDeclarations( @NotNull GrTypeDefinition grType, @NotNull PsiScopeProcessor processor, @NotNull ResolveState state, @Nullable PsiElement lastParent, @NotNull PsiElement place) { if (place instanceof GrCodeReferenceElement && lastParent instanceof GrModifierList) { final PsiElement possibleAnnotation = PsiTreeUtil.skipParentsOfType(place, GrCodeReferenceElement.class); if (possibleAnnotation instanceof GrAnnotation && possibleAnnotation.getParent() == lastParent) { return true; // don't process class members while resolving annotation which annotates // current class } } for (final PsiTypeParameter typeParameter : grType.getTypeParameters()) { if (!processElement(processor, typeParameter, state)) return false; } NameHint nameHint = processor.getHint(NameHint.KEY); String name = nameHint == null ? null : nameHint.getName(state); ClassHint classHint = processor.getHint(ClassHint.KEY); final PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY); final PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getProject()); boolean processInstanceMethods = (shouldProcessMethods(classHint) || shouldProcessProperties(classHint)) && shouldProcessInstanceMembers(grType, lastParent); LanguageLevel level = PsiUtil.getLanguageLevel(place); if (shouldProcessProperties(classHint)) { Map<String, CandidateInfo> fieldsMap = CollectClassMembersUtil.getAllFields(grType); if (name != null) { CandidateInfo fieldInfo = fieldsMap.get(name); if (fieldInfo != null) { if (!processField( grType, processor, state, place, processInstanceMethods, substitutor, factory, level, fieldInfo)) { return false; } } else if (grType.isTrait() && lastParent != null) { PsiField field = findFieldByName(grType, name, false, true); if (field != null && field.hasModifierProperty(PsiModifier.PUBLIC)) { if (!processField( grType, processor, state, place, processInstanceMethods, substitutor, factory, level, new CandidateInfo(field, PsiSubstitutor.EMPTY))) { return false; } } } } else { for (CandidateInfo info : fieldsMap.values()) { if (!processField( grType, processor, state, place, processInstanceMethods, substitutor, factory, level, info)) { return false; } } if (grType.isTrait() && lastParent != null) { for (PsiField field : CollectClassMembersUtil.getFields(grType, true)) { if (field.hasModifierProperty(PsiModifier.PUBLIC)) { if (!processField( grType, processor, state, place, processInstanceMethods, substitutor, factory, level, new CandidateInfo(field, PsiSubstitutor.EMPTY))) { return false; } } } } } } if (shouldProcessMethods(classHint)) { Map<String, List<CandidateInfo>> methodsMap = CollectClassMembersUtil.getAllMethods(grType, true); boolean isPlaceGroovy = place.getLanguage() == GroovyFileType.GROOVY_LANGUAGE; if (name == null) { for (List<CandidateInfo> list : methodsMap.values()) { for (CandidateInfo info : list) { if (!processMethod( grType, processor, state, place, processInstanceMethods, substitutor, factory, level, isPlaceGroovy, info)) { return false; } } } } else { List<CandidateInfo> byName = methodsMap.get(name); if (byName != null) { for (CandidateInfo info : byName) { if (!processMethod( grType, processor, state, place, processInstanceMethods, substitutor, factory, level, isPlaceGroovy, info)) { return false; } } } } } final GrTypeDefinitionBody body = grType.getBody(); if (body != null) { if (shouldProcessClasses(classHint)) { for (PsiClass innerClass : getInnerClassesForResolve(grType, lastParent, place)) { final String innerClassName = innerClass.getName(); if (nameHint != null && !innerClassName.equals(nameHint.getName(state))) { continue; } if (!processor.execute(innerClass, state)) { return false; } } } } return true; }
public static Collection<HierarchicalMethodSignature> getVisibleSignatures(PsiClass aClass) { Map<MethodSignature, HierarchicalMethodSignature> map = getSignaturesMap(aClass); return map.values(); }
// uses hierarchy signature tree if available, traverses class structure by itself otherwise public static boolean isSuperMethodSmart( @NotNull PsiMethod method, @NotNull PsiMethod superMethod) { // boolean old = PsiSuperMethodUtil.isSuperMethod(method, superMethod); if (method == superMethod) return false; PsiClass aClass = method.getContainingClass(); PsiClass superClass = superMethod.getContainingClass(); if (aClass == null || superClass == null || superClass == aClass) return false; if (!canHaveSuperMethod(method, true, false)) return false; PsiMethod[] superMethods = null; Map<MethodSignature, HierarchicalMethodSignature> cachedMap = SIGNATURES_KEY.getCachedValueOrNull(aClass); if (cachedMap != null) { HierarchicalMethodSignature signature = cachedMap.get(method.getSignature(PsiSubstitutor.EMPTY)); if (signature != null) { superMethods = MethodSignatureUtil.convertMethodSignaturesToMethods(signature.getSuperSignatures()); } } if (superMethods == null) { PsiClassType[] directSupers = aClass.getSuperTypes(); List<PsiMethod> found = null; boolean canceled = false; for (PsiClassType directSuper : directSupers) { PsiClassType.ClassResolveResult resolveResult = directSuper.resolveGenerics(); if (resolveResult.getSubstitutor() != PsiSubstitutor.EMPTY) { // generics canceled = true; break; } PsiClass directSuperClass = resolveResult.getElement(); if (directSuperClass == null) continue; PsiMethod[] candidates = directSuperClass.findMethodsBySignature(method, false); if (candidates.length != 0) { if (found == null) found = new ArrayList<PsiMethod>(); for (PsiMethod candidate : candidates) { if (PsiUtil.canBeOverriden(candidate)) found.add(candidate); } } } superMethods = canceled ? null : found == null ? PsiMethod.EMPTY_ARRAY : found.toArray(new PsiMethod[found.size()]); } if (superMethods == null) { superMethods = MethodSignatureUtil.convertMethodSignaturesToMethods( method.getHierarchicalMethodSignature().getSuperSignatures()); } for (PsiMethod superCandidate : superMethods) { if (superMethod.equals(superCandidate) || isSuperMethodSmart(superCandidate, superMethod)) return true; } return false; }
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); }
public void registerNestedSession(InferenceSession session) { myNestedSessions.put(session.getContext(), session); myNestedSessions.putAll(session.getInferenceSessionContainer().myNestedSessions); }