![JAR search and dependency download from the Maven repository](/logo.png)
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.
*
*/
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