private static void bindReference(PsiFile psiFile, PsiField psiField, PsiClass containingClass, String fieldName, PsiReference reference, Project project) { if (reference instanceof PsiReferenceExpression) { PsiReferenceExpressionImpl.bindToElementViaStaticImport(containingClass, fieldName, ((PsiJavaFile)psiFile).getImportList()); final PsiElement qualifier = ((PsiReferenceExpression)reference).getQualifier(); if (qualifier != null) { final Boolean canRemoveQualifier = qualifier.getCopyableUserData(ChangeContextUtil.CAN_REMOVE_QUALIFIER_KEY); if (canRemoveQualifier != null && canRemoveQualifier.booleanValue()) { qualifier.delete(); } else { final PsiJavaCodeReferenceElement classReferenceElement = JavaPsiFacade.getElementFactory(project).createReferenceExpression(containingClass); qualifier.replace(classReferenceElement); } } } else if (reference.getElement() instanceof PsiDocMethodOrFieldRef){ reference.bindToElement(psiField); //todo refs through inheritors } }
private static boolean fromInflater(PsiReference reference) { if (reference instanceof PsiReferenceExpression) { PsiReferenceExpression referenceExpression = (PsiReferenceExpression) reference; PsiElement parent = referenceExpression.getParent(); if (parent instanceof PsiMethodCallExpression) { PsiMethodCallExpressionImpl methodCallExpression = (PsiMethodCallExpressionImpl) ((PsiReferenceExpressionImpl) reference).getParent(); PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); if (qualifierExpression != null) { PsiType psiType = qualifierExpression.getType(); if (psiType != null) { String canonicalText = psiType.getCanonicalText(); if ("android.view.LayoutInflater".equals(canonicalText)) { if ("inflate".equals(methodExpression.getReferenceName())) { return true; } } } } } } return false; }
@Nullable private JavaResolveResult resolveOptimised(@NotNull PsiJavaCodeReferenceElement ref) { try { if(ref instanceof PsiReferenceExpressionImpl) { PsiReferenceExpressionImpl.OurGenericsResolver resolver = PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE; JavaResolveResult[] results = JavaResolveUtil.resolveWithContainingFile(ref, resolver, true, true, myFile); return results.length == 1 ? results[0] : JavaResolveResult.EMPTY; } else { return ref.advancedResolve(true); } } catch(IndexNotReadyException e) { return null; } }
@Nullable private JavaResolveResult[] resolveOptimised(@NotNull PsiReferenceExpression expression) { try { if(expression instanceof PsiReferenceExpressionImpl) { PsiReferenceExpressionImpl.OurGenericsResolver resolver = PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE; return JavaResolveUtil.resolveWithContainingFile(expression, resolver, true, true, myFile); } else { return expression.multiResolve(true); } } catch(IndexNotReadyException e) { return null; } }
@NotNull private JavaResolveResult resolveOptimised(@NotNull PsiJavaCodeReferenceElement ref) { JavaResolveResult result; if (ref instanceof PsiReferenceExpressionImpl) { JavaResolveResult[] results = JavaResolveUtil.resolveWithContainingFile(ref, PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE, true, true, myFile); result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY; } else { result = ref.advancedResolve(true); } return result; }
@NotNull private JavaResolveResult[] resolveOptimised(@NotNull PsiReferenceExpression expression) { JavaResolveResult[] results; if (expression instanceof PsiReferenceExpressionImpl) { results = JavaResolveUtil.resolveWithContainingFile(expression, PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE, true, true, myFile); } else { results = expression.multiResolve(true); } return results; }
/** * Override to filter errors related to type incompatibilities arising from a * manifold extension adding an interface to an existing classpath class (as opposed * to a source file). Basically suppress "incompatible type errors" or similar * involving a structural interface extension. */ @Override public boolean accept( @NotNull HighlightInfo hi, @Nullable PsiFile file ) { if( hi.getDescription() == null || hi.getSeverity() != HighlightSeverity.ERROR || file == null ) { return true; } PsiElement firstElem = file.findElementAt( hi.getStartOffset() ); if( firstElem == null ) { return true; } PsiElement elem = firstElem.getParent(); if( elem == null ) { return true; } if( isInvalidStaticMethodOnInterface( hi ) ) { PsiElement lhsType = ((PsiReferenceExpressionImpl)((PsiMethodCallExpressionImpl)elem.getParent()).getMethodExpression().getQualifierExpression()).resolve(); if( lhsType instanceof ManifoldPsiClass || lhsType instanceof ManifoldExtendedPsiClass ) { PsiMethod psiMethod = ((PsiMethodCallExpressionImpl)elem.getParent()).resolveMethod(); if( psiMethod.getContainingClass().isInterface() ) { // ignore "Static method may be invoked on containing interface class only" errors where the method really is directly on a the interface, albeit the delegate return false; } } return true; } //## //## structural interface extensions cannot be added to the psiClass, so for now we suppress "incompatible type errors" or similar involving a structural interface extension. //## Boolean x = acceptInterfaceError( hi, firstElem, elem ); if( x != null ) return x; return true; }
@Nullable private static HighlightInfo checkReferenceToOurInstanceInsideThisOrSuper(@NotNull final PsiElement expression, @NotNull PsiClass referencedClass, final String resolvedName, @NotNull PsiFile containingFile) { if (PsiTreeUtil.getParentOfType(expression, PsiReferenceParameterList.class) != null) return null; PsiElement element = expression.getParent(); while (element != null) { // check if expression inside super()/this() call if (RefactoringChangeUtil.isSuperOrThisMethodCall(element)) { PsiElement parentClass = new PsiMatcherImpl(element) .parent(PsiMatchers.hasClass(PsiExpressionStatement.class)) .parent(PsiMatchers.hasClass(PsiCodeBlock.class)) .parent(PsiMatchers.hasClass(PsiMethod.class)) .dot(JavaMatchers.isConstructor(true)) .parent(PsiMatchers.hasClass(PsiClass.class)) .getElement(); if (parentClass == null) { return null; } // only this class/superclasses instance methods are not allowed to call PsiClass aClass = (PsiClass)parentClass; if (PsiUtil.isInnerClass(aClass) && referencedClass == aClass.getContainingClass()) return null; // field or method should be declared in this class or super if (!InheritanceUtil.isInheritorOrSelf(aClass, referencedClass, true)) return null; // and point to our instance if (expression instanceof PsiReferenceExpression && !thisOrSuperReference(((PsiReferenceExpression)expression).getQualifierExpression(), aClass)) { return null; } if (expression instanceof PsiJavaCodeReferenceElement && !aClass.equals(PsiTreeUtil.getParentOfType(expression, PsiClass.class)) && PsiTreeUtil.getParentOfType(expression, PsiTypeElement.class) != null) { return null; } if (expression instanceof PsiJavaCodeReferenceElement && PsiTreeUtil.getParentOfType(expression, PsiClassObjectAccessExpression.class) != null) { return null; } final HighlightInfo highlightInfo = createMemberReferencedError(resolvedName, expression.getTextRange()); if (expression instanceof PsiReferenceExpression && PsiUtil.isInnerClass(aClass)) { final String referenceName = ((PsiReferenceExpression)expression).getReferenceName(); final PsiClass containingClass = aClass.getContainingClass(); LOG.assertTrue(containingClass != null); final PsiField fieldInContainingClass = containingClass.findFieldByName(referenceName, true); if (fieldInContainingClass != null && ((PsiReferenceExpression)expression).getQualifierExpression() == null) { QuickFixAction.registerQuickFixAction(highlightInfo, new QualifyWithThisFix(containingClass, expression)); } } return highlightInfo; } if (element instanceof PsiReferenceExpression) { final PsiElement resolve; if (element instanceof PsiReferenceExpressionImpl) { PsiReferenceExpressionImpl referenceExpression = (PsiReferenceExpressionImpl)element; JavaResolveResult[] results = JavaResolveUtil .resolveWithContainingFile(referenceExpression, PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE, true, false, containingFile); resolve = results.length == 1 ? results[0].getElement() : null; } else { resolve = ((PsiReferenceExpression)element).resolve(); } if (resolve instanceof PsiField && ((PsiField)resolve).hasModifierProperty(PsiModifier.STATIC)) { return null; } } element = element.getParent(); if (element instanceof PsiClass && InheritanceUtil.isInheritorOrSelf((PsiClass)element, referencedClass, true)) return null; } return null; }
private PsiReferenceExpression getFileFromViewHolderInject(PsiExpression psiExpression) { SliceAnalysisParams sliceAnalysisParams = new SliceAnalysisParams(); sliceAnalysisParams.scope = new AnalysisScope(psiExpression.getProject()); sliceAnalysisParams.dataFlowToThis = true; SliceUsage sliceUsage = SliceUsage.createRootUsage(psiExpression, sliceAnalysisParams); ArrayList<SliceUsage> children = new ArrayList<SliceUsage>(); checkUsages(sliceUsage, children); for (SliceUsage child : children) { if (child.getElement() instanceof PsiLocalVariable) { PsiLocalVariable localVariable = (PsiLocalVariable) child.getElement(); Collection<PsiReference> search = ReferencesSearch.search(localVariable).findAll(); for (PsiReference psiReference : search) { if (psiReference instanceof CompositeElement) { CompositeElement treeParent = ((PsiReferenceExpressionImpl) psiReference).getTreeParent(); if (treeParent instanceof PsiAssignmentExpression) { PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) treeParent; PsiExpression rExpression = assignmentExpression.getRExpression(); if (rExpression instanceof PsiMethodCallExpression) { PsiMethodCallExpression expression = (PsiMethodCallExpression) rExpression; PsiReferenceExpression methodExpression = expression.getMethodExpression(); if (methodExpression.getQualifierExpression() != null) { PsiType type = methodExpression.getQualifierExpression().getType(); if (type != null) { if (type.getCanonicalText().equals("android.view.LayoutInflater")) { if ("inflate".equals(methodExpression.getReferenceName())) { PsiExpressionList argumentList = expression.getArgumentList(); PsiExpression layoutFile = argumentList.getExpressions()[0]; if (layoutFile instanceof PsiReferenceExpression) { return (PsiReferenceExpression) layoutFile; } } } } } } } } } } } return null; }
@Nullable private static HighlightInfo checkReferenceToOurInstanceInsideThisOrSuper(@NotNull final PsiElement expression, @NotNull PsiClass referencedClass, final String resolvedName, @NotNull PsiFile containingFile) { if (PsiTreeUtil.getParentOfType(expression, PsiReferenceParameterList.class) != null) return null; PsiElement element = expression.getParent(); while (element != null) { // check if expression inside super()/this() call if (RefactoringChangeUtil.isSuperOrThisMethodCall(element)) { PsiElement parentClass = new PsiMatcherImpl(element) .parent(PsiMatchers.hasClass(PsiExpressionStatement.class)) .parent(PsiMatchers.hasClass(PsiCodeBlock.class)) .parent(PsiMatchers.hasClass(PsiMethod.class)) .dot(JavaMatchers.isConstructor(true)) .parent(PsiMatchers.hasClass(PsiClass.class)) .getElement(); if (parentClass == null) { return null; } // only this class/superclasses instance methods are not allowed to call PsiClass aClass = (PsiClass)parentClass; if (PsiUtil.isInnerClass(aClass) && referencedClass == aClass.getContainingClass()) return null; // field or method should be declared in this class or super if (!InheritanceUtil.isInheritorOrSelf(aClass, referencedClass, true)) return null; // and point to our instance if (expression instanceof PsiReferenceExpression && !thisOrSuperReference(((PsiReferenceExpression)expression).getQualifierExpression(), aClass)) { return null; } if (expression instanceof PsiJavaCodeReferenceElement && !aClass.equals(PsiTreeUtil.getParentOfType(expression, PsiClass.class)) && PsiTreeUtil.getParentOfType(expression, PsiTypeElement.class) != null) { return null; } final HighlightInfo highlightInfo = createMemberReferencedError(resolvedName, expression.getTextRange()); if (expression instanceof PsiReferenceExpression && PsiUtil.isInnerClass(aClass)) { final String referenceName = ((PsiReferenceExpression)expression).getReferenceName(); final PsiClass containingClass = aClass.getContainingClass(); LOG.assertTrue(containingClass != null); final PsiField fieldInContainingClass = containingClass.findFieldByName(referenceName, true); if (fieldInContainingClass != null && ((PsiReferenceExpression)expression).getQualifierExpression() == null) { QuickFixAction.registerQuickFixAction(highlightInfo, new QualifyWithThisFix(containingClass, expression)); } } return highlightInfo; } if (element instanceof PsiReferenceExpression) { final PsiElement resolve; if (element instanceof PsiReferenceExpressionImpl) { PsiReferenceExpressionImpl referenceExpression = (PsiReferenceExpressionImpl)element; JavaResolveResult[] results = JavaResolveUtil .resolveWithContainingFile(referenceExpression, PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE, true, false, containingFile); resolve = results.length == 1 ? results[0].getElement() : null; } else { resolve = ((PsiReferenceExpression)element).resolve(); } if (resolve instanceof PsiField && ((PsiField)resolve).hasModifierProperty(PsiModifier.STATIC)) { return null; } } element = element.getParent(); if (element instanceof PsiClass && InheritanceUtil.isInheritorOrSelf((PsiClass)element, referencedClass, true)) return null; } return null; }