package net.king2500.plugins.PhpAdvancedAutoComplete; import com.intellij.lang.Language; import com.intellij.lang.documentation.DocumentationProviderEx; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager; import com.intellij.psi.impl.light.LightElement; import com.jetbrains.php.lang.psi.PhpPsiUtil; import com.jetbrains.php.lang.psi.elements.FunctionReference; import com.jetbrains.php.lang.psi.elements.Statement; import io.netty.util.internal.StringUtil; import net.king2500.plugins.PhpAdvancedAutoComplete.utils.PhpElementsUtil; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * @author Thomas Schulz <[email protected]> */ public class PhpFormatDocumentationProvider extends DocumentationProviderEx { private static final String PHP_FORMAT_URL = "https://www.php.net/manual/en/function.{functionName}.php"; @Override public @Nullable List<String> getUrlFor(PsiElement element, PsiElement originalElement) { if (!(element instanceof FormatTokenDocElement)) { return null; } String functionName = ((FormatTokenDocElement)element).getFunctionName(); return Collections.singletonList(PHP_FORMAT_URL.replace("{functionName}", functionName)); } @Override public @Nullable String generateDoc(PsiElement element, @Nullable PsiElement originalElement) { if (!(element instanceof FormatTokenDocElement)) { return null; } String tokenText = ((FormatTokenDocElement)element).getTokenText(); String functionName = ((FormatTokenDocElement)element).getFunctionName(); if (Arrays.asList(PhpCompletionTokens.scanFormatFuncs).contains(functionName + ":1")) { return PhpCompletionTokens.scanFormatTokensDoc.getOrDefault(tokenText, ""); } else { return PhpCompletionTokens.formatTokensDoc.getOrDefault(tokenText, ""); } } @Override public @Nullable PsiElement getDocumentationElementForLookupItem(PsiManager psiManager, Object object, PsiElement psiElement) { if (!(object instanceof String)) { return null; } String fqn = getCallToFormatFunc(psiElement); if (StringUtil.isNullOrEmpty(fqn)) { return null; } String tokenText = (String)object; if ("%%".equals(tokenText)) { tokenText = "%"; } else if (!"%".equals(tokenText)) { tokenText = StringUtils.strip((String)object, "%"); } String functionName = StringUtils.strip(fqn, "\\"); return new FormatTokenDocElement(psiManager, psiElement.getLanguage(), tokenText, functionName); } private String getCallToFormatFunc(PsiElement psiElement) { FunctionReference function = PhpPsiUtil.getParentByCondition(psiElement, true, FunctionReference.INSTANCEOF, Statement.INSTANCEOF); if (function == null) { return null; } return PhpElementsUtil.resolveFqn(function); } private static class FormatTokenDocElement extends LightElement { private final String tokenText; private final String functionName; protected FormatTokenDocElement(@NotNull final PsiManager manager, @NotNull final Language language, @NotNull final String tokenText, @NotNull final String functionName) { super(manager, language); this.tokenText = tokenText; this.functionName = functionName; } public String getTokenText() { return tokenText; } @Override public String getText() { return functionName; } public String getFunctionName() { return functionName; } @Override public String toString() { return "FormatTokenDocElement for " + tokenText; } } }