public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { if (isReferenceTo(element)) return getElement(); final String newName; if (element instanceof PsiClass) { PsiClass psiClass = (PsiClass) element; final boolean jvmFormat = Boolean.TRUE.equals(JavaClassReferenceProvider.JVM_FORMAT.getValue(getOptions())); newName = jvmFormat ? ClassUtil.getJVMClassName(psiClass) : psiClass.getQualifiedName(); } else if (element instanceof PsiPackage) { PsiPackage psiPackage = (PsiPackage) element; newName = psiPackage.getQualifiedName(); } else { throw new IncorrectOperationException("Cannot bind to " + element); } assert newName != null; TextRange range = new TextRange( myJavaClassReferenceSet.getReference(0).getRangeInElement().getStartOffset(), getRangeInElement().getEndOffset()); final ElementManipulator<PsiElement> manipulator = getManipulator(getElement()); if (manipulator != null) { final PsiElement finalElement = manipulator.handleContentChange(getElement(), range, newName); range = new TextRange(range.getStartOffset(), range.getStartOffset() + newName.length()); myJavaClassReferenceSet.reparse(finalElement, range); return finalElement; } return element; }
public JavaClassReference( final JavaClassReferenceSet referenceSet, TextRange range, int index, String text, final boolean staticImport) { super(referenceSet.getProvider()); myInStaticImport = staticImport; LOG.assertTrue(range.getEndOffset() <= referenceSet.getElement().getTextLength()); myIndex = index; myRange = range; myText = text; myJavaClassReferenceSet = referenceSet; }
private boolean isStaticClassReference(final String s, boolean strict) { if (myIndex == 0) { return false; } char c = s.charAt(getRangeInElement().getStartOffset() - 1); return myJavaClassReferenceSet.isStaticSeparator(c, strict); }
private JavaResolveResult advancedResolveInner(final PsiElement psiElement, final String qName) { final PsiManager manager = psiElement.getManager(); final GlobalSearchScope scope = getScope(); if (myIndex == myJavaClassReferenceSet.getReferences().length - 1) { final PsiClass aClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(qName, scope); if (aClass != null) { return new ClassCandidateInfo(aClass, PsiSubstitutor.EMPTY, false, psiElement); } else { if (!JavaClassReferenceProvider.ADVANCED_RESOLVE.getBooleanValue(getOptions())) { return JavaResolveResult.EMPTY; } } } PsiElement resolveResult = JavaPsiFacade.getInstance(manager.getProject()).findPackage(qName); if (resolveResult == null) { resolveResult = JavaPsiFacade.getInstance(manager.getProject()).findClass(qName, scope); } if (myInStaticImport && resolveResult == null) { resolveResult = resolveMember(qName, manager, getElement().getResolveScope()); } if (resolveResult == null) { PsiFile containingFile = psiElement.getContainingFile(); if (containingFile instanceof PsiJavaFile) { if (containingFile instanceof JspFile) { containingFile = containingFile.getViewProvider().getPsi(StdLanguages.JAVA); if (containingFile == null) return JavaResolveResult.EMPTY; } final ClassResolverProcessor processor = new ClassResolverProcessor(getCanonicalText(), psiElement); containingFile.processDeclarations(processor, ResolveState.initial(), null, psiElement); if (processor.getResult().length == 1) { final JavaResolveResult javaResolveResult = processor.getResult()[0]; if (javaResolveResult != JavaResolveResult.EMPTY && getOptions() != null) { final Boolean value = JavaClassReferenceProvider.RESOLVE_QUALIFIED_CLASS_NAME.getValue(getOptions()); final PsiClass psiClass = (PsiClass) javaResolveResult.getElement(); if (value != null && value.booleanValue() && psiClass != null) { final String qualifiedName = psiClass.getQualifiedName(); if (!qName.equals(qualifiedName)) { return JavaResolveResult.EMPTY; } } } return javaResolveResult; } } } return resolveResult != null ? new CandidateInfo(resolveResult, PsiSubstitutor.EMPTY, false, false, psiElement) : JavaResolveResult.EMPTY; }
private GlobalSearchScope getScope() { final GlobalSearchScope scope = myJavaClassReferenceSet.getProvider().getScope(); if (scope == null) { final Module module = ModuleUtil.findModuleForPsiElement(getElement()); if (module != null) { return module.getModuleWithDependenciesAndLibrariesScope(true); } return GlobalSearchScope.allScope(getElement().getProject()); } return scope; }
private JavaResolveResult doAdvancedResolve() { final PsiElement psiElement = getElement(); if (!psiElement.isValid()) return JavaResolveResult.EMPTY; final String elementText = psiElement.getText(); final PsiElement context = getContext(); if (context instanceof PsiClass) { if (isStaticClassReference(elementText, false)) { final PsiClass psiClass = ((PsiClass) context).findInnerClassByName(getCanonicalText(), false); if (psiClass != null) return new ClassCandidateInfo(psiClass, PsiSubstitutor.EMPTY, false, psiElement); PsiElement member = doResolveMember((PsiClass) context, myText); return member == null ? JavaResolveResult.EMPTY : new CandidateInfo(member, PsiSubstitutor.EMPTY, false, false, psiElement); } else if (!myInStaticImport && myJavaClassReferenceSet.isAllowDollarInNames()) { return JavaResolveResult.EMPTY; } } final int endOffset = getRangeInElement().getEndOffset(); LOG.assertTrue(endOffset <= elementText.length(), elementText); final int startOffset = myJavaClassReferenceSet.getReference(0).getRangeInElement().getStartOffset(); final String qName = elementText.substring(startOffset, endOffset); if (!qName.contains(".")) { final String defaultPackage = JavaClassReferenceProvider.DEFAULT_PACKAGE.getValue(getOptions()); if (StringUtil.isNotEmpty(defaultPackage)) { final JavaResolveResult resolveResult = advancedResolveInner(psiElement, defaultPackage + "." + qName); if (resolveResult != JavaResolveResult.EMPTY) { return resolveResult; } } } return advancedResolveInner(psiElement, qName); }
@NotNull private Object[] getSubclassVariants( @NotNull PsiPackage context, @NotNull String[] extendClasses) { HashSet<Object> lookups = new HashSet<Object>(); GlobalSearchScope packageScope = PackageScope.packageScope(context, true); GlobalSearchScope scope = myJavaClassReferenceSet.getProvider().getScope(); if (scope != null) { packageScope = packageScope.intersectWith(scope); } final GlobalSearchScope allScope = ProjectScope.getAllScope(context.getProject()); final boolean instantiatable = JavaClassReferenceProvider.INSTANTIATABLE.getBooleanValue(getOptions()); final boolean notInterface = JavaClassReferenceProvider.NOT_INTERFACE.getBooleanValue(getOptions()); final boolean notEnum = JavaClassReferenceProvider.NOT_ENUM.getBooleanValue(getOptions()); final boolean concrete = JavaClassReferenceProvider.CONCRETE.getBooleanValue(getOptions()); final ClassKind classKind = getClassKind(); for (String extendClassName : extendClasses) { final PsiClass extendClass = JavaPsiFacade.getInstance(context.getProject()).findClass(extendClassName, allScope); if (extendClass != null) { // add itself if (packageScope.contains(extendClass.getContainingFile().getVirtualFile())) { if (isClassAccepted( extendClass, classKind, instantiatable, concrete, notInterface, notEnum)) { ContainerUtil.addIfNotNull(createSubclassLookupValue(context, extendClass), lookups); } } for (final PsiClass clazz : ClassInheritorsSearch.search(extendClass, packageScope, true)) { if (isClassAccepted(clazz, classKind, instantiatable, concrete, notInterface, notEnum)) { ContainerUtil.addIfNotNull(createSubclassLookupValue(context, clazz), lookups); } } } } return lookups.toArray(); }
public String getUnresolvedMessagePattern() { return myJavaClassReferenceSet.getUnresolvedMessagePattern(myIndex); }
@Nullable private Map<CustomizableReferenceProvider.CustomizationKey, Object> getOptions() { return myJavaClassReferenceSet.getOptions(); }
public boolean isSoft() { return myJavaClassReferenceSet.isSoft(); }
public PsiElement getElement() { return myJavaClassReferenceSet.getElement(); }
private boolean canReferencePackage() { return myJavaClassReferenceSet.canReferencePackage(myIndex); }
@Nullable public PsiReference getContextReference() { return myIndex > 0 ? myJavaClassReferenceSet.getReference(myIndex - 1) : null; }