public void testInferInCall1() throws Exception { PsiReferenceExpression ref = configure(); PsiType type = ref.getType(); assertTrue(type instanceof PsiClassType); PsiType[] paramTypes = ((PsiClassType) type).getParameters(); assertEquals(1, paramTypes.length); assertEquals(CommonClassNames.JAVA_LANG_OBJECT, paramTypes[0].getCanonicalText()); }
public void testInferInAssign1() throws Exception { PsiReferenceExpression ref = configure(); PsiType type = ref.getType(); assertTrue(type instanceof PsiClassType); PsiType[] paramTypes = ((PsiClassType) type).getParameters(); assertEquals(1, paramTypes.length); assertEquals("java.lang.String", paramTypes[0].getCanonicalText()); }
/** @return true, if a declaration was introduced, false otherwise */ private static boolean replaceVariableName( PsiElement element, PsiReferenceExpression firstReference, String newName, String originalName, StringBuilder out) { if (element instanceof PsiReferenceExpression) { final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) element; if (element.equals(firstReference) && isLeftSideOfSimpleAssignment(referenceExpression)) { final PsiType type = firstReference.getType(); if (type != null) { out.append(type.getCanonicalText()); out.append(' '); out.append(newName); return true; } } final String text = element.getText(); if (text.equals(originalName)) { out.append(newName); return false; } } final PsiElement[] children = element.getChildren(); if (children.length == 0) { final String text = element.getText(); out.append(text); } else { boolean result = false; for (final PsiElement child : children) { if (result) { out.append(child.getText()); } else { result = replaceVariableName(child, firstReference, newName, originalName, out); } } return result; } return false; }
private void checkResolvesTo(@NonNls String typeName) throws Exception { PsiReferenceExpression ref = configure(); PsiType type = ref.getType(); assertNotNull(type); assertEquals(typeName, type.getCanonicalText()); }
@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 createArrayIterationText(@NotNull PsiForStatement forStatement) { final PsiExpression condition = forStatement.getCondition(); final PsiBinaryExpression strippedCondition = (PsiBinaryExpression) ParenthesesUtils.stripParentheses(condition); if (strippedCondition == null) { return null; } final PsiExpression lhs = ParenthesesUtils.stripParentheses(strippedCondition.getLOperand()); if (lhs == null) { return null; } final PsiExpression rhs = ParenthesesUtils.stripParentheses(strippedCondition.getROperand()); if (rhs == null) { return null; } final IElementType tokenType = strippedCondition.getOperationTokenType(); final PsiReferenceExpression arrayLengthExpression; final String indexName; if (tokenType.equals(JavaTokenType.LT)) { arrayLengthExpression = (PsiReferenceExpression) ParenthesesUtils.stripParentheses(rhs); indexName = lhs.getText(); } else if (tokenType.equals(JavaTokenType.GT)) { arrayLengthExpression = (PsiReferenceExpression) ParenthesesUtils.stripParentheses(lhs); indexName = rhs.getText(); } else { return null; } if (arrayLengthExpression == null) { return null; } PsiReferenceExpression arrayReference = (PsiReferenceExpression) arrayLengthExpression.getQualifierExpression(); if (arrayReference == null) { final PsiElement target = arrayLengthExpression.resolve(); if (!(target instanceof PsiVariable)) { return null; } final PsiVariable variable = (PsiVariable) target; final PsiExpression initializer = variable.getInitializer(); if (!(initializer instanceof PsiReferenceExpression)) { return null; } final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) initializer; arrayReference = (PsiReferenceExpression) referenceExpression.getQualifierExpression(); if (arrayReference == null) { return null; } } final PsiType type = arrayReference.getType(); if (!(type instanceof PsiArrayType)) { return null; } final PsiArrayType arrayType = (PsiArrayType) type; final PsiType componentType = arrayType.getComponentType(); final String typeText = componentType.getCanonicalText(); final PsiElement target = arrayReference.resolve(); if (!(target instanceof PsiVariable)) { return null; } final PsiVariable arrayVariable = (PsiVariable) target; final PsiStatement body = forStatement.getBody(); final PsiStatement firstStatement = getFirstStatement(body); final boolean isDeclaration = isArrayElementDeclaration(firstStatement, arrayVariable, indexName); 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; if (VariableAccessUtils.variableIsAssigned(variable, forStatement)) { final String collectionName = arrayReference.getReferenceName(); contentVariableName = createNewVariableName(forStatement, componentType, collectionName); final Project project = forStatement.getProject(); final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project); if (codeStyleSettings.GENERATE_FINAL_LOCALS) { finalString = "final "; } else { finalString = ""; } statementToSkip = null; } else { contentVariableName = variable.getName(); statementToSkip = declarationStatement; if (variable.hasModifierProperty(PsiModifier.FINAL)) { finalString = "final "; } else { finalString = ""; } } } else { final String collectionName = arrayReference.getReferenceName(); contentVariableName = createNewVariableName(forStatement, componentType, collectionName); final Project project = forStatement.getProject(); final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project); if (codeStyleSettings.GENERATE_FINAL_LOCALS) { finalString = "final "; } else { finalString = ""; } statementToSkip = null; } @NonNls final StringBuilder out = new StringBuilder(); out.append("for("); out.append(finalString); out.append(typeText); out.append(' '); out.append(contentVariableName); out.append(": "); final String arrayName = arrayReference.getText(); out.append(arrayName); out.append(')'); if (body != null) { replaceArrayAccess( body, contentVariableName, arrayVariable, indexName, statementToSkip, out); } return out.toString(); }
private static boolean isInConcatenationContext(PsiElement element) { final PsiElement parent = element.getParent(); if (parent instanceof PsiPolyadicExpression) { final PsiPolyadicExpression parentExpression = (PsiPolyadicExpression) parent; final PsiType parentType = parentExpression.getType(); if (parentType == null) { return false; } final String parentTypeText = parentType.getCanonicalText(); return JAVA_LANG_STRING.equals(parentTypeText); } else if (parent instanceof PsiAssignmentExpression) { final PsiAssignmentExpression parentExpression = (PsiAssignmentExpression) parent; final IElementType tokenType = parentExpression.getOperationTokenType(); if (!JavaTokenType.PLUSEQ.equals(tokenType)) { return false; } final PsiType parentType = parentExpression.getType(); if (parentType == null) { return false; } final String parentTypeText = parentType.getCanonicalText(); return JAVA_LANG_STRING.equals(parentTypeText); } else if (parent instanceof PsiExpressionList) { final PsiElement grandParent = parent.getParent(); if (!(grandParent instanceof PsiMethodCallExpression)) { return false; } final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) grandParent; final PsiReferenceExpression methodExpression = methodCall.getMethodExpression(); final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); final PsiType type; if (qualifierExpression == null) { // to use the intention inside the source of // String and StringBuffer type = methodExpression.getType(); } else { type = qualifierExpression.getType(); } if (type == null) { return false; } final String className = type.getCanonicalText(); if (CommonClassNames.JAVA_LANG_STRING_BUFFER.equals(className) || CommonClassNames.JAVA_LANG_STRING_BUILDER.equals(className)) { @NonNls final String methodName = methodExpression.getReferenceName(); if (!"append".equals(methodName) && !"insert".equals(methodName)) { return false; } final PsiElement method = methodExpression.resolve(); return method != null; } else if (JAVA_LANG_STRING.equals(className)) { @NonNls final String methodName = methodExpression.getReferenceName(); if (!"indexOf".equals(methodName) && !"lastIndexOf".equals(methodName) && !"replace".equals(methodName)) { return false; } final PsiElement method = methodExpression.resolve(); return method != null; } } return false; }
@Override public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiReferenceExpression parameterReference = (PsiReferenceExpression) descriptor.getPsiElement(); final PsiElement target = parameterReference.resolve(); if (!(target instanceof PsiParameter)) { return; } final PsiParameter parameter = (PsiParameter) target; final PsiElement declarationScope = parameter.getDeclarationScope(); final PsiElement body; if (declarationScope instanceof PsiMethod) { final PsiMethod method = (PsiMethod) declarationScope; body = method.getBody(); } else if (declarationScope instanceof PsiCatchSection) { final PsiCatchSection catchSection = (PsiCatchSection) declarationScope; body = catchSection.getCatchBlock(); } else if (declarationScope instanceof PsiLoopStatement) { final PsiLoopStatement forStatement = (PsiLoopStatement) declarationScope; final PsiStatement forBody = forStatement.getBody(); if (forBody instanceof PsiBlockStatement) { final PsiBlockStatement blockStatement = (PsiBlockStatement) forBody; body = blockStatement.getCodeBlock(); } else { body = forBody; } } else { return; } if (body == null) { return; } final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); final String parameterName = parameterReference.getText(); final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project); final String variableName = javaCodeStyleManager.suggestUniqueVariableName(parameterName, parameterReference, true); final SearchScope scope = parameter.getUseScope(); final Query<PsiReference> search = ReferencesSearch.search(parameter, scope); final PsiReference reference = search.findFirst(); if (reference == null) { return; } final PsiElement element = reference.getElement(); if (!(element instanceof PsiReferenceExpression)) { return; } final PsiReferenceExpression firstReference = (PsiReferenceExpression) element; final PsiElement[] children = body.getChildren(); final int startIndex; final int endIndex; if (body instanceof PsiCodeBlock) { startIndex = 1; endIndex = children.length - 1; } else { startIndex = 0; endIndex = children.length; } boolean newDeclarationCreated = false; final StringBuilder buffer = new StringBuilder(); for (int i = startIndex; i < endIndex; i++) { final PsiElement child = children[i]; newDeclarationCreated |= replaceVariableName(child, firstReference, variableName, parameterName, buffer); } final String replacementText; if (newDeclarationCreated) { replacementText = "{" + buffer + '}'; } else { final PsiType type = parameterReference.getType(); if (type == null) { return; } final String className = type.getCanonicalText(); replacementText = '{' + className + ' ' + variableName + " = " + parameterName + ';' + buffer + '}'; } final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory(); final PsiCodeBlock block = elementFactory.createCodeBlockFromText(replacementText, null); body.replace(block); codeStyleManager.reformat(declarationScope); }