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

com.liferay.source.formatter.checkstyle.checks.ChainingCheck Maven / Gradle / Ivy

There is a newer version: 1.0.1437
Show newest version
/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library 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 Lesser General Public License for more
 * details.
 */

package com.liferay.source.formatter.checkstyle.checks;

import com.liferay.petra.string.CharPool;
import com.liferay.petra.string.StringBundler;
import com.liferay.petra.string.StringPool;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.tools.ToolsUtil;
import com.liferay.source.formatter.checks.util.JavaSourceUtil;
import com.liferay.source.formatter.parser.JavaClass;
import com.liferay.source.formatter.parser.JavaClassParser;
import com.liferay.source.formatter.parser.JavaMethod;
import com.liferay.source.formatter.parser.JavaSignature;
import com.liferay.source.formatter.parser.JavaTerm;
import com.liferay.source.formatter.util.FileUtil;
import com.liferay.source.formatter.util.SourceFormatterUtil;

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

import java.io.File;

import java.net.URL;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author Hugo Huijser
 */
public class ChainingCheck extends BaseCheck {

	@Override
	public int[] getDefaultTokens() {
		return new int[] {
			TokenTypes.CLASS_DEF, TokenTypes.ENUM_DEF, TokenTypes.INTERFACE_DEF,
			TokenTypes.LITERAL_NEW, TokenTypes.TYPECAST
		};
	}

	@Override
	protected void doVisitToken(DetailAST detailAST) {
		if (detailAST.getType() == TokenTypes.LITERAL_NEW) {
			_checkChainingOnNewInstance(detailAST);

			return;
		}

		if ((detailAST.getType() == TokenTypes.TYPECAST) &&
			isAttributeValue(_APPLY_TO_TYPE_CAST_KEY)) {

			_checkChainingOnTypeCast(detailAST);

			return;
		}

		DetailAST parentDetailAST = detailAST.getParent();

		if (parentDetailAST != null) {
			return;
		}

		_checkChainingOnMethodCalls(detailAST);
	}

	private void _checkAllowedChaining(DetailAST methodCallDetailAST) {
		DetailAST parentDetailAST = methodCallDetailAST.getParent();

		while (true) {
			if ((parentDetailAST.getType() == TokenTypes.DOT) ||
				(parentDetailAST.getType() == TokenTypes.METHOD_CALL)) {

				parentDetailAST = parentDetailAST.getParent();

				continue;
			}

			break;
		}

		if (parentDetailAST.getType() != TokenTypes.EXPR) {
			return;
		}

		parentDetailAST = parentDetailAST.getParent();

		if (parentDetailAST.getType() != TokenTypes.ASSIGN) {
			return;
		}

		parentDetailAST = parentDetailAST.getParent();

		if (parentDetailAST.getType() != TokenTypes.VARIABLE_DEF) {
			return;
		}

		String classOrVariableName = _getClassOrVariableName(
			methodCallDetailAST);

		if (!Objects.equals(classOrVariableName, "Optional") &&
			!Objects.equals(classOrVariableName, "Stream") &&
			!Objects.equals(classOrVariableName, "Try")) {

			return;
		}

		DetailAST variableNameDetailAST = parentDetailAST.findFirstToken(
			TokenTypes.IDENT);

		String variableName = variableNameDetailAST.getText();

		String variableTypeName = getVariableTypeName(
			methodCallDetailAST, variableName, false);

		if (!classOrVariableName.equals(variableTypeName)) {
			return;
		}

		List identDetailASTList = _getIdentDetailASTList(
			parentDetailAST.getParent(), variableName);

		if ((identDetailASTList.size() == 2) &&
			Objects.equals(
				_findFirstParent(
					identDetailASTList.get(0), TokenTypes.ELIST,
					TokenTypes.LITERAL_IF),
				_findFirstParent(
					identDetailASTList.get(1), TokenTypes.ELIST,
					TokenTypes.LITERAL_IF))) {

			log(
				methodCallDetailAST, _MSG_ALLOWED_CHAINING,
				StringBundler.concat(
					classOrVariableName, StringPool.PERIOD,
					getMethodName(methodCallDetailAST)));
		}
	}

	private void _checkChainingOnMethodCalls(DetailAST detailAST) {
		List methodCallDetailASTList = getAllChildTokens(
			detailAST, true, TokenTypes.METHOD_CALL);

		for (DetailAST methodCallDetailAST : methodCallDetailASTList) {
			DetailAST dotDetailAST = methodCallDetailAST.findFirstToken(
				TokenTypes.DOT);

			if (dotDetailAST != null) {
				List childMethodCallDetailASTList =
					getAllChildTokens(
						dotDetailAST, false, TokenTypes.METHOD_CALL);

				// Only check the method that is first in the chain

				if (!childMethodCallDetailASTList.isEmpty()) {
					continue;
				}
			}

			_checkAllowedChaining(methodCallDetailAST);

			List chainedMethodNames = _getChainedMethodNames(
				methodCallDetailAST);

			_checkRequiredChaining(methodCallDetailAST, chainedMethodNames);

			int chainSize = chainedMethodNames.size();

			if (chainSize == 1) {
				continue;
			}

			if (chainSize == 2) {
				DetailAST elistDetailAST = methodCallDetailAST.findFirstToken(
					TokenTypes.ELIST);

				if ((elistDetailAST.getChildCount() == 0) &&
					(dotDetailAST == null)) {

					continue;
				}

				_checkMethodName(
					chainedMethodNames, "getClass", methodCallDetailAST);

				String name1 = chainedMethodNames.get(0);
				String name2 = chainedMethodNames.get(1);

				if (name1.equals("concat") && name2.equals("concat")) {
					continue;
				}
			}

			if (chainSize > 3) {
				_checkChainOrder(methodCallDetailAST, chainedMethodNames);
			}

			if (_isAllowedChainingMethodCall(
					methodCallDetailAST, chainedMethodNames, detailAST)) {

				continue;
			}

			int concatsCount = Collections.frequency(
				chainedMethodNames, "concat");

			if (concatsCount > 2) {
				log(methodCallDetailAST, _MSG_AVOID_TOO_MANY_CONCAT);

				continue;
			}

			if ((chainSize == 3) && (concatsCount == 2)) {
				continue;
			}

			log(
				methodCallDetailAST, _MSG_AVOID_METHOD_CHAINING,
				getMethodName(methodCallDetailAST));
		}
	}

	private void _checkChainingOnNewInstance(DetailAST detailAST) {
		DetailAST dotDetailAST = detailAST.getParent();

		if (dotDetailAST.getType() != TokenTypes.DOT) {
			return;
		}

		DetailAST methodCallDetailAST = dotDetailAST.getParent();

		if (methodCallDetailAST.getType() != TokenTypes.METHOD_CALL) {
			return;
		}

		if ((detailAST.findFirstToken(TokenTypes.ARRAY_DECLARATOR) != null) ||
			(detailAST.findFirstToken(TokenTypes.OBJBLOCK) != null)) {

			return;
		}

		List chainedMethodNames = _getChainedMethodNames(
			methodCallDetailAST);

		if (_isAllowedChainingMethodCall(
				methodCallDetailAST, chainedMethodNames, detailAST)) {

			return;
		}

		log(methodCallDetailAST, _MSG_AVOID_NEW_INSTANCE_CHAINING);
	}

	private void _checkChainingOnTypeCast(DetailAST detailAST) {
		if (_isInsideConstructorThisCall(detailAST) ||
			hasParentWithTokenType(detailAST, TokenTypes.SUPER_CTOR_CALL)) {

			return;
		}

		DetailAST parentDetailAST = detailAST.getParent();

		if (parentDetailAST.getType() == TokenTypes.DOT) {
			log(detailAST, _MSG_AVOID_TYPE_CAST_CHAINING);
		}
	}

	private void _checkChainOrder(
		DetailAST methodCallDetailAST, List chainedMethodNames) {

		if (!Objects.equals(chainedMethodNames.get(0), "status") ||
			!Objects.equals(
				chainedMethodNames.get(chainedMethodNames.size() - 1),
				"build") ||
			!Objects.equals(
				_getClassOrVariableName(methodCallDetailAST), "Response")) {

			return;
		}

		List middleMethodNames = chainedMethodNames.subList(
			1, chainedMethodNames.size() - 1);

		String unsortedNames = middleMethodNames.toString();

		Collections.sort(middleMethodNames);

		if (!unsortedNames.equals(middleMethodNames.toString())) {
			log(methodCallDetailAST, _MSG_UNSORTED_RESPONSE);
		}
	}

	private void _checkMethodName(
		List chainedMethodNames, String methodName,
		DetailAST methodCallDetailAST) {

		String firstMethodName = chainedMethodNames.get(0);

		if (firstMethodName.equals(methodName) &&
			!_isInsideConstructorThisCall(methodCallDetailAST) &&
			!hasParentWithTokenType(
				methodCallDetailAST, TokenTypes.SUPER_CTOR_CALL)) {

			log(methodCallDetailAST, _MSG_AVOID_METHOD_CHAINING, methodName);
		}
	}

	private void _checkRequiredChaining(
		DetailAST methodCallDetailAST, List chainedMethodNames) {

		String classOrVariableName = _getClassOrVariableName(
			methodCallDetailAST);

		if (classOrVariableName == null) {
			return;
		}

		String variableTypeName = getVariableTypeName(
			methodCallDetailAST, classOrVariableName, false);

		String fullyQualifiedClassName = variableTypeName;

		for (String importName : getImportNames(methodCallDetailAST)) {
			if (importName.endsWith("." + variableTypeName)) {
				fullyQualifiedClassName = importName;

				break;
			}
		}

		List requiredChainingMethodNames =
			_getRequiredChainingMethodNames(fullyQualifiedClassName);

		if (requiredChainingMethodNames == null) {
			return;
		}

		String methodName = chainedMethodNames.get(
			chainedMethodNames.size() - 1);

		if (!requiredChainingMethodNames.contains(methodName)) {
			return;
		}

		DetailAST topLevelMethodCallDetailAST = methodCallDetailAST;

		while (true) {
			DetailAST parentDetailAST = topLevelMethodCallDetailAST.getParent();

			if (parentDetailAST.getType() != TokenTypes.DOT) {
				break;
			}

			parentDetailAST = parentDetailAST.getParent();

			if (parentDetailAST.getType() != TokenTypes.METHOD_CALL) {
				break;
			}

			topLevelMethodCallDetailAST = parentDetailAST;
		}

		DetailAST parentDetailAST = topLevelMethodCallDetailAST.getParent();

		if (parentDetailAST.getType() != TokenTypes.EXPR) {
			return;
		}

		DetailAST nextSiblingDetailAST = parentDetailAST.getNextSibling();

		if ((nextSiblingDetailAST == null) ||
			(nextSiblingDetailAST.getType() != TokenTypes.SEMI)) {

			return;
		}

		nextSiblingDetailAST = nextSiblingDetailAST.getNextSibling();

		if ((nextSiblingDetailAST == null) ||
			(nextSiblingDetailAST.getType() != TokenTypes.EXPR)) {

			return;
		}

		DetailAST nextMethodCallDetailAST =
			nextSiblingDetailAST.getFirstChild();

		if (nextMethodCallDetailAST.getType() != TokenTypes.METHOD_CALL) {
			return;
		}

		while (true) {
			DetailAST firstChildDetailAST =
				nextMethodCallDetailAST.getFirstChild();

			if (firstChildDetailAST.getType() != TokenTypes.DOT) {
				break;
			}

			firstChildDetailAST = firstChildDetailAST.getFirstChild();

			if (firstChildDetailAST.getType() != TokenTypes.METHOD_CALL) {
				break;
			}

			nextMethodCallDetailAST = firstChildDetailAST;
		}

		if (classOrVariableName.equals(
				_getClassOrVariableName(nextMethodCallDetailAST)) &&
			!Objects.equals(getMethodName(nextMethodCallDetailAST), "remove")) {

			log(
				methodCallDetailAST, _MSG_REQUIRED_CHAINING,
				classOrVariableName + "." + methodName);
		}
	}

	private DetailAST _findFirstParent(DetailAST detailAST, int... types) {
		DetailAST parentDetailAST = detailAST.getParent();

		while (true) {
			if (parentDetailAST == null) {
				return null;
			}

			if (ArrayUtil.contains(types, parentDetailAST.getType())) {
				return parentDetailAST;
			}

			parentDetailAST = parentDetailAST.getParent();
		}
	}

	private List _getChainedMethodNames(DetailAST methodCallDetailAST) {
		List chainedMethodNames = new ArrayList<>();

		chainedMethodNames.add(getMethodName(methodCallDetailAST));

		while (true) {
			DetailAST parentDetailAST = methodCallDetailAST.getParent();

			if (parentDetailAST.getType() != TokenTypes.DOT) {
				return chainedMethodNames;
			}

			DetailAST grandParentDetailAST = parentDetailAST.getParent();

			if (grandParentDetailAST.getType() != TokenTypes.METHOD_CALL) {
				DetailAST siblingDetailAST =
					methodCallDetailAST.getNextSibling();

				if (siblingDetailAST.getType() == TokenTypes.IDENT) {
					chainedMethodNames.add(siblingDetailAST.getText());
				}

				return chainedMethodNames;
			}

			methodCallDetailAST = grandParentDetailAST;

			chainedMethodNames.add(getMethodName(methodCallDetailAST));
		}
	}

	private String _getClassOrVariableName(DetailAST methodCallDetailAST) {
		DetailAST dotDetailAST = methodCallDetailAST.findFirstToken(
			TokenTypes.DOT);

		if (dotDetailAST == null) {
			return null;
		}

		DetailAST firstChildDetailAST = dotDetailAST.getFirstChild();

		FullIdent fullIdent = null;

		if (firstChildDetailAST.getType() == TokenTypes.LITERAL_NEW) {
			fullIdent = FullIdent.createFullIdent(
				firstChildDetailAST.getFirstChild());
		}
		else {
			fullIdent = FullIdent.createFullIdent(dotDetailAST);
		}

		firstChildDetailAST = firstChildDetailAST.getFirstChild();

		if ((firstChildDetailAST != null) &&
			(firstChildDetailAST.getType() == TokenTypes.DOT)) {

			return fullIdent.getText();
		}

		String s = fullIdent.getText();

		int x = s.lastIndexOf(CharPool.PERIOD);

		if (x == -1) {
			return s;
		}

		return s.substring(0, x);
	}

	private DetailAST _getGlobalVariableDefinitonDetailAST(
		DetailAST methodCallDetailAST) {

		DetailAST parentDetailAST = methodCallDetailAST.getParent();

		while (true) {
			if ((parentDetailAST == null) ||
				(parentDetailAST.getType() == TokenTypes.CTOR_DEF) ||
				(parentDetailAST.getType() == TokenTypes.METHOD_DEF)) {

				return null;
			}

			if (parentDetailAST.getType() == TokenTypes.VARIABLE_DEF) {
				DetailAST grandParentDetailAST = parentDetailAST.getParent();

				if (grandParentDetailAST.getType() == TokenTypes.OBJBLOCK) {
					return parentDetailAST;
				}

				return null;
			}

			parentDetailAST = parentDetailAST.getParent();
		}
	}

	private List _getIdentDetailASTList(
		DetailAST detailAST, String name) {

		List identDetailASTList = new ArrayList<>();

		for (DetailAST identDetailAST :
				getAllChildTokens(detailAST, true, TokenTypes.IDENT)) {

			if (name.equals(identDetailAST.getText())) {
				identDetailASTList.add(identDetailAST);
			}
		}

		return identDetailASTList;
	}

	private JavaClass _getJavaClass(String requiredChainingClassFileName) {
		File file = SourceFormatterUtil.getFile(
			getBaseDirName(), requiredChainingClassFileName,
			ToolsUtil.PORTAL_MAX_DIR_LEVEL);

		try {
			if (file != null) {
				return JavaClassParser.parseJavaClass(
					requiredChainingClassFileName, FileUtil.read(file));
			}

			String portalBranchName = getAttributeValue(
				SourceFormatterUtil.GIT_LIFERAY_PORTAL_BRANCH);

			if (Validator.isNull(portalBranchName)) {
				return null;
			}

			URL url = new URL(
				StringBundler.concat(
					SourceFormatterUtil.GIT_LIFERAY_PORTAL_URL,
					portalBranchName, StringPool.SLASH,
					requiredChainingClassFileName));

			return JavaClassParser.parseJavaClass(
				requiredChainingClassFileName,
				StringUtil.read(url.openStream()));
		}
		catch (Exception exception) {
			return null;
		}
	}

	private DetailAST _getOuterMethodCallDetailAST(DetailAST detailAST) {
		while (true) {
			if ((detailAST.getType() != TokenTypes.DOT) &&
				(detailAST.getType() != TokenTypes.METHOD_CALL)) {

				return null;
			}

			DetailAST parentDetailAST = detailAST.getParent();

			if ((detailAST.getType() == TokenTypes.METHOD_CALL) &&
				(parentDetailAST.getType() != TokenTypes.DOT)) {

				break;
			}

			detailAST = parentDetailAST;
		}

		while (true) {
			DetailAST parentDetailAST = detailAST.getParent();

			if (parentDetailAST == null) {
				return null;
			}

			if (parentDetailAST.getType() == TokenTypes.METHOD_CALL) {
				detailAST = parentDetailAST;

				break;
			}

			detailAST = parentDetailAST;
		}

		while (true) {
			if ((detailAST.getType() != TokenTypes.DOT) &&
				(detailAST.getType() != TokenTypes.METHOD_CALL)) {

				return null;
			}

			DetailAST childDetailAST = detailAST.getFirstChild();

			if ((detailAST.getType() == TokenTypes.DOT) &&
				(childDetailAST.getType() != TokenTypes.METHOD_CALL)) {

				return detailAST.getParent();
			}

			detailAST = childDetailAST;
		}
	}

	private List _getRequiredChainingMethodNames(
		String fullyQualifiedClassName) {

		if (_requiredChainingMethodNamesMap != null) {
			return _requiredChainingMethodNamesMap.get(fullyQualifiedClassName);
		}

		_requiredChainingMethodNamesMap = new HashMap<>();

		List requiredChainingClassFileNames = getAttributeValues(
			_REQUIRED_CHAINING_CLASS_FILE_NAMES_KEY);

		for (String requiredChainingClassFileName :
				requiredChainingClassFileNames) {

			JavaClass javaClass = _getJavaClass(requiredChainingClassFileName);

			if (javaClass == null) {
				continue;
			}

			List requiredChainingMethodNames = new ArrayList<>();

			for (JavaTerm javaTerm : javaClass.getChildJavaTerms()) {
				if (!(javaTerm instanceof JavaMethod)) {
					continue;
				}

				JavaMethod javaMethod = (JavaMethod)javaTerm;

				if (!javaMethod.isPublic()) {
					continue;
				}

				JavaSignature javaSignature = javaMethod.getSignature();

				if (Objects.equals(
						javaClass.getName(), javaSignature.getReturnType())) {

					requiredChainingMethodNames.add(javaMethod.getName());
				}
			}

			_requiredChainingMethodNamesMap.put(
				javaClass.getPackageName() + "." + javaClass.getName(),
				requiredChainingMethodNames);
		}

		return _requiredChainingMethodNamesMap.get(fullyQualifiedClassName);
	}

	private String _getReturnType(
		String methodName, DetailAST classDefinitionDetailAST) {

		List methodDefinitionDetailASTList = getAllChildTokens(
			classDefinitionDetailAST, true, TokenTypes.METHOD_DEF);

		for (DetailAST methodDefinitionDetailAST :
				methodDefinitionDetailASTList) {

			DetailAST nameDetailAST = methodDefinitionDetailAST.findFirstToken(
				TokenTypes.IDENT);

			if (methodName.equals(nameDetailAST.getText())) {
				return getTypeName(methodDefinitionDetailAST, false);
			}
		}

		return null;
	}

	private boolean _isAllowedChainingMethodCall(
		DetailAST methodCallDetailAST, List chainedMethodNames,
		DetailAST detailAST) {

		DetailAST globalVariableDefinitonDetailAST =
			_getGlobalVariableDefinitonDetailAST(methodCallDetailAST);

		if ((globalVariableDefinitonDetailAST != null) &&
			((detailAST.getType() != TokenTypes.CLASS_DEF) ||
			 _isInsideInnerClass(
				 globalVariableDefinitonDetailAST, detailAST))) {

			return true;
		}

		if (_isInsideConstructorThisCall(methodCallDetailAST) ||
			hasParentWithTokenType(
				methodCallDetailAST, TokenTypes.SUPER_CTOR_CALL)) {

			return true;
		}

		List allowedMethodNames = getAttributeValues(
			_ALLOWED_METHOD_NAMES_KEY);

		for (String allowedMethodName : allowedMethodNames) {
			if (chainedMethodNames.contains(allowedMethodName)) {
				return true;
			}
		}

		String absolutePath = getAbsolutePath();

		if (absolutePath.contains("/test/") ||
			absolutePath.contains("/testIntegration/")) {

			List allowedMockitoMethodNames = getAttributeValues(
				_ALLOWED_MOCKITO_METHOD_NAMES_KEY);

			for (String allowedMockitoMethodName : allowedMockitoMethodNames) {
				if (chainedMethodNames.contains(allowedMockitoMethodName)) {
					return true;
				}
			}
		}

		DetailAST dotDetailAST = methodCallDetailAST.findFirstToken(
			TokenTypes.DOT);

		if (dotDetailAST == null) {
			String className = JavaSourceUtil.getClassName(absolutePath);

			List allowedClassNames = getAttributeValues(
				_ALLOWED_CLASS_NAMES_KEY);

			for (String allowedClassName : allowedClassNames) {
				if (className.matches(allowedClassName)) {
					return true;
				}
			}

			String returnType = _getReturnType(
				chainedMethodNames.get(0), detailAST);

			if (returnType != null) {
				List allowedVariableTypeNames = getAttributeValues(
					_ALLOWED_VARIABLE_TYPE_NAMES_KEY);

				for (String allowedVariableTypeName :
						allowedVariableTypeNames) {

					if (returnType.matches(allowedVariableTypeName)) {
						return true;
					}
				}
			}

			return false;
		}

		String classOrVariableName = _getClassOrVariableName(
			methodCallDetailAST);

		if (classOrVariableName != null) {
			if (_isLambdaVariable(methodCallDetailAST, classOrVariableName)) {
				return true;
			}

			List allowedClassNames = getAttributeValues(
				_ALLOWED_CLASS_NAMES_KEY);

			for (String s :
					StringUtil.split(classOrVariableName, CharPool.PERIOD)) {

				for (String allowedClassName : allowedClassNames) {
					if (s.matches("(?i)" + allowedClassName)) {
						return true;
					}
				}
			}

			String variableTypeName = getVariableTypeName(
				methodCallDetailAST, classOrVariableName, false);

			if (Validator.isNotNull(variableTypeName)) {
				List allowedVariableTypeNames = getAttributeValues(
					_ALLOWED_VARIABLE_TYPE_NAMES_KEY);

				for (String allowedVariableTypeName :
						allowedVariableTypeNames) {

					if (variableTypeName.matches(allowedVariableTypeName)) {
						return true;
					}
				}
			}
		}

		DetailAST outerMethodCallDetailAST = _getOuterMethodCallDetailAST(
			methodCallDetailAST);

		if (outerMethodCallDetailAST != null) {
			return _isAllowedChainingMethodCall(
				outerMethodCallDetailAST,
				_getChainedMethodNames(outerMethodCallDetailAST), detailAST);
		}

		return false;
	}

	private boolean _isInsideConstructorThisCall(DetailAST detailAST) {
		DetailAST parentDetailAST = detailAST.getParent();

		while (parentDetailAST != null) {
			String parentDetailASTText = parentDetailAST.getText();

			if ((parentDetailAST.getType() == TokenTypes.CTOR_CALL) &&
				parentDetailASTText.equals("this")) {

				return true;
			}

			parentDetailAST = parentDetailAST.getParent();
		}

		return false;
	}

	private boolean _isInsideInnerClass(
		DetailAST globalVariableDefinitonDetailAST,
		DetailAST outerClassDefinitionDetailAST) {

		DetailAST detailAST = getParentWithTokenType(
			globalVariableDefinitonDetailAST, TokenTypes.CLASS_DEF,
			TokenTypes.ENUM_DEF, TokenTypes.INTERFACE_DEF,
			TokenTypes.LITERAL_NEW);

		if (!detailAST.equals(outerClassDefinitionDetailAST)) {
			return true;
		}

		return false;
	}

	private boolean _isLambdaVariable(
		DetailAST methodCallDetailAST, String variableName) {

		DetailAST parentDetailAST = methodCallDetailAST.getParent();

		while (parentDetailAST != null) {
			if (parentDetailAST.getType() != TokenTypes.LAMBDA) {
				parentDetailAST = parentDetailAST.getParent();

				continue;
			}

			DetailAST nameDetailAST = parentDetailAST.findFirstToken(
				TokenTypes.IDENT);

			if ((nameDetailAST != null) &&
				variableName.equals(nameDetailAST.getText())) {

				return true;
			}

			return false;
		}

		return false;
	}

	private static final String _ALLOWED_CLASS_NAMES_KEY = "allowedClassNames";

	private static final String _ALLOWED_METHOD_NAMES_KEY =
		"allowedMethodNames";

	private static final String _ALLOWED_MOCKITO_METHOD_NAMES_KEY =
		"allowedMockitoMethodNames";

	private static final String _ALLOWED_VARIABLE_TYPE_NAMES_KEY =
		"allowedVariableTypeNames";

	private static final String _APPLY_TO_TYPE_CAST_KEY = "applyToTypeCast";

	private static final String _MSG_ALLOWED_CHAINING = "chaining.allowed";

	private static final String _MSG_AVOID_METHOD_CHAINING =
		"chaining.avoid.method";

	private static final String _MSG_AVOID_NEW_INSTANCE_CHAINING =
		"chaining.avoid.new.instance";

	private static final String _MSG_AVOID_TOO_MANY_CONCAT =
		"concat.avoid.too.many";

	private static final String _MSG_AVOID_TYPE_CAST_CHAINING =
		"chaining.avoid.type.cast";

	private static final String _MSG_REQUIRED_CHAINING = "chaining.required";

	private static final String _MSG_UNSORTED_RESPONSE = "response.unsorted";

	private static final String _REQUIRED_CHAINING_CLASS_FILE_NAMES_KEY =
		"requiredChainingClassFileNames";

	private Map> _requiredChainingMethodNamesMap;

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy