[javadoc] PsiSnippetAttributeList#getAttribute; inject plain text for unknown lang attribute

GitOrigin-RevId: 014ed5a2388084a20c53c9ff506dd7f9c4a8d322
This commit is contained in:
Tagir Valeev
2023-03-10 10:50:40 +01:00
committed by intellij-monorepo-bot
parent d7ac37c2f9
commit a69a85af47
5 changed files with 54 additions and 33 deletions

View File

@@ -1817,31 +1817,35 @@ public class JavaDocInfoGenerator {
return;
}
PsiSnippetDocTagBody body = value.getBody();
PsiSnippetAttribute[] attributes = value.getAttributeList().getAttributes();
PsiSnippetAttribute regionAttribute = ContainerUtil.find(attributes, attr -> attr.getName().equals(PsiSnippetAttribute.REGION_ATTRIBUTE));
PsiSnippetAttributeList list = value.getAttributeList();
PsiSnippetAttribute regionAttribute = list.getAttribute(PsiSnippetAttribute.REGION_ATTRIBUTE);
String region = regionAttribute == null || regionAttribute.getValue() == null ? null :
regionAttribute.getValue().getValue();
if (body != null) {
buffer.append("<pre>");
List<Pair<PsiElement, TextRange>> files = InjectedLanguageManager.getInstance(snippetTag.getProject()).getInjectedPsiFiles(snippetTag);
PsiElement element = files != null ? files.get(0).first : null;
buffer.append("<pre>");
generateSnippetBody(buffer, element != null ? element : body, region);
buffer.append("</pre>");
} else {
for (PsiSnippetAttribute attribute : attributes) {
PsiSnippetAttributeValue attrValue = attribute.getValue();
PsiSnippetAttribute refAttribute = list.getAttribute(PsiSnippetAttribute.CLASS_ATTRIBUTE);
if (refAttribute == null) {
refAttribute = list.getAttribute(PsiSnippetAttribute.FILE_ATTRIBUTE);
}
if (refAttribute != null) {
PsiSnippetAttributeValue attrValue = refAttribute.getValue();
if (attrValue != null) {
PsiReference ref = attrValue.getReference();
if (ref != null) {
PsiElement resolved = ref.resolve();
if (resolved instanceof PsiFile file) {
buffer.append("<pre>");
generateSnippetBody(buffer, file, region);
buffer.append("</pre>");
} else {
buffer.append(getSpanForUnresolvedItem()).append(JavaBundle.message("javadoc.snippet.not.found", attrValue.getValue()))
.append("</span>");
}
PsiElement resolved = ref == null ? null : ref.resolve();
if (resolved instanceof PsiFile file) {
buffer.append("<pre>");
generateSnippetBody(buffer, file, region);
buffer.append("</pre>");
}
else {
buffer.append(getSpanForUnresolvedItem()).append(JavaBundle.message("javadoc.snippet.not.found",
attrValue.getValue()))
.append("</span>");
}
}
}

View File

@@ -5,14 +5,12 @@ import com.intellij.lang.Language;
import com.intellij.lang.injection.MultiHostInjector;
import com.intellij.lang.injection.MultiHostRegistrar;
import com.intellij.lang.java.JShellLanguage;
import com.intellij.openapi.fileTypes.PlainTextLanguage;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.source.javadoc.PsiSnippetDocTagImpl;
import com.intellij.psi.impl.source.javadoc.SnippetDocTagManipulator;
import com.intellij.psi.javadoc.PsiSnippetAttribute;
import com.intellij.psi.javadoc.PsiSnippetAttributeList;
import com.intellij.psi.javadoc.PsiSnippetDocTag;
import com.intellij.psi.javadoc.PsiSnippetDocTagValue;
import com.intellij.psi.javadoc.*;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -44,24 +42,24 @@ public class JavadocInjector implements MultiHostInjector {
if (valueElement == null) return JShellLanguage.INSTANCE;
final PsiSnippetAttributeList attributeList = valueElement.getAttributeList();
for (PsiSnippetAttribute attribute : attributeList.getAttributes()) {
if (!PsiSnippetAttribute.LANG_ATTRIBUTE.equals(attribute.getName())) continue;
final PsiElement langValue = attribute.getValue();
if (langValue == null) break;
final String langValueText = stripPossibleLeadingAndTrailingQuotes(langValue);
PsiSnippetAttribute attribute = attributeList.getAttribute(PsiSnippetAttribute.LANG_ATTRIBUTE);
if (attribute == null) {
return JShellLanguage.INSTANCE;
}
final PsiSnippetAttributeValue langValue = attribute.getValue();
if (langValue != null) {
String langValueText = langValue.getValue();
if ("java".equalsIgnoreCase(langValueText)) {
return JShellLanguage.INSTANCE;
}
final Language language = findRegisteredLanguage(langValueText);
if (language == null) break;
return language;
if (language != null) {
return language;
}
}
return JShellLanguage.INSTANCE;
return PlainTextLanguage.INSTANCE;
}
private static @Nullable Language findRegisteredLanguage(@NotNull String langValueText) {

View File

@@ -1,9 +1,10 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.psi.javadoc;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* List of attributes (for example {@code file} or {@code class}) of a given doc tag.
@@ -16,4 +17,10 @@ public interface PsiSnippetAttributeList extends PsiElement {
* @return array of name-value pairs of snippet tag.
*/
PsiSnippetAttribute @NotNull [] getAttributes();
/**
* @param name name of the attribute to find
* @return the first instance of attribute having a given name; null if no such attribute found
*/
@Nullable PsiSnippetAttribute getAttribute(@NotNull String name);
}

View File

@@ -1,7 +1,8 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.psi.impl.source.javadoc;
import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.impl.source.tree.CompositePsiElement;
import com.intellij.psi.impl.source.tree.JavaDocElementType;
@@ -9,6 +10,7 @@ import com.intellij.psi.javadoc.PsiSnippetAttribute;
import com.intellij.psi.javadoc.PsiSnippetAttributeList;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PsiSnippetAttributeListImpl extends CompositePsiElement implements PsiSnippetAttributeList {
public PsiSnippetAttributeListImpl() {
@@ -33,6 +35,16 @@ public class PsiSnippetAttributeListImpl extends CompositePsiElement implements
return children;
}
@Override
public @Nullable PsiSnippetAttribute getAttribute(@NotNull String name) {
for (PsiElement child = getFirstChild(); child != null; child = child.getNextSibling()) {
if (child instanceof PsiSnippetAttribute && ((PsiSnippetAttribute)child).getName().equals(name)) {
return (PsiSnippetAttribute)child;
}
}
return null;
}
@Override
public String toString() {
return "PsiSnippetAttributeList";

View File

@@ -1,4 +1,4 @@
// "JShellLanguage" "true"
// "TEXT" "true"
/**
* {@snippet<caret> lang=_NONEXISTING_LANGUAGE_: