package glslplugin.extensions;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.lang.parameterInfo.*;
import com.intellij.psi.PsiElementResolveResult;
import glslplugin.lang.elements.GLSLElement;
import glslplugin.lang.elements.GLSLIdentifier;
import glslplugin.lang.elements.GLSLTokenTypes;
import glslplugin.lang.elements.declarations.GLSLDeclarator;
import glslplugin.lang.elements.declarations.GLSLFunctionDeclaration;
import glslplugin.lang.elements.declarations.GLSLParameterDeclaration;
import glslplugin.lang.elements.expressions.GLSLFunctionCallExpression;
import glslplugin.lang.elements.reference.GLSLFunctionReference;
import glslplugin.lang.elements.reference.GLSLReferenceBase;
import glslplugin.lang.elements.statements.GLSLCompoundStatement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* Created by abigail on 08/07/15.
*/
public class GLSLParameterInfoHandler implements ParameterInfoHandler<GLSLFunctionCallExpression, Object> {
private static final Object[] EMPTY_ARRAY = new Object[0];
@Override
public boolean couldShowInLookup() {
return true;
}
@Nullable
@Override
public Object[] getParametersForLookup(LookupElement item, ParameterInfoContext context) {
return EMPTY_ARRAY;
}
@Nullable
@Override
public Object[] getParametersForDocumentation(Object p, ParameterInfoContext context) {
return EMPTY_ARRAY;
}
@Nullable
@Override
public GLSLFunctionCallExpression findElementForParameterInfo(@NotNull CreateParameterInfoContext context) {
GLSLFunctionCallExpression call =
ParameterInfoUtils.findParentOfTypeWithStopElements(context.getFile(), context.getOffset(),
GLSLFunctionCallExpression.class, GLSLCompoundStatement.class);
if (call == null) return null;
final GLSLReferenceBase<GLSLIdentifier, ? extends GLSLElement> rawReference = call.getReferenceProxy();
if (!(rawReference instanceof GLSLFunctionReference))return null;
GLSLFunctionReference reference = ((GLSLFunctionReference) rawReference);
Object[] items = reference.multiResolve(false);
if (items.length == 0) {
List<GLSLFunctionDeclaration> declarations = new ArrayList<GLSLFunctionDeclaration>();
for (Object variant : reference.getVariants()) {
if (variant == null || !(variant instanceof GLSLDeclarator)) continue;
GLSLDeclarator declarator = (GLSLDeclarator) variant;
if (declarator.getParentDeclaration() instanceof GLSLFunctionDeclaration) {
String name = declarator.getName();
if (name.equals(call.getFunctionName())) {
declarations.add((GLSLFunctionDeclaration) declarator.getParentDeclaration());
}
}
}
items = declarations.toArray();
}
context.setItemsToShow(items);
return call;
}
@Override
public void showParameterInfo(@NotNull GLSLFunctionCallExpression call, @NotNull CreateParameterInfoContext context) {
context.showHint(call, call.getTextRange().getStartOffset(), this);
}
@Nullable
@Override
public GLSLFunctionCallExpression findElementForUpdatingParameterInfo(@NotNull UpdateParameterInfoContext context) {
GLSLFunctionCallExpression call =
ParameterInfoUtils.findParentOfTypeWithStopElements(context.getFile(), context.getOffset(),
GLSLFunctionCallExpression.class, GLSLCompoundStatement.class);
context.setParameterOwner(call);
return call;
}
@Override
public void updateParameterInfo(@NotNull GLSLFunctionCallExpression call, @NotNull UpdateParameterInfoContext context) {
if (context.getParameterOwner() != call) {
context.removeHint();
return;
}
int index = ParameterInfoUtils.getCurrentParameterIndex(call.getParameterList().getNode(), context.getOffset(), GLSLTokenTypes.COMMA);
context.setCurrentParameter(index);
}
@Nullable
@Override
public String getParameterCloseChars() {
return ParameterInfoUtils.DEFAULT_PARAMETER_CLOSE_CHARS;
}
@Override
public boolean tracksParameterIndex() {
return false;
}
@Override
public void updateUI(Object p, @NotNull ParameterInfoUIContext context) {
if (p instanceof PsiElementResolveResult) p = ((PsiElementResolveResult) p).getElement();
if (!(p instanceof GLSLFunctionDeclaration)) return;
GLSLFunctionDeclaration declaration = (GLSLFunctionDeclaration) p;
GLSLParameterDeclaration[] parameters = declaration.getParameters();
StringBuilder buffer = new StringBuilder();
buffer.append(declaration.getType().getReturnType().getTypename())
.append(' ').append(declaration.getName()).append('(');
final int currentParameter = context.getCurrentParameterIndex();
int highlightStartOffset = -1, highlightEndOffset = -1;
for (int i = 0; i < parameters.length; i++) {
if (i == currentParameter) highlightStartOffset = buffer.length();
buffer.append(parameters[i].getText());
if (i == currentParameter) highlightEndOffset = buffer.length();
if (i < parameters.length - 1) buffer.append(", ");
}
buffer.append(')');
context.setupUIComponentPresentation(buffer.toString(), highlightStartOffset, highlightEndOffset, false, false, false, context.getDefaultParameterColor());
}
}