@Override public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) { super.visitMethodCallExpression(expression); final PsiReferenceExpression methodExpression = expression.getMethodExpression(); @NonNls final String methodName = methodExpression.getReferenceName(); if (methodName == null) { return; } if (!methodName.startsWith("get") && !methodName.startsWith("update")) { return; } final PsiExpressionList argumentList = expression.getArgumentList(); final PsiExpression[] arguments = argumentList.getExpressions(); if (arguments.length == 0) { return; } final PsiExpression argument = arguments[0]; if (!TypeUtils.expressionHasType(argument, PsiKeyword.INT)) { return; } if (!PsiUtil.isConstantExpression(argument)) { return; } final Integer val = (Integer) ConstantExpressionUtil.computeCastTo(argument, PsiType.INT); if (val == null || val.intValue() != 0) { return; } final PsiExpression qualifier = methodExpression.getQualifierExpression(); if (!TypeUtils.expressionHasTypeOrSubtype(qualifier, "java.sql.ResultSet")) { return; } registerError(argument); }
@Nullable private PsiType extractListTypeFromContainingClass( PsiElement element) { PsiClass listClass = PsiTreeUtil.getParentOfType(element, PsiClass.class); if (listClass == null) { return null; } final PsiMethod[] getMethods = listClass.findMethodsByName("get", true); if (getMethods.length == 0) { return null; } final PsiType type = getMethods[0].getReturnType(); if (!(type instanceof PsiClassType)) { return null; } final PsiClassType classType = (PsiClassType)type; final PsiClass parameterClass = classType.resolve(); if (parameterClass == null) { return null; } PsiClass subClass = null; while (listClass != null && !listClass.hasTypeParameters()) { subClass = listClass; listClass = listClass.getSuperClass(); } if (listClass == null || subClass == null) { return TypeUtils.getObjectType(element); } final PsiTypeParameter[] typeParameters = listClass.getTypeParameters(); if (!parameterClass.equals(typeParameters[0])) { return TypeUtils.getObjectType(element); } final PsiReferenceList extendsList = subClass.getExtendsList(); if (extendsList == null) { return null; } final PsiJavaCodeReferenceElement[] referenceElements = extendsList.getReferenceElements(); if (referenceElements.length == 0) { return null; } final PsiType[] types = referenceElements[0].getTypeParameters(); if (types.length == 0) { return TypeUtils.getObjectType(element); } return types[0]; }
@Override public void visitThrowStatement(PsiThrowStatement statement) { super.visitThrowStatement(statement); final PsiCatchSection catchSection = PsiTreeUtil.getParentOfType(statement, PsiCatchSection.class, true, PsiClass.class); if (catchSection == null) { return; } final PsiParameter parameter = catchSection.getParameter(); if (parameter == null) { return; } @NonNls final String parameterName = parameter.getName(); if (PsiUtil.isIgnoredName(parameterName)) { return; } final PsiExpression exception = statement.getException(); if (exception == null) { return; } if (ignoreCantWrap) { final PsiType thrownType = exception.getType(); if (thrownType instanceof PsiClassType) { final PsiClassType classType = (PsiClassType) thrownType; final PsiClass exceptionClass = classType.resolve(); if (exceptionClass != null) { final PsiMethod[] constructors = exceptionClass.getConstructors(); final PsiClassType throwableType = TypeUtils.getType(CommonClassNames.JAVA_LANG_THROWABLE, statement); boolean canWrap = false; outer: for (PsiMethod constructor : constructors) { final PsiParameterList parameterList = constructor.getParameterList(); final PsiParameter[] parameters = parameterList.getParameters(); for (PsiParameter constructorParameter : parameters) { final PsiType type = constructorParameter.getType(); if (throwableType.equals(type)) { canWrap = true; break outer; } } } if (!canWrap) { return; } } } } final ReferenceFinder visitor = new ReferenceFinder(parameter); exception.accept(visitor); if (visitor.usesParameter()) { return; } registerStatementError(statement); }
@Override public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) { super.visitMethodCallExpression(expression); final PsiReferenceExpression methodExpression = expression.getMethodExpression(); @NonNls final String methodName = methodExpression.getReferenceName(); if (methodName == null) { return; } final boolean resultSet; if (methodName.startsWith("get") || methodName.startsWith("update")) { resultSet = true; } else if (methodName.startsWith("set")) { resultSet = false; } else { return; } final PsiExpressionList argumentList = expression.getArgumentList(); final PsiExpression[] arguments = argumentList.getExpressions(); if (arguments.length == 0) { return; } final PsiExpression argument = arguments[0]; final Object val = ExpressionUtils.computeConstantExpression(argument); if (!(val instanceof Integer) || ((Integer) val).intValue() != 0) { return; } final PsiExpression qualifier = methodExpression.getQualifierExpression(); if (resultSet) { if (TypeUtils.expressionHasTypeOrSubtype(qualifier, "java.sql.ResultSet")) { registerError(argument, Boolean.valueOf(resultSet)); } } else { if (TypeUtils.expressionHasTypeOrSubtype(qualifier, "java.sql.PreparedStatement")) { registerError(argument, Boolean.valueOf(resultSet)); } } }
@Override public void visitMethodCallExpression(PsiMethodCallExpression expression) { super.visitMethodCallExpression(expression); final PsiReferenceExpression methodExpression = expression.getMethodExpression(); @NonNls final String name = methodExpression.getReferenceName(); if (HardcodedMethodConstants.TO_STRING.equals(name)) { final PsiExpressionList argumentList = expression.getArgumentList(); final PsiExpression[] arguments = argumentList.getExpressions(); if (arguments.length != 0) { return; } final PsiExpression qualifier = methodExpression.getQualifierExpression(); checkExpression(qualifier); } else if ("append".equals(name)) { final PsiExpression qualifier = methodExpression.getQualifierExpression(); if (!TypeUtils.expressionHasTypeOrSubtype( qualifier, CommonClassNames.JAVA_LANG_ABSTRACT_STRING_BUILDER)) { return; } final PsiExpressionList argumentList = expression.getArgumentList(); final PsiExpression[] arguments = argumentList.getExpressions(); if (arguments.length != 1) { return; } final PsiExpression argument = arguments[0]; checkExpression(argument); } else if ("valueOf".equals(name)) { final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); if (!(qualifierExpression instanceof PsiReferenceExpression)) { return; } final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) qualifierExpression; final String canonicalText = referenceExpression.getCanonicalText(); if (!CommonClassNames.JAVA_LANG_STRING.equals(canonicalText)) { return; } final PsiExpressionList argumentList = expression.getArgumentList(); final PsiExpression[] arguments = argumentList.getExpressions(); if (arguments.length != 1) { return; } final PsiExpression argument = arguments[0]; checkExpression(argument); } }
private boolean isAddedToCollection(PsiExpression expression) { final PsiElement parent = expression.getParent(); if (!(parent instanceof PsiExpressionList)) { return false; } final PsiExpressionList expressionList = (PsiExpressionList) parent; final PsiElement grandParent = expressionList.getParent(); if (!(grandParent instanceof PsiMethodCallExpression)) { return false; } final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) grandParent; final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); @NonNls final String methodName = methodExpression.getReferenceName(); if (!"put".equals(methodName) && !"set".equals(methodName) && !"add".equals(methodName)) { return false; } final PsiExpression qualifier = methodExpression.getQualifierExpression(); return TypeUtils.expressionHasTypeOrSubtype( qualifier, CommonClassNames.JAVA_UTIL_COLLECTION, CommonClassNames.JAVA_UTIL_MAP) != null; }
private void checkTypeElement(PsiTypeElement typeElement) { if (typeElement == null || !TypeUtils.isOptional(typeElement.getType())) { return; } registerError(typeElement, typeElement); }
@Nullable private String createListIterationText(@NotNull PsiForStatement forStatement) { final PsiBinaryExpression condition = (PsiBinaryExpression) ParenthesesUtils.stripParentheses(forStatement.getCondition()); if (condition == null) { return null; } final PsiExpression lhs = ParenthesesUtils.stripParentheses(condition.getLOperand()); if (lhs == null) { return null; } final PsiExpression rhs = ParenthesesUtils.stripParentheses(condition.getROperand()); if (rhs == null) { return null; } final IElementType tokenType = condition.getOperationTokenType(); final String indexName; PsiExpression collectionSize; if (JavaTokenType.LT.equals(tokenType)) { indexName = lhs.getText(); collectionSize = rhs; } else if (JavaTokenType.GT.equals(tokenType)) { indexName = rhs.getText(); collectionSize = lhs; } else { return null; } if (collectionSize instanceof PsiReferenceExpression) { final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) collectionSize; final PsiElement target = referenceExpression.resolve(); if (target instanceof PsiVariable) { final PsiVariable variable = (PsiVariable) target; collectionSize = ParenthesesUtils.stripParentheses(variable.getInitializer()); } } if (!(collectionSize instanceof PsiMethodCallExpression)) { return null; } final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) ParenthesesUtils.stripParentheses(collectionSize); if (methodCallExpression == null) { return null; } final PsiReferenceExpression listLengthExpression = methodCallExpression.getMethodExpression(); final PsiExpression qualifier = ParenthesesUtils.stripParentheses(listLengthExpression.getQualifierExpression()); final PsiReferenceExpression listReference; if (qualifier instanceof PsiReferenceExpression) { listReference = (PsiReferenceExpression) qualifier; } else { listReference = null; } PsiType parameterType; if (listReference == null) { parameterType = extractListTypeFromContainingClass(forStatement); } else { final PsiType type = listReference.getType(); if (type == null) { return null; } parameterType = extractContentTypeFromType(type); } if (parameterType == null) { parameterType = TypeUtils.getObjectType(forStatement); } final String typeString = parameterType.getCanonicalText(); final PsiVariable listVariable; if (listReference == null) { listVariable = null; } else { final PsiElement target = listReference.resolve(); if (!(target instanceof PsiVariable)) { return null; } listVariable = (PsiVariable) target; } final PsiStatement body = forStatement.getBody(); final PsiStatement firstStatement = getFirstStatement(body); final boolean isDeclaration = isListElementDeclaration(firstStatement, listVariable, indexName, parameterType); final String contentVariableName; @NonNls final String finalString; final PsiStatement statementToSkip; if (isDeclaration) { final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement) firstStatement; assert declarationStatement != null; final PsiElement[] declaredElements = declarationStatement.getDeclaredElements(); final PsiElement declaredElement = declaredElements[0]; if (!(declaredElement instanceof PsiVariable)) { return null; } final PsiVariable variable = (PsiVariable) declaredElement; contentVariableName = variable.getName(); statementToSkip = declarationStatement; if (variable.hasModifierProperty(PsiModifier.FINAL)) { finalString = "final "; } else { finalString = ""; } } else { final String collectionName; if (listReference == null) { collectionName = null; } else { collectionName = listReference.getReferenceName(); } contentVariableName = createNewVariableName(forStatement, parameterType, collectionName); finalString = ""; statementToSkip = null; } @NonNls final StringBuilder out = new StringBuilder(); out.append("for("); out.append(finalString); out.append(typeString); out.append(' '); out.append(contentVariableName); out.append(": "); @NonNls final String listName; if (listReference == null) { listName = "this"; } else { listName = listReference.getText(); } out.append(listName); out.append(')'); if (body != null) { replaceCollectionGetAccess( body, contentVariableName, listVariable, indexName, statementToSkip, out); } return out.toString(); }
@Nullable private String createCollectionIterationText(@NotNull PsiForStatement forStatement) throws IncorrectOperationException { final PsiStatement body = forStatement.getBody(); final PsiStatement firstStatement = getFirstStatement(body); final PsiStatement initialization = forStatement.getInitialization(); if (!(initialization instanceof PsiDeclarationStatement)) { return null; } final PsiDeclarationStatement declaration = (PsiDeclarationStatement) initialization; final PsiElement declaredIterator = declaration.getDeclaredElements()[0]; if (!(declaredIterator instanceof PsiVariable)) { return null; } final PsiVariable iteratorVariable = (PsiVariable) declaredIterator; final PsiMethodCallExpression initializer = (PsiMethodCallExpression) iteratorVariable.getInitializer(); if (initializer == null) { return null; } final PsiType iteratorType = initializer.getType(); if (iteratorType == null) { return null; } final PsiType iteratorContentType = extractContentTypeFromType(iteratorType); final PsiType iteratorVariableType = iteratorVariable.getType(); final PsiType contentType; final PsiClassType javaLangObject = TypeUtils.getObjectType(forStatement); if (iteratorContentType == null) { final PsiType iteratorVariableContentType = extractContentTypeFromType(iteratorVariableType); if (iteratorVariableContentType == null) { contentType = javaLangObject; } else { contentType = iteratorVariableContentType; } } else { contentType = iteratorContentType; } final PsiReferenceExpression methodExpression = initializer.getMethodExpression(); final PsiExpression collection = methodExpression.getQualifierExpression(); final String iteratorName = iteratorVariable.getName(); final boolean isDeclaration = isIteratorNextDeclaration(firstStatement, iteratorName, contentType); final PsiStatement statementToSkip; @NonNls final String finalString; final String contentVariableName; if (isDeclaration) { final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement) firstStatement; assert declarationStatement != null; final PsiElement[] declaredElements = declarationStatement.getDeclaredElements(); final PsiElement declaredElement = declaredElements[0]; if (!(declaredElement instanceof PsiVariable)) { return null; } final PsiVariable variable = (PsiVariable) declaredElement; contentVariableName = variable.getName(); statementToSkip = declarationStatement; if (variable.hasModifierProperty(PsiModifier.FINAL)) { finalString = "final "; } else { finalString = ""; } } else { if (collection instanceof PsiReferenceExpression) { final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) collection; final String collectionName = referenceExpression.getReferenceName(); contentVariableName = createNewVariableName(forStatement, contentType, collectionName); } else { contentVariableName = createNewVariableName(forStatement, contentType, null); } final Project project = forStatement.getProject(); final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project); if (codeStyleSettings.GENERATE_FINAL_LOCALS) { finalString = "final "; } else { finalString = ""; } statementToSkip = null; } final String contentTypeString = contentType.getCanonicalText(); @NonNls final StringBuilder out = new StringBuilder(); out.append("for("); out.append(finalString); out.append(contentTypeString); out.append(' '); out.append(contentVariableName); out.append(": "); if (!contentType.equals(javaLangObject)) { @NonNls final String iterableTypeString = "java.lang.Iterable<" + contentTypeString + '>'; if (iteratorContentType == null) { out.append('('); out.append(iterableTypeString); out.append(')'); } } if (collection == null) { out.append("this"); } else { out.append(collection.getText()); } out.append(')'); replaceIteratorNext( body, contentVariableName, iteratorName, statementToSkip, out, contentType); return out.toString(); }
private static boolean isCharacter(PsiExpression expression) { return TypeUtils.expressionHasType(expression, PsiKeyword.CHAR) || TypeUtils.expressionHasType(expression, CommonClassNames.JAVA_LANG_CHARACTER); }