package glslplugin.lang.elements.expressions; import com.intellij.lang.ASTNode; import com.intellij.psi.tree.IElementType; import glslplugin.lang.elements.expressions.operator.GLSLOperator; import glslplugin.lang.elements.expressions.operator.GLSLOperators; import glslplugin.lang.elements.types.GLSLType; import glslplugin.lang.elements.types.GLSLTypes; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.logging.Logger; /** * Unary operator expression is an expression with one operand and one unary operator, such as "-", "!" or "~" * * @author Jan Polák */ public class GLSLUnaryOperatorExpression extends GLSLOperatorExpression { private final boolean prefix; public GLSLUnaryOperatorExpression(@NotNull ASTNode astNode, boolean prefix) { super(astNode); this.prefix = prefix; } /** * Prefix operator has the operator before operand, postfix is reversed. * @return True if prefix operator, false if postfix operator */ public boolean isPrefix() { return prefix; } @Nullable public GLSLExpression getOperand() { GLSLExpression[] operands = getOperands(); if (operands.length == 1) { return operands[0]; } else { Logger.getLogger("GLSLUnaryOperatorExpression").warning("Unary operator expression with " + operands.length + " operand(s)."); return null; } } /** * Overrides the operator type to provide the unary versions of '+' and '-'. * * @param type the elements type to convert to an operator. * @return the resulting operator. */ @Override @Nullable protected GLSLOperator getOperatorFromType(IElementType type) { GLSLOperator op = super.getOperatorFromType(type); if (op == GLSLOperators.ADDITION) op = GLSLOperators.PLUS; if (op == GLSLOperators.SUBTRACTION) op = GLSLOperators.MINUS; return op; } @Override public boolean isConstantValue() { return getConstantValue() != null; } @Nullable @Override public Object getConstantValue() { GLSLExpression operand = getOperand(); if(operand == null || !operand.isConstantValue())return null; GLSLOperator operator = getOperator(); if(operator == null || !(operator instanceof GLSLOperator.GLSLUnaryOperator))return null; GLSLOperator.GLSLUnaryOperator unaryOperator = (GLSLOperator.GLSLUnaryOperator) operator; GLSLType operandType = operand.getType(); if(!operandType.isValidType())return null; if(!unaryOperator.isValidInput(operandType))return null; return unaryOperator.getResultValue(operand.getConstantValue(), prefix); } @NotNull @Override public GLSLType getType() { GLSLOperator operator = getOperator(); GLSLExpression operand = getOperand(); if(operator == null || operand == null || !(operator instanceof GLSLOperator.GLSLUnaryOperator)){ return GLSLTypes.UNKNOWN_TYPE; }else{ GLSLOperator.GLSLUnaryOperator unaryOperator = (GLSLOperator.GLSLUnaryOperator) operator; return unaryOperator.getResultType(operand.getType()); } } public String toString() { GLSLOperator operator = getOperator(); if(operator != null){ return "Unary Operator Expression '" + operator.getTextRepresentation() + "'"; }else{ return "Unary Operator Expression '(unknown)'"; } } }