[javadoc] ability to provide delegate to copy javadoc from

This commit is contained in:
Daniil Ovchinnikov
2016-06-28 15:43:50 +03:00
parent 8cd5ca7a39
commit ec94c66cc9
4 changed files with 151 additions and 7 deletions
@@ -0,0 +1,69 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.javadoc;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiDocCommentOwner;
import com.intellij.psi.PsiMember;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class DocumentationDelegateProvider {
public static final ExtensionPointName<DocumentationDelegateProvider> EP_NAME = ExtensionPointName.create(
"com.intellij.documentationDelegateProvider"
);
/**
* <p>
* Computes PsiDocCommentOwner to get documentation from.
* </p>
* <p>
* Suppose there is a <code>Foo#bar()</code> with doc and <code>Baz#bar()</code> without doc:
* <pre>
* class Foo {
* /**
* * Some javadoc
* *&#47;
* void bar() {}
* }
* class Baz {
* void bar() {}
* }
* </pre>
* If it is needed to display doc from <code>Foo#bar()</code> when doc for <code>Baz#bar()</code> is queried
* then this method should return PsiMethod corresponding to <code>Foo#bar()</code> for PsiMethod corresponding to <code>Baz#bar()</code>.
* <br>
* The copied documentation will include <i>Description copied from</i> link.
* </p>
*
* @param member method to search delegate for.
* @return delegate PsiDocCommentOwner instance.
*/
@Nullable
public abstract PsiDocCommentOwner computeDocumentationDelegate(@NotNull PsiMember member);
@Nullable
public static PsiDocCommentOwner findDocumentationDelegate(@NotNull PsiMember method) {
for (DocumentationDelegateProvider delegator : EP_NAME.getExtensions()) {
PsiDocCommentOwner type = delegator.computeDocumentationDelegate(method);
if (type != null) {
return type;
}
}
return null;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -2223,9 +2223,14 @@ public class JavaDocInfoGenerator {
if (aClass == null) {
return null;
}
Pair<T, InheritDocProvider<T>> delegate = findInheritDocTagInDelegate(aMethod, loc);
if (delegate != null) {
return delegate;
}
if (aClass instanceof PsiAnonymousClass) {
return searchDocTagInSupers(new PsiClassType[] {((PsiAnonymousClass)aClass).getBaseClassType()}, aMethod, loc, visitedClasses);
return searchDocTagInSupers(new PsiClassType[]{((PsiAnonymousClass)aClass).getBaseClassType()}, aMethod, loc, visitedClasses);
}
PsiClassType[] implementsTypes = aClass.getImplementsListTypes();
@@ -2239,14 +2244,44 @@ public class JavaDocInfoGenerator {
return searchDocTagInSupers(extendsTypes, aMethod, loc, visitedClasses);
}
@Nullable private <T> Pair<T, InheritDocProvider<T>> findInheritDocTag(PsiMethod method, DocTagLocator<T> loc) {
PsiClass aClass = method.getContainingClass();
@Nullable
private <T> Pair<T, InheritDocProvider<T>> findInheritDocTagInDelegate(PsiMethod method, DocTagLocator<T> loc) {
PsiMethod delegateMethod = findDelegateMethod(method);
if (delegateMethod == null) return null;
PsiClass containingClass = delegateMethod.getContainingClass();
if (containingClass == null) return null;
T tag = loc.find(delegateMethod, getDocComment(delegateMethod));
if (tag == null) return null;
return Pair.create(tag, new InheritDocProvider<T>() {
@Override
public Pair<T, InheritDocProvider<T>> getInheritDoc() {
return findInheritDocTag(delegateMethod, loc);
}
@Override
public PsiClass getElement() {
return containingClass;
}
});
}
@Nullable
private static PsiMethod findDelegateMethod(@NotNull PsiMethod method) {
PsiDocCommentOwner delegate = DocumentationDelegateProvider.findDocumentationDelegate(method);
return delegate instanceof PsiMethod ? (PsiMethod)delegate : null;
}
@Nullable
private <T> Pair<T, InheritDocProvider<T>> findInheritDocTag(PsiMethod method, DocTagLocator<T> loc) {
PsiClass aClass = method.getContainingClass();
if (aClass == null) return null;
return findInheritDocTagInClass(method, aClass, loc, new HashSet<PsiClass>());
}
private static class ParamInfo {
private final String name;
private final PsiDocTag docTag;