<commit_before>package quickfix;

import static edu.umd.cs.findbugs.plugin.eclipse.quickfix.util.ASTUtil.getASTNode;

import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.plugin.eclipse.quickfix.BugResolution;
import edu.umd.cs.findbugs.plugin.eclipse.quickfix.exception.BugResolutionException;

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.InfixExpression.Operator;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;

import util.CustomLabelVisitor;

public class IsNANResolution extends BugResolution {

    @Override
    protected boolean resolveBindings() {
        return true;
    }
    
    
    @Override
    protected void repairBug(ASTRewrite rewrite, CompilationUnit workingUnit, BugInstance bug) throws BugResolutionException {
        ASTNode node = getASTNode(workingUnit, bug.getPrimarySourceLineAnnotation());
        IsNANVisitor visitor = new IsNANVisitor();
        node.accept(visitor);
        
        AST ast = rewrite.getAST();
        
        Expression fixedExpression = makeFixedExpression(rewrite, visitor, ast);
        
        rewrite.replace(visitor.infixToReplace, fixedExpression, null);
    }


    @SuppressWarnings("unchecked")
    private Expression makeFixedExpression(ASTRewrite rewrite, IsNANVisitor visitor, AST ast) {
        Expression retVal = null;
        
        if (visitor.isPrimitive) {
            MethodInvocation fixedExpression = ast.newMethodInvocation();
            SimpleName staticType = ast.newSimpleName(visitor.isDouble? "Double" : "Float");
            fixedExpression.setExpression(staticType);
            fixedExpression.setName(ast.newSimpleName("isNaN"));
            fixedExpression.arguments().add(rewrite.createMoveTarget(visitor.testedVariable));
            
            if (!visitor.isEquals) {
                PrefixExpression not = ast.newPrefixExpression();
                not.setOperator(PrefixExpression.Operator.NOT);
                not.setOperand(fixedExpression);
                retVal = not;
            } else {
                retVal = fixedExpression;
            }
            
        } else {
            
        }
        
        return retVal;
    }
    
    
    private static class IsNANVisitor extends ASTVisitor {
        
        public InfixExpression infixToReplace;
        public Expression testedVariable;
        public boolean isEquals;
        public boolean isDouble;
        public boolean isPrimitive;
        
        @Override
        public boolean visit(InfixExpression node) {
            if (infixToReplace != null) {<commit_msg>isNaN works on boxed primitives<commit_after>package quickfix;

import static edu.umd.cs.findbugs.plugin.eclipse.quickfix.util.ASTUtil.getASTNode;

import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.plugin.eclipse.quickfix.BugResolution;
import edu.umd.cs.findbugs.plugin.eclipse.quickfix.exception.BugResolutionException;

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.InfixExpression.Operator;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;

import util.CustomLabelVisitor;

public class IsNANResolution extends BugResolution {

    @Override
    protected boolean resolveBindings() {
        return true;
    }
    
    
    @Override
    protected void repairBug(ASTRewrite rewrite, CompilationUnit workingUnit, BugInstance bug) throws BugResolutionException {
        ASTNode node = getASTNode(workingUnit, bug.getPrimarySourceLineAnnotation());
        IsNANVisitor visitor = new IsNANVisitor();
        node.accept(visitor);
        
        AST ast = rewrite.getAST();
        
        Expression fixedExpression = makeFixedExpression(rewrite, visitor, ast);
        
        rewrite.replace(visitor.infixToReplace, fixedExpression, null);
    }


    @SuppressWarnings("unchecked")
    private Expression makeFixedExpression(ASTRewrite rewrite, IsNANVisitor visitor, AST ast) {
        MethodInvocation fixedMethod = ast.newMethodInvocation();
        fixedMethod.setName(ast.newSimpleName("isNaN"));
        
        if (visitor.isPrimitive) {
            //make a reference to Double or Float
            SimpleName staticType = ast.newSimpleName(visitor.isDouble? "Double" : "Float");
            fixedMethod.setExpression(staticType);
            fixedMethod.arguments().add(rewrite.createMoveTarget(visitor.testedVariable));
        } else {
            //call isNaN directly on the boxed variable
            fixedMethod.setExpression((Expression) rewrite.createMoveTarget(visitor.testedVariable));
        }
        
        
        if (!visitor.isEquals) {
            PrefixExpression not = ast.newPrefixExpression();
            not.setOperator(PrefixExpression.Operator.NOT);
            not.setOperand(fixedMethod);
            return not;
        } 
        
        return fixedMethod;
    }
    
    
    private static class IsNANVisitor extends ASTVisitor {
        
        public InfixExpression infixToReplace;
        public Expression testedVariable;
        public boolean isEquals;
        public boolean isDouble;
        public boolean isPrimitive;
        
        @Override
        public boolean visit(InfixExpression node) {
            if (infixToReplace != null) {
{'fraction_non_alphanumeric': 0.08808034244320052, 'fraction_numerical': 0.0, 'mean_word_length': 2.8817891373801916, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3608731', 'n_tokens_mistral': 1722, 'n_tokens_neox': 1682, 'n_words': 310}