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

net.sourceforge.pmd.lang.java.ast.ASTSwitchLike Maven / Gradle / Ivy

The newest version!
/**
 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
 */

package net.sourceforge.pmd.lang.java.ast;

import java.util.Iterator;

import net.sourceforge.pmd.lang.ast.NodeStream;
import net.sourceforge.pmd.lang.java.symbols.JClassSymbol;
import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol;


/**
 * Common supertype for {@linkplain ASTSwitchStatement switch statements}
 * and {@linkplain ASTSwitchExpression switch expressions}. Their grammar
 * is identical, and is described below. The difference is that switch
 * expressions need to be exhaustive.
 *
 * 
 *
 * SwitchLike        ::= {@link ASTSwitchExpression SwitchExpression}
 *                     | {@link ASTSwitchStatement SwitchStatement}
 *
 *                   ::= "switch" "(" {@link ASTExpression Expression} ")" SwitchBlock
 *
 * SwitchBlock       ::= SwitchArrowBlock | SwitchNormalBlock
 *
 * SwitchArrowBlock  ::= "{" {@link ASTSwitchArrowBranch SwitchArrowBranch}* "}"
 * SwitchNormalBlock ::= "{" {@linkplain ASTSwitchFallthroughBranch SwitchFallthroughBranch}* "}"
 *
 * 
*/ public interface ASTSwitchLike extends JavaNode, Iterable { /** * Returns true if this switch has a {@code default} case. */ default boolean hasDefaultCase() { return getBranches().any(it -> it.getLabel().isDefault()); } /** * Returns a stream of all branches of this switch. */ default NodeStream getBranches() { return children(ASTSwitchBranch.class); } /** * Gets the expression tested by this switch. * This is the expression between the parentheses. */ default ASTExpression getTestedExpression() { return (ASTExpression) getChild(0); } /** * Returns true if this switch statement tests an expression * having an enum type and all the constants of this type * are covered by a switch case. Returns false if the type of * the tested expression could not be resolved. */ default boolean isExhaustiveEnumSwitch() { JTypeDeclSymbol symbol = getTestedExpression().getTypeMirror().getSymbol(); if (symbol instanceof JClassSymbol && ((JClassSymbol) symbol).isEnum()) { long numConstants = ((JClassSymbol) symbol).getEnumConstants().size(); // we assume there's no duplicate labels int numLabels = getBranches().sumByInt(it -> it.getLabel().getNumChildren()); return numLabels == numConstants; } return false; } /** * Returns true if this switch statement tests an expression * having an enum type. */ default boolean isEnumSwitch() { JTypeDeclSymbol type = getTestedExpression().getTypeMirror().getSymbol(); return type instanceof JClassSymbol && ((JClassSymbol) type).isEnum(); } @Override default Iterator iterator() { return children(ASTSwitchBranch.class).iterator(); } /** * Returns true if this a switch which uses fallthrough branches * (old school {@code case label: break;}) and not arrow branches. * If the switch has no branches, returns false. */ default boolean isFallthroughSwitch() { return getBranches().filterIs(ASTSwitchFallthroughBranch.class).nonEmpty(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy