Rename jet -> kotlin in idea
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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 org.jetbrains.kotlin.idea;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.intellij.lang.documentation.AbstractDocumentationProvider;
|
||||
import com.intellij.lang.java.JavaDocumentationProvider;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.asJava.KotlinLightMethod;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
||||
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens;
|
||||
import org.jetbrains.kotlin.kdoc.psi.api.KDoc;
|
||||
import org.jetbrains.kotlin.psi.JetDeclaration;
|
||||
import org.jetbrains.kotlin.psi.JetPackageDirective;
|
||||
import org.jetbrains.kotlin.psi.JetReferenceExpression;
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
|
||||
public class JetQuickDocumentationProvider extends AbstractDocumentationProvider {
|
||||
private static final Predicate<PsiElement> SKIP_WHITESPACE_AND_EMPTY_PACKAGE = new Predicate<PsiElement>() {
|
||||
@Override
|
||||
public boolean apply(PsiElement input) {
|
||||
// Skip empty package because there can be comments before it
|
||||
// Skip whitespaces
|
||||
return (input instanceof JetPackageDirective && input.getChildren().length == 0) || input instanceof PsiWhiteSpace;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) {
|
||||
return getText(element, originalElement, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateDoc(PsiElement element, PsiElement originalElement) {
|
||||
return getText(element, originalElement, false);
|
||||
}
|
||||
|
||||
private static String getText(PsiElement element, PsiElement originalElement, boolean quickNavigation) {
|
||||
if (element instanceof JetDeclaration) {
|
||||
return renderKotlinDeclaration((JetDeclaration) element, quickNavigation);
|
||||
}
|
||||
else if (element instanceof KotlinLightMethod) {
|
||||
return renderKotlinDeclaration(((KotlinLightMethod) element).getOrigin(), quickNavigation);
|
||||
}
|
||||
|
||||
if (quickNavigation) {
|
||||
JetReferenceExpression referenceExpression = PsiTreeUtil.getParentOfType(originalElement, JetReferenceExpression.class, false);
|
||||
if (referenceExpression != null) {
|
||||
BindingContext context = ResolvePackage.analyze(referenceExpression);
|
||||
DeclarationDescriptor declarationDescriptor = context.get(BindingContext.REFERENCE_TARGET, referenceExpression);
|
||||
if (declarationDescriptor != null) {
|
||||
return mixKotlinToJava(declarationDescriptor, element, originalElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This element was resolved to non-kotlin element, it will be rendered with own provider
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String renderKotlinDeclaration(JetDeclaration declaration, boolean quickNavigation) {
|
||||
BindingContext context = ResolvePackage.analyze(declaration);
|
||||
DeclarationDescriptor declarationDescriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration);
|
||||
|
||||
assert declarationDescriptor != null;
|
||||
|
||||
String renderedDecl = DescriptorRenderer.HTML_NAMES_WITH_SHORT_TYPES.render(declarationDescriptor);
|
||||
if (!quickNavigation) {
|
||||
renderedDecl = "<pre>" + DescriptorRenderer.HTML_NAMES_WITH_SHORT_TYPES.render(declarationDescriptor) + "</pre>";
|
||||
}
|
||||
|
||||
PsiElement navigationElement = declaration.getNavigationElement();
|
||||
if (navigationElement instanceof JetDeclaration) {
|
||||
declaration = (JetDeclaration) navigationElement;
|
||||
}
|
||||
KDoc comment = declaration.getDocComment();
|
||||
if (comment != null) {
|
||||
renderedDecl = renderedDecl + "<br/>" + kDocToHtml(comment);
|
||||
}
|
||||
|
||||
return renderedDecl;
|
||||
}
|
||||
|
||||
private static String mixKotlinToJava(
|
||||
@NotNull DeclarationDescriptor declarationDescriptor,
|
||||
PsiElement element, PsiElement originalElement
|
||||
) {
|
||||
String originalInfo = new JavaDocumentationProvider().getQuickNavigateInfo(element, originalElement);
|
||||
if (originalInfo != null) {
|
||||
String renderedDecl = DescriptorRenderer.HTML_NAMES_WITH_SHORT_TYPES.render(declarationDescriptor);
|
||||
return renderedDecl + "<br/>Java declaration:<br/>" + originalInfo;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getKDocContent(@NotNull KDoc kDoc) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
boolean contentStarted = false;
|
||||
boolean afterAsterisk = false;
|
||||
|
||||
for (PsiElement element : kDoc.getChildren()) {
|
||||
IElementType type = element.getNode().getElementType();
|
||||
|
||||
if (KDocTokens.CONTENT_TOKENS.contains(type)) {
|
||||
contentStarted = true;
|
||||
builder.append(afterAsterisk ? StringUtil.trimLeading(element.getText()) : element.getText());
|
||||
afterAsterisk = false;
|
||||
}
|
||||
|
||||
if (type == KDocTokens.LEADING_ASTERISK || type == KDocTokens.START) {
|
||||
afterAsterisk = true;
|
||||
}
|
||||
|
||||
if (contentStarted && element instanceof PsiWhiteSpace) {
|
||||
builder.append(StringUtil.repeat("\n", StringUtil.countNewLines(element.getText())));
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static String kDocToHtml(@NotNull KDoc comment) {
|
||||
// TODO: Parse and show markdown comments as html
|
||||
String content = getKDocContent(comment);
|
||||
String htmlContent = StringUtil.replace(content, "\n", "<br/>")
|
||||
.replaceAll("(@param)\\s+(\\w+)", "@param - <i>$2</i>")
|
||||
.replaceAll("(@\\w+)", "<b>$1</b>");
|
||||
|
||||
return "<p>" + htmlContent + "</p>";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user