@Override public void indexStub(@NotNull PsiClassReferenceListStub stub, @NotNull IndexSink sink) { PsiReferenceList.Role role = stub.getRole(); if (role == PsiReferenceList.Role.EXTENDS_LIST || role == PsiReferenceList.Role.IMPLEMENTS_LIST) { String[] names = stub.getReferencedNames(); for (String name : names) { String shortName = PsiNameHelper.getShortClassName(name); if (!StringUtil.isEmptyOrSpaces(shortName)) { sink.occurrence(JavaStubIndexKeys.SUPER_CLASSES, shortName); } } if (role == PsiReferenceList.Role.EXTENDS_LIST) { StubElement parentStub = stub.getParentStub(); if (parentStub instanceof PsiClassStub) { PsiClassStub psiClassStub = (PsiClassStub)parentStub; if (psiClassStub.isEnum()) { sink.occurrence(JavaStubIndexKeys.SUPER_CLASSES, "Enum"); } if (psiClassStub.isAnnotationType()) { sink.occurrence(JavaStubIndexKeys.SUPER_CLASSES, "Annotation"); } } } } }
@Override public void visitClass(@NotNull PsiClass aClass) { // no call to super, so it doesn't drill down final PsiReferenceList implementsList = aClass.getImplementsList(); if (implementsList == null) { return; } final PsiJavaCodeReferenceElement[] references = implementsList.getReferenceElements(); for (final PsiJavaCodeReferenceElement reference : references) { final PsiElement target = reference.resolve(); if (!(target instanceof PsiClass)) { return; } final PsiClass targetClass = (PsiClass)target; if (targetClass.isInterface() && interfaceContainsOnlyConstants(targetClass, new HashSet<PsiClass>())) { registerError(reference); } } }
@Override public boolean satisfiedBy(PsiElement element) { if (!(element instanceof PsiReferenceList)) { return false; } final PsiReferenceList throwsList = (PsiReferenceList)element; if (throwsList.getReferenceElements().length < 2) { return false; } final PsiElement parent = element.getParent(); if (!(parent instanceof PsiMethod)) { return false; } final PsiMethod method = (PsiMethod)parent; return method.getThrowsList().equals(element); }
@Override public void visitClass(@NotNull PsiClass aClass) { // no call to super, so it doesn't drill down final PsiReferenceList implementsList = aClass.getImplementsList(); if (implementsList == null) { return; } final PsiJavaCodeReferenceElement[] references = implementsList.getReferenceElements(); for (final PsiJavaCodeReferenceElement reference : references) { final PsiClass iface = (PsiClass)reference.resolve(); if (iface != null) { if (interfaceContainsOnlyConstants(iface, new HashSet<PsiClass>())) { registerError(reference); } } } }
private void checkReferenceList(PsiReferenceList referenceList, PsiClass containingClass) { if (referenceList == null) { return; } final PsiJavaCodeReferenceElement[] elements = referenceList.getReferenceElements(); for (final PsiJavaCodeReferenceElement element : elements) { final PsiElement referent = element.resolve(); if (!(referent instanceof PsiClass)) { continue; } final PsiClass psiClass = (PsiClass)referent; psiClass.isAnnotationType(); if (psiClass.isAnnotationType()) { registerError(element, containingClass); } } }
/** * Make the class implementing Parcelable */ private void makeClassImplementParcelable(PsiElementFactory elementFactory, JavaCodeStyleManager styleManager) { final PsiClassType[] implementsListTypes = psiClass.getImplementsListTypes(); final String implementsType = "android.os.Parcelable"; for (PsiClassType implementsListType : implementsListTypes) { PsiClass resolved = implementsListType.resolve(); // Already implements Parcelable, no need to add it if (resolved != null && implementsType.equals(resolved.getQualifiedName())) { return; } } PsiJavaCodeReferenceElement implementsReference = elementFactory.createReferenceFromText(implementsType, psiClass); PsiReferenceList implementsList = psiClass.getImplementsList(); if (implementsList != null) { styleManager.shortenClassReferences(implementsList.add(implementsReference)); } }
private void compareThrows(PsiReferenceList beforeThrows, PsiReferenceList afterThrows, PsiMethod psiMethod) { PsiClassType[] beforeTypes = beforeThrows.getReferencedTypes(); PsiClassType[] afterTypes = afterThrows.getReferencedTypes(); assertEquals("Throws counts are different for Method :" + psiMethod.getName(), beforeTypes.length, afterTypes.length); for (PsiClassType beforeType : beforeTypes) { boolean found = false; for (PsiClassType afterType : afterTypes) { if (beforeType.equals(afterType)) { found = true; break; } } assertTrue("Expected throw: " + beforeType.getClassName() + " not found on " + psiMethod.getName(), found); } }
public static void addSuperClass(@NotNull PsiClass targetClass, @NotNull PsiClass superClass, @NotNull Project project) { if (classHasDirectSuperClass(targetClass, superClass)) { return; } final PsiReferenceList psiReferenceList = targetClass.getExtendsList(); if (psiReferenceList == null) { return; } if (psiReferenceList.getReferenceElements().length != 0 && !targetClass.isInterface()) { final String message = "Multiple inheritance is not allowed. " + targetClass.getName() + " already contains a super class."; throw new IncorrectOperationException(message); } else { psiReferenceList.add(getElementFactory(project).createClassReferenceElement(superClass)); } }
@NotNull public static PsiReferenceList.Role elementTypeToRole(@NotNull IElementType type) { if(type == JavaStubElementTypes.EXTENDS_BOUND_LIST) { return PsiReferenceList.Role.EXTENDS_BOUNDS_LIST; } if(type == JavaStubElementTypes.EXTENDS_LIST) { return PsiReferenceList.Role.EXTENDS_LIST; } if(type == JavaStubElementTypes.IMPLEMENTS_LIST) { return PsiReferenceList.Role.IMPLEMENTS_LIST; } if(type == JavaStubElementTypes.THROWS_LIST) { return PsiReferenceList.Role.THROWS_LIST; } if(type == JavaStubElementTypes.PROVIDES_WITH_LIST) { return PsiReferenceList.Role.PROVIDES_WITH_LIST; } throw new RuntimeException("Unknown element type: " + type); }
@NotNull private static List<String> getImplementationNames(@NotNull List<PsiProvidesStatement> statements) { List<String> list = new ArrayList<>(); for(PsiProvidesStatement statement : statements) { PsiReferenceList implementationList = statement.getImplementationList(); if(implementationList == null) { continue; } for(PsiJavaCodeReferenceElement element : implementationList.getReferenceElements()) { ContainerUtil.addIfNotNull(list, element.getQualifiedName()); } } return list; }
@Nullable protected Preference getPreferredCondition(@NotNull final PsiElement position) { if(INSIDE_REFERENCE_LIST.accepts(position)) { PsiReferenceList list = (PsiReferenceList) position.getParent().getParent(); PsiReferenceList.Role role = list.getRole(); if(shouldContainInterfaces(list, role)) { return Preference.Interfaces; } if(role == PsiReferenceList.Role.EXTENDS_LIST) { return Preference.Classes; } if(role == PsiReferenceList.Role.THROWS_LIST) { return Preference.Exceptions; } } return null; }
@Override public void visitMethod(PsiMethod method) { super.visitMethod(method); if (!TestUtils.isJUnitTestMethod(method)) { return; } final PsiReferenceList throwsList = method.getThrowsList(); final PsiJavaCodeReferenceElement[] referenceElements = throwsList.getReferenceElements(); if (referenceElements.length < 2) { return; } final Query<PsiReference> query = MethodReferencesSearch.search(method); final PsiReference firstReference = query.findFirst(); if (firstReference != null) { return; } registerError(throwsList); }
private static PsiClass getBoundingType( PsiTypeParameter tp ) { PsiReferenceList extendsList = tp.getExtendsList(); PsiClassType[] referencedTypes = extendsList.getReferencedTypes(); if( referencedTypes.length > 0 ) { return referencedTypes[0].resolve(); } return ClassUtil.findPsiClass( tp.getManager(), Object.class.getName() ); }
@NotNull @Override public PsiClassReferenceListStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException { byte role = dataStream.readByte(); int len = dataStream.readVarInt(); StringRef[] names = StringRef.createArray(len); for (int i = 0; i < names.length; i++) { names[i] = dataStream.readName(); } PsiReferenceList.Role decodedRole = decodeRole(role); return new PsiClassReferenceListStubImpl(roleToElementType(decodedRole), parentStub, names, decodedRole); }
private static PsiReferenceList.Role elementTypeToRole(IElementType type) { if (type == JavaStubElementTypes.EXTENDS_BOUND_LIST) return PsiReferenceList.Role.EXTENDS_BOUNDS_LIST; else if (type == JavaStubElementTypes.EXTENDS_LIST) return PsiReferenceList.Role.EXTENDS_LIST; else if (type == JavaStubElementTypes.IMPLEMENTS_LIST) return PsiReferenceList.Role.IMPLEMENTS_LIST; else if (type == JavaStubElementTypes.THROWS_LIST) return PsiReferenceList.Role.THROWS_LIST; throw new RuntimeException("Unknown element type: " + type); }
private static JavaClassReferenceListElementType roleToElementType(PsiReferenceList.Role role) { switch (role) { case EXTENDS_BOUNDS_LIST: return JavaStubElementTypes.EXTENDS_BOUND_LIST; case EXTENDS_LIST: return JavaStubElementTypes.EXTENDS_LIST; case IMPLEMENTS_LIST: return JavaStubElementTypes.IMPLEMENTS_LIST; case THROWS_LIST: return JavaStubElementTypes.THROWS_LIST; } throw new RuntimeException("Unknown role: " + role); }
private static byte encodeRole(PsiReferenceList.Role role) { switch (role) { case EXTENDS_LIST: return 0; case IMPLEMENTS_LIST: return 1; case THROWS_LIST: return 2; case EXTENDS_BOUNDS_LIST: return 3; } throw new RuntimeException("Unknown role: " + role); }
private static PsiReferenceList.Role decodeRole(byte code) { switch (code) { case 0: return PsiReferenceList.Role.EXTENDS_LIST; case 1: return PsiReferenceList.Role.IMPLEMENTS_LIST; case 2: return PsiReferenceList.Role.THROWS_LIST; case 3: return PsiReferenceList.Role.EXTENDS_BOUNDS_LIST; } throw new RuntimeException("Unknown role code: " + code); }
public static void newReferenceList(JavaClassReferenceListElementType type, StubElement parent, String... types) { PsiReferenceList.Role role; if (type == JavaStubElementTypes.EXTENDS_LIST) role = PsiReferenceList.Role.EXTENDS_LIST; else if (type == JavaStubElementTypes.IMPLEMENTS_LIST) role = PsiReferenceList.Role.IMPLEMENTS_LIST; else if (type == JavaStubElementTypes.THROWS_LIST) role = PsiReferenceList.Role.THROWS_LIST; else if (type == JavaStubElementTypes.EXTENDS_BOUND_LIST) role = PsiReferenceList.Role.EXTENDS_BOUNDS_LIST; else throw new IllegalArgumentException("Unknown type: " + type); new PsiClassReferenceListStubImpl(type, parent, types, role); }
@Override public void visitMethod(@NotNull PsiMethod method) { // note: no call to super if (method.getNameIdentifier() == null) { return; } final PsiReferenceList throwList = method.getThrowsList(); final PsiJavaCodeReferenceElement[] thrownExceptions = throwList.getReferenceElements(); final int exceptionCount = thrownExceptions.length; if (exceptionCount <= getLimit()) { return; } registerMethodError(method, Integer.valueOf(exceptionCount)); }
@Override public void visitClass(@NotNull PsiClass aClass) { if (!PsiUtil.isLanguageLevel5OrHigher(aClass)) { return; } if (aClass.isAnnotationType()) { return; } final PsiReferenceList extendsList = aClass.getExtendsList(); checkReferenceList(extendsList, aClass); final PsiReferenceList implementsList = aClass.getImplementsList(); checkReferenceList(implementsList, aClass); }
@NotNull private <T extends PsiModifierListOwner & PsiNamedElement> PsiMethod generateDelegateMethod(@NotNull PsiClass psiClass, @NotNull T psiElement, @NotNull PsiAnnotation psiAnnotation, @NotNull PsiMethod psiMethod, @NotNull PsiSubstitutor psiSubstitutor) { final PsiType returnType = psiSubstitutor.substitute(psiMethod.getReturnType()); final LombokLightMethodBuilder methodBuilder = new LombokLightMethodBuilder(psiClass.getManager(), psiMethod.getName()) .withModifier(PsiModifier.PUBLIC) .withMethodReturnType(returnType) .withContainingClass(psiClass) //Have to go to original method, or some refactoring action will not work (like extract parameter oder change signature) .withNavigationElement(psiMethod); for (PsiTypeParameter typeParameter : psiMethod.getTypeParameters()) { methodBuilder.withTypeParameter(typeParameter); } final PsiReferenceList throwsList = psiMethod.getThrowsList(); for (PsiClassType psiClassType : throwsList.getReferencedTypes()) { methodBuilder.withException(psiClassType); } final PsiParameterList parameterList = psiMethod.getParameterList(); final PsiParameter[] psiParameters = parameterList.getParameters(); for (int parameterIndex = 0; parameterIndex < psiParameters.length; parameterIndex++) { final PsiParameter psiParameter = psiParameters[parameterIndex]; final PsiType psiParameterType = psiSubstitutor.substitute(psiParameter.getType()); final String generatedParameterName = StringUtils.defaultIfEmpty(psiParameter.getName(), "p" + parameterIndex); methodBuilder.withParameter(generatedParameterName, psiParameterType); } methodBuilder.withBody(createCodeBlock(psiClass, psiElement, psiMethod, returnType, psiParameters)); return methodBuilder; }
public LombokLightMethodBuilder(@NotNull PsiManager manager, @NotNull String name) { super(manager, JavaLanguage.INSTANCE, name, new LombokLightParameterListBuilder(manager, JavaLanguage.INSTANCE), new LombokLightModifierList(manager, JavaLanguage.INSTANCE), new LombokLightReferenceListBuilder(manager, JavaLanguage.INSTANCE, PsiReferenceList.Role.THROWS_LIST), new LightTypeParameterListBuilder(manager, JavaLanguage.INSTANCE)); setBaseIcon(LombokIcons.METHOD_ICON); }
private static boolean referenceListContainsClass(@NotNull PsiReferenceList psiReferenceList, @NotNull PsiClass aClass) { for (PsiJavaCodeReferenceElement element : psiReferenceList.getReferenceElements()) { if (element.getQualifiedName().equals(aClass.getQualifiedName())) { return true; } } return false; }
public static void addInterface(@NotNull PsiClass targetClass, @NotNull PsiClass interfaceClass, @NotNull Project project) { if (classHasDirectInterface(targetClass, interfaceClass)) { return; } final PsiReferenceList psiReferenceList = targetClass.getImplementsList(); if (psiReferenceList != null) { psiReferenceList.add(getElementFactory(project).createClassReferenceElement(interfaceClass)); } }
@Override public void indexStub(@NotNull PsiClassReferenceListStub stub, @NotNull IndexSink sink) { PsiReferenceList.Role role = stub.getRole(); if(role == PsiReferenceList.Role.EXTENDS_LIST || role == PsiReferenceList.Role.IMPLEMENTS_LIST) { String[] names = stub.getReferencedNames(); for(String name : names) { String shortName = PsiNameHelper.getShortClassName(name); if(!StringUtil.isEmptyOrSpaces(shortName)) { sink.occurrence(JavaStubIndexKeys.SUPER_CLASSES, shortName); } } if(role == PsiReferenceList.Role.EXTENDS_LIST) { StubElement parentStub = stub.getParentStub(); if(parentStub instanceof PsiClassStub) { PsiClassStub psiClassStub = (PsiClassStub) parentStub; if(psiClassStub.isEnum()) { sink.occurrence(JavaStubIndexKeys.SUPER_CLASSES, "Enum"); } if(psiClassStub.isAnnotationType()) { sink.occurrence(JavaStubIndexKeys.SUPER_CLASSES, "Annotation"); } } } } }
@Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { if (!(file instanceof PsiJavaFile)) return false; final PsiReference psiReference = TargetElementUtil.findReference(editor); if (psiReference == null) return false; final PsiReferenceList referenceList = PsiTreeUtil.getParentOfType(psiReference.getElement(), PsiReferenceList.class); if (referenceList == null) return false; final PsiClass psiClass = PsiTreeUtil.getParentOfType(referenceList, PsiClass.class); if (psiClass == null) return false; if (psiClass.getExtendsList() != referenceList && psiClass.getImplementsList() != referenceList) return false; PsiJavaCodeReferenceElement referenceElement = getTopLevelRef(psiReference, referenceList); if (referenceElement == null) return false; final PsiElement target = referenceElement.resolve(); if (target == null || !(target instanceof PsiClass)) return false; PsiClass targetClass = (PsiClass)target; if (targetClass.isInterface()) { myName = "Interface"; } else { myName = "Class"; } return true; }
@Nullable private static PsiJavaCodeReferenceElement getTopLevelRef(PsiReference psiReference, PsiReferenceList referenceList) { PsiElement element = psiReference.getElement(); while (element.getParent() != referenceList) { element = element.getParent(); if (element == null) return null; } if (!(element instanceof PsiJavaCodeReferenceElement)) return null; return (PsiJavaCodeReferenceElement)element; }
@Override public HighlightUsagesHandlerBase createHighlightUsagesHandler(final Editor editor, final PsiFile file) { int offset = TargetElementUtil.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset()); final PsiElement target = file.findElementAt(offset); if (target instanceof PsiKeyword && (PsiKeyword.EXTENDS.equals(target.getText()) || PsiKeyword.IMPLEMENTS.equals(target.getText()))) { PsiElement parent = target.getParent(); if (!(parent instanceof PsiReferenceList)) return null; PsiElement grand = parent.getParent(); if (!(grand instanceof PsiClass)) return null; return new HighlightOverridingMethodsHandler(editor, file, target, (PsiClass) grand); } return null; }