use of com.intellij.psi.javadoc.PsiInlineDocTag in project intellij-community by JetBrains.
the class GroovyMethodSignatureInsertHandler method handleInsert.
@Override
public void handleInsert(InsertionContext context, LookupElement item) {
if (!(item.getObject() instanceof PsiMethod)) {
return;
}
PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getEditor().getDocument());
final Editor editor = context.getEditor();
final PsiMethod method = (PsiMethod) item.getObject();
final PsiParameter[] parameters = method.getParameterList().getParameters();
final StringBuilder buffer = new StringBuilder();
final CharSequence chars = editor.getDocument().getCharsSequence();
int endOffset = editor.getCaretModel().getOffset();
final Project project = context.getProject();
int afterSharp = CharArrayUtil.shiftBackwardUntil(chars, endOffset - 1, "#") + 1;
int signatureOffset = afterSharp;
PsiElement element = context.getFile().findElementAt(signatureOffset - 1);
final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(element.getProject());
PsiDocTag tag = PsiTreeUtil.getParentOfType(element, PsiDocTag.class);
if (context.getCompletionChar() == Lookup.REPLACE_SELECT_CHAR) {
final PsiDocTagValue value = tag.getValueElement();
endOffset = value.getTextRange().getEndOffset();
}
editor.getDocument().deleteString(afterSharp, endOffset);
editor.getCaretModel().moveToOffset(signatureOffset);
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
editor.getSelectionModel().removeSelection();
buffer.append(method.getName()).append("(");
final int afterParenth = afterSharp + buffer.length();
for (int i = 0; i < parameters.length; i++) {
final PsiType type = TypeConversionUtil.erasure(parameters[i].getType());
buffer.append(type.getCanonicalText());
if (i < parameters.length - 1) {
buffer.append(",");
if (styleSettings.SPACE_AFTER_COMMA)
buffer.append(" ");
}
}
buffer.append(")");
if (!(tag instanceof PsiInlineDocTag)) {
buffer.append(" ");
} else {
final int currentOffset = editor.getCaretModel().getOffset();
if (chars.charAt(currentOffset) == '}') {
afterSharp++;
} else {
buffer.append("} ");
}
}
String insertString = buffer.toString();
EditorModificationUtil.insertStringAtCaret(editor, insertString);
editor.getCaretModel().moveToOffset(afterSharp + buffer.length());
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
shortenReferences(project, editor, context, afterParenth);
}
use of com.intellij.psi.javadoc.PsiInlineDocTag in project markdown-doclet by Abnaxos.
the class DocCommentProcessor method processDocComment.
/**
* Process the given `PsiDocComment` using Markdown and return a new `PsiDocComment`
* representing the resulting HTML. The resulting `PsiDocComment` can then be passed
* to IDEA's default QuickDoc implementation.
*
* @todo Error reporting ({@link com.sun.javadoc.DocErrorReporter} without {@link com.sun.javadoc.RootDoc}).
*
* @param docComment The `PsiDocComment` to process.
*
* @return A `PsiDocComment` representing the resulting HTML.
*/
public PsiDocComment processDocComment(PsiDocComment docComment) {
if (!isEnabled() || docComment == null) {
return docComment;
}
final Map<String, URL> umlDiagrams = generateUmlDiagrams(docComment);
Options options = new Options() {
@Override
protected ToHtmlSerializer createDocletSerializer() {
return new DocletSerializer(this, getLinkRenderer()) {
@Override
protected void printImageTag(LinkRenderer.Rendering rendering) {
URL diagram = umlDiagrams.get(rendering.href);
if (diagram != null) {
super.printImageTag(mapHref(rendering, diagram.toString()));
} else if (!ABSOLUTE_IMG_RE.matcher(rendering.href).matches() || rendering.href.contains("{@}")) {
URL baseUrl = VfsUtilCore.convertToURL(file.getVirtualFile().getUrl());
if (baseUrl != null) {
try {
super.printImageTag(mapHref(rendering, new URL(baseUrl, rendering.href).toString()));
} catch (MalformedURLException e) {
super.printImageTag(rendering);
}
}
} else {
super.printImageTag(rendering);
}
}
private LinkRenderer.Rendering mapHref(LinkRenderer.Rendering rendering, String newHref) {
LinkRenderer.Rendering mapped = new LinkRenderer.Rendering(newHref, rendering.text);
mapped.attributes.addAll(rendering.attributes);
return mapped;
}
};
}
};
PsiDocCommentOwner context = PsiTreeUtil.getParentOfType(docComment, PsiDocCommentOwner.class);
markdownOptions.applyTo(options);
MarkdownDoclet doclet = new MarkdownDoclet(options, null);
MarkdownTaglets.instance().setDocErrorReporter(doclet);
StringBuilder buf = new StringBuilder();
StringBuilder tagBlock = new StringBuilder();
boolean start = true;
// List<String> tagBlockInlineTags = new ArrayList<>();
for (PsiElement elem : docComment.getChildren()) {
if (elem instanceof PsiDocToken) {
IElementType tokenType = ((PsiDocToken) elem).getTokenType();
if (tokenType == JavaDocTokenType.DOC_COMMENT_START || tokenType == JavaDocTokenType.DOC_COMMENT_END) {
continue;
}
}
if (start && elem instanceof PsiWhiteSpace) {
continue;
} else if (elem instanceof PsiInlineDocTag) {
start = false;
if (tagBlock.length() == 0) {
// inlineTags.add(elem.getText());
buf.append(elem.getText());
} else {
// tagBlockInlineTags.add(elem.getText());
tagBlock.append(elem.getText());
}
} else if (elem instanceof PsiDocTag) {
PsiDocTag docTag = (PsiDocTag) elem;
switch(docTag.getName()) {
case "see":
tagBlock.append('\n');
renderSeeTag(doclet, tagBlock, docTag);
break;
case "param":
case "throws":
case "exception":
renderSimpleTag(doclet, tagBlock, docTag, true);
break;
case "return":
renderSimpleTag(doclet, tagBlock, docTag, false);
break;
case "todo":
renderTodoTag(doclet, tagBlock, docTag);
break;
default:
tagBlock.append('\n').append(stripLead(elem.getText()));
break;
}
} else {
start = false;
if (tagBlock.length() == 0) {
buf.append(elem.getText());
} else {
tagBlock.append(elem.getText());
}
}
}
String markdown = stripLead(buf.toString());
Plugin.print("Markdown source", markdown);
String docCommentText = "/**\n" + escapeAsterisks(doclet.toHtml(markdown, false)) + "\n" + escapeAsterisks(tagBlock.toString()) + "\n*/";
Plugin.print("Processed DocComment", docCommentText);
PsiDocComment processedDocComment = docCommentFromText(context, docCommentText);
LinkExpander linkExpander = new LinkExpander(context, processedDocComment, docCommentText);
processedDocComment = linkExpander.apply();
return processedDocComment;
}
use of com.intellij.psi.javadoc.PsiInlineDocTag in project markdown-doclet by Abnaxos.
the class DocCommentProcessor method generateUmlDiagrams.
/**
* Generates all PlantUML diagrams in the given `PsiDocComment`. It returns a Map of
* file names and the URLs where the image for that file has been saved to. Use this
* URL for the `<img>` tag.
*
* @param docComment The `PsiDocComment`.
*
* @return A map mapping the file names to the image URLs.
*
* @see TempFileManager#saveTempFile(byte[], String)
*/
private Map<String, URL> generateUmlDiagrams(PsiDocComment docComment) {
TempFileManager tempFiles = Plugin.tempFileManager();
Map<String, URL> urls = null;
for (PsiDocTag tag : docComment.getTags()) {
if (tag instanceof PsiInlineDocTag) {
continue;
} else if (tag.getName().equals("uml") || tag.getName().equals("startuml")) {
if (urls == null) {
urls = new HashMap<>();
}
String text = stripLead(tag.getText());
text = stripFirstWord(text)[1];
String[] stripped = stripFirstWord(text);
String fileName = stripped[0];
text = stripped[1];
String plantUml = "@startuml " + fileName + "\n" + "skinparam backgroundColor transparent\n" + text + "\n@enduml";
Plugin.print("UML Diagram Source", plantUml);
ByteArrayOutputStream image = new ByteArrayOutputStream();
try {
new SourceStringReader(plantUml).generateImage(image);
} catch (IOException e) {
LOG.error("Error generating UML", e, fileName, String.valueOf(docComment.toString()), String.valueOf(docComment.getContainingFile()));
}
try {
urls.put(fileName, tempFiles.saveTempFile(image.toByteArray(), "png"));
} catch (IOException e) {
LOG.error("Error generating UML", e, fileName, String.valueOf(docComment.toString()), String.valueOf(docComment.getContainingFile()));
}
}
}
return MoreObjects.firstNonNull(urls, Collections.<String, URL>emptyMap());
}
Aggregations