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

eu.cqse.check.base.ThrowExceptionCheckBase Maven / Gradle / Ivy

Go to download

The Teamscale Custom Check API allows users to extend Teamscale by writing custom analyses that create findings.

There is a newer version: 2024.7.2
Show newest version
/*
 * Copyright (c) CQSE GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package eu.cqse.check.base;

import java.util.List;

import org.conqat.lib.commons.collections.CollectionUtils;

import eu.cqse.check.framework.core.CheckException;
import eu.cqse.check.framework.core.CheckImplementationBase;
import eu.cqse.check.framework.scanner.ETokenType;
import eu.cqse.check.framework.scanner.IToken;
import eu.cqse.check.framework.shallowparser.SubTypeNames;
import eu.cqse.check.framework.shallowparser.framework.EShallowEntityType;
import eu.cqse.check.framework.shallowparser.framework.ShallowEntity;
import eu.cqse.check.framework.shallowparser.framework.ShallowEntityTraversalUtils;
import eu.cqse.check.framework.util.tokens.TokenPattern;
import eu.cqse.check.framework.util.tokens.TokenPatternMatch;

/**
 * Base class for custom checks which reveal when exceptions are thrown.
 */
public abstract class ThrowExceptionCheckBase extends CheckImplementationBase {

	/** Arbitrarily chosen int as group number for the token matcher. */
	private static final int GROUP_NAME = 0;

	private static final TokenPattern THROW_NEW_PATTERN = new TokenPattern().sequence(ETokenType.THROW)
			.sequence(ETokenType.NEW)
			.sequence(ETokenType.IDENTIFIER, new TokenPattern().repeated(ETokenType.DOT, ETokenType.IDENTIFIER))
			.group(GROUP_NAME).sequence(ETokenType.LPAREN);

	@Override
	public void execute() throws CheckException {
		List methods = ShallowEntityTraversalUtils
				.listEntitiesOfType(context.getAbstractSyntaxTree(getCodeViewOption()), EShallowEntityType.METHOD);
		for (ShallowEntity method : methods) {
			processEntity(method);
		}
	}

	private void processEntity(ShallowEntity entity) throws CheckException {
		// Lambda bodies are already checked in the corresponding method, in which they
		// are defined.
		if (entity.getSubtype().equals(SubTypeNames.LAMBDA) || skipMethod(entity)) {
			return;
		}
		processTokens(entity.includedTokens());
	}

	protected TokenPattern getFindingPattern() {
		return THROW_NEW_PATTERN;
	}

	private void processTokens(List tokens) throws CheckException {
		TokenPattern pattern = getFindingPattern();
		for (TokenPatternMatch match : pattern.findAll(tokens)) {
			List matchedTokens = match.groupTokens(GROUP_NAME);
			if (matchedTokens.isEmpty()) {
				continue;
			}
			// The identifier with the exception name is the last token in the matching
			// sequence
			IToken exceptionToken = CollectionUtils.getLast(matchedTokens);
			String exceptionName = exceptionToken.getText();
			if (createFindingForException(matchedTokens, exceptionName)) {
				buildFinding(getFindingMessage(matchedTokens) + exceptionName, buildLocation().forToken(exceptionToken))
						.createAndStore();
			}
		}
	}

	/**
	 * Returns true if given method should be skipped from the check analysis.
	 */
	public abstract boolean skipMethod(ShallowEntity entity);

	/** Creates a finding messages for the given tokens. */
	protected abstract String getFindingMessage(List tokens);

	/**
	 * Returns true if this check should create a finding for the thrown exception.
	 */
	public abstract boolean createFindingForException(List tokens, String exceptionClassName)
			throws CheckException;
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy