All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.thomasjensen.checkstyle.addons.checks.coding.LostInstanceCheck Maven / Gradle / Ivy

The newest version!
package com.thomasjensen.checkstyle.addons.checks.coding;
/*
 * Checkstyle-Addons - Additional Checkstyle checks
 * Copyright (c) 2015-2022, the Checkstyle Addons contributors
 *
 * This program is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License, version 3, as published by the Free
 * Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this
 * program.  If not, see .
 */

import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;

import com.thomasjensen.checkstyle.addons.checks.AbstractAddonsCheck;
import com.thomasjensen.checkstyle.addons.checks.BinaryName;


/**
 * Checks that object instances created explicitly with new are actually used for something. Just being
 * assigned to a variable or passed as a parameter is enough. A full data flow analysis is not performed.
 * 

Documentation

*/ public class LostInstanceCheck extends AbstractAddonsCheck { /** * List of tokens that, when occurring as a parent token of LITERAL_NEW, indicate that LITERAL_NEW does not stand * alone. */ private static final int[] GOOD_PARENTS = new int[]{TokenTypes.ASSIGN, TokenTypes.PLUS_ASSIGN, TokenTypes.MINUS_ASSIGN, TokenTypes.STAR_ASSIGN, TokenTypes.DIV_ASSIGN, TokenTypes.MOD_ASSIGN, TokenTypes.SR_ASSIGN, TokenTypes.BSR_ASSIGN, TokenTypes.SL_ASSIGN, TokenTypes.BAND_ASSIGN, TokenTypes.BXOR_ASSIGN, TokenTypes.BOR_ASSIGN, TokenTypes.ANNOTATION_MEMBER_VALUE_PAIR, TokenTypes.ARRAY_INIT, TokenTypes.ELIST, TokenTypes.FOR_EACH_CLAUSE, TokenTypes.LITERAL_RETURN, TokenTypes.LITERAL_THROW}; /** * List of tokens that, when occurring as a parent token of LITERAL_NEW, indicate that LITERAL_NEW stands alone. */ private static final int[] BAD_PARENTS = new int[]{TokenTypes.SLIST, TokenTypes.LITERAL_IF, TokenTypes.LITERAL_ELSE, TokenTypes.LITERAL_FOR, TokenTypes.LITERAL_DO, TokenTypes.LITERAL_WHILE}; @Override public void init() { super.init(); Arrays.sort(GOOD_PARENTS); Arrays.sort(BAD_PARENTS); } @Override public Set getRelevantTokens() { return Collections.singleton(Integer.valueOf(TokenTypes.LITERAL_NEW)); } @Override public void visitToken(@Nullable final BinaryName pBinaryClassName, @Nonnull final DetailAST pAst) { boolean isLost = false; if (!isBeingDereferenced(pAst)) { for (DetailAST a = pAst.getParent(); !getApiFixer().isRootToken(a.getType()); a = a.getParent()) { if (a.getType() == TokenTypes.ELIST) { final int parentType = a.getParent().getType(); if (parentType == TokenTypes.FOR_INIT || parentType == TokenTypes.FOR_ITERATOR) { isLost = true; } break; } if (Arrays.binarySearch(GOOD_PARENTS, a.getType()) >= 0) { break; } if (Arrays.binarySearch(BAD_PARENTS, a.getType()) >= 0) { isLost = true; break; } } } if (isLost) { log(pAst, "lost.instance"); } } /** * Determine if the instance created with new ist followed by a dot. If so, it is being used for * something, so its existence is not considered useless. * * @param pLiteralNew the current LITERAL_NEW token found by the visitor * @return true if the instance is being dereferenced */ private boolean isBeingDereferenced(final DetailAST pLiteralNew) { boolean result = false; final DetailAST parent = pLiteralNew.getParent(); if (parent.getType() == TokenTypes.DOT && (pLiteralNew.getNextSibling() != null || parent.getParent().getType() == TokenTypes.DOT)) { result = true; } return result; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy