@NotNull @Override public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { return new JavaElementVisitor() { @Override public void visitNewExpression(PsiNewExpression expression) { if (PsiDiamondTypeUtil.canCollapseToDiamond(expression, expression, null)) { final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference(); LOG.assertTrue(classReference != null); final PsiReferenceParameterList parameterList = classReference.getParameterList(); LOG.assertTrue(parameterList != null); final PsiElement firstChild = parameterList.getFirstChild(); final PsiElement lastChild = parameterList.getLastChild(); final TextRange range = new TextRange(firstChild != null && firstChild.getNode().getElementType() == JavaTokenType.LT ? 1 : 0, parameterList.getTextLength() - (lastChild != null && lastChild.getNode().getElementType() == JavaTokenType.GT ? 1 : 0)); holder.registerProblem(parameterList, "Explicit type argument #ref #loc can be replaced with <>", ProblemHighlightType.LIKE_UNUSED_SYMBOL, range, new ReplaceWithDiamondFix()); } } }; }
public static PsiExpression replaceExplicitWithDiamondWhenApplicable(final PsiExpression initializer, final PsiType expectedType) { if (initializer instanceof PsiNewExpression) { final PsiNewExpression newExpression = (PsiNewExpression)initializer; final PsiExpression tryToDetectDiamondNewExpr = ((PsiVariable)JavaPsiFacade.getElementFactory(initializer.getProject()) .createVariableDeclarationStatement("x", expectedType, initializer, initializer).getDeclaredElements()[0]) .getInitializer(); if (tryToDetectDiamondNewExpr instanceof PsiNewExpression && PsiDiamondTypeUtil.canCollapseToDiamond((PsiNewExpression)tryToDetectDiamondNewExpr, (PsiNewExpression)tryToDetectDiamondNewExpr, expectedType)) { final PsiElement paramList = PsiDiamondTypeUtil .replaceExplicitWithDiamond(newExpression.getClassOrAnonymousClassReference().getParameterList()); return PsiTreeUtil.getParentOfType(paramList, PsiNewExpression.class); } } return initializer; }
public static TypeConversionDescriptor wrapWithNewExpression(PsiType to, PsiType from, @Nullable PsiExpression expression, PsiElement context) { final String typeText = PsiDiamondTypeUtil.getCollapsedType(to, context); final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(to); final PsiClass atomicClass = resolveResult.getElement(); LOG.assertTrue(atomicClass != null); final PsiTypeParameter[] typeParameters = atomicClass.getTypeParameters(); if (typeParameters.length == 1) { final PsiType initial = resolveResult.getSubstitutor().substitute(typeParameters[0]); final PsiPrimitiveType unboxedInitialType = PsiPrimitiveType.getUnboxedType(initial); if (unboxedInitialType != null) { LOG.assertTrue(initial != null); if (from instanceof PsiPrimitiveType) { final PsiClassType boxedFromType = ((PsiPrimitiveType)from).getBoxedType(atomicClass); LOG.assertTrue(boxedFromType != null); if (!TypeConversionUtil.isAssignable(initial, boxedFromType)) { return new TypeConversionDescriptor("$val$", "new " + typeText + "((" + unboxedInitialType.getCanonicalText() + ")$val$)", expression); } } } } return new TypeConversionDescriptor("$val$", "new " + typeText + "($val$)", expression); }
public static PsiExpression replaceExplicitWithDiamondWhenApplicable(final PsiExpression initializer, final PsiType expectedType) { if (initializer instanceof PsiNewExpression) { final PsiNewExpression newExpression = (PsiNewExpression)initializer; final PsiExpression tryToDetectDiamondNewExpr = ((PsiVariable)JavaPsiFacade.getElementFactory(initializer.getProject()) .createVariableDeclarationStatement("x", expectedType, initializer).getDeclaredElements()[0]) .getInitializer(); if (tryToDetectDiamondNewExpr instanceof PsiNewExpression && PsiDiamondTypeUtil.canCollapseToDiamond((PsiNewExpression)tryToDetectDiamondNewExpr, (PsiNewExpression)tryToDetectDiamondNewExpr, expectedType)) { final PsiElement paramList = PsiDiamondTypeUtil .replaceExplicitWithDiamond(newExpression.getClassOrAnonymousClassReference().getParameterList()); return PsiTreeUtil.getParentOfType(paramList, PsiNewExpression.class); } } return initializer; }
@NotNull @Override public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { return new JavaElementVisitor() { @Override public void visitNewExpression(PsiNewExpression expression) { if (PsiDiamondTypeUtil.canCollapseToDiamond(expression, expression, null)) { final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference(); LOG.assertTrue(classReference != null); final PsiReferenceParameterList parameterList = classReference.getParameterList(); LOG.assertTrue(parameterList != null); holder.registerProblem(parameterList, "Explicit type argument #ref #loc can be replaced with <>", ProblemHighlightType.LIKE_UNUSED_SYMBOL, new ReplaceWithDiamondFix()); } } }; }
public static PsiExpression replaceExplicitWithDiamondWhenApplicable(final PsiExpression initializer, final PsiType expectedType) { if(initializer instanceof PsiNewExpression) { final PsiNewExpression newExpression = (PsiNewExpression) initializer; final PsiExpression tryToDetectDiamondNewExpr = ((PsiVariable) JavaPsiFacade.getElementFactory(initializer.getProject()) .createVariableDeclarationStatement("x", expectedType, initializer).getDeclaredElements()[0]).getInitializer(); if(tryToDetectDiamondNewExpr instanceof PsiNewExpression && PsiDiamondTypeUtil.canCollapseToDiamond((PsiNewExpression) tryToDetectDiamondNewExpr, (PsiNewExpression) tryToDetectDiamondNewExpr, expectedType)) { final PsiElement paramList = PsiDiamondTypeUtil.replaceExplicitWithDiamond(newExpression.getClassOrAnonymousClassReference() .getParameterList()); return PsiTreeUtil.getParentOfType(paramList, PsiNewExpression.class); } } return initializer; }
@Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return; final PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(PsiDiamondTypeUtil.replaceExplicitWithDiamond(element), PsiNewExpression.class); if (newExpression != null) { CodeStyleManager.getInstance(project).reformat(newExpression); } }
private static String createPipelineHeadText(PsiExpression collectionExpression, boolean force) { if (collectionExpression instanceof PsiNewExpression) { final PsiDiamondType.DiamondInferenceResult diamondResolveResult = PsiDiamondTypeImpl.resolveInferredTypesNoCheck((PsiNewExpression)collectionExpression, collectionExpression); if (!diamondResolveResult.getInferredTypes().isEmpty()) { collectionExpression = PsiDiamondTypeUtil.expandTopLevelDiamondsInside(collectionExpression); } } else if (collectionExpression instanceof PsiMethodCallExpression) { final PsiType currentType = collectionExpression.getType(); if (currentType == null) { return null; } final PsiExpression copiedExpression = (PsiExpression) collectionExpression.copy(); final PsiType newType = copiedExpression.getType(); if (!currentType.equals(newType)) { collectionExpression = AddTypeArgumentsFix.addTypeArguments(copiedExpression, currentType); if (collectionExpression == null) { return null; } } } final PsiType type = collectionExpression.getType(); if (type instanceof PsiClassType) { final PsiClass resolved = ((PsiClassType)type).resolve(); LOG.assertTrue(resolved != null && resolved.getQualifiedName() != null, type); if (InheritanceUtil.isInheritor(resolved, CommonClassNames.JAVA_UTIL_COLLECTION)) { return collectionExpression.getText() + ".stream()"; } else { return "java.util.stream.StreamSupport.stream(" + collectionExpression.getText() + ".spliterator(), false)"; } } else if (type instanceof PsiArrayType) { return CommonClassNames.JAVA_UTIL_ARRAYS + ".stream(" + collectionExpression.getText() + ")"; } else if (force) { return collectionExpression.getText() + ".stream()"; } throw new AssertionError("type: " + type + " is unexpected for expression: " + collectionExpression.getText()); }
static void replaceNewExpressionType(final Project project, final PsiNewExpression expression, final Map.Entry<TypeMigrationUsageInfo, PsiType> info) { final PsiType changeType = info.getValue(); if (changeType != null) { try { final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference(); final PsiType componentType = changeType.getDeepComponentType(); if (classReference != null) { final PsiElement psiElement = replaceTypeWithClassReferenceOrKeyword(project, componentType, classReference); final PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(psiElement, PsiNewExpression.class); if (newExpression != null && PsiDiamondTypeUtil.canCollapseToDiamond(newExpression, newExpression, changeType)) { final PsiJavaCodeReferenceElement anonymousClassReference = newExpression.getClassOrAnonymousClassReference(); if (anonymousClassReference != null) { PsiDiamondTypeUtil.replaceExplicitWithDiamond(anonymousClassReference.getParameterList()); } } } else { final PsiElement typeKeyword = getTypeKeyword(expression); if (typeKeyword != null) { replaceTypeWithClassReferenceOrKeyword(project, componentType, typeKeyword); } } } catch (IncorrectOperationException e) { LOG.error(e); } } }
private static PsiExpression expandDiamondsWhenNeeded(PsiExpression thenValue, PsiType requiredType) { if (thenValue instanceof PsiNewExpression) { if (!PsiDiamondTypeUtil.canChangeContextForDiamond((PsiNewExpression)thenValue, requiredType)) { return PsiDiamondTypeUtil.expandTopLevelDiamondsInside(thenValue); } } return thenValue; }
static boolean tryToReplaceWithDiamond(PsiNewExpression newExpression, @Nullable PsiType changeType) { if(newExpression != null && PsiDiamondTypeUtil.canCollapseToDiamond(newExpression, newExpression, changeType)) { final PsiJavaCodeReferenceElement anonymousClassReference = newExpression.getClassOrAnonymousClassReference(); if(anonymousClassReference != null) { PsiDiamondTypeUtil.replaceExplicitWithDiamond(anonymousClassReference.getParameterList()); } return true; } return false; }
private void doRefactoring() throws IncorrectOperationException { calculateTypeParametersToCreate(); PsiClass aClass = createClass(myNewClassName); myTargetClass.add(aClass); PsiNewExpression newExpr = (PsiNewExpression) myAnonClass.getParent(); @NonNls StringBuffer buf = new StringBuffer(); buf.append("new "); buf.append(aClass.getName()); if (!myTypeParametersToCreate.isEmpty()) { buf.append("<"); int idx = 0; //noinspection ForLoopThatDoesntUseLoopVariable for (Iterator<PsiTypeParameter> it = myTypeParametersToCreate.iterator(); it.hasNext(); idx++) { if (idx > 0) buf.append(", "); String typeParamName = it.next().getName(); buf.append(typeParamName); } buf.append(">"); } buf.append("("); boolean isFirstParameter = true; for (VariableInfo info : myVariableInfos) { if (info.passAsParameter) { if (isFirstParameter) { isFirstParameter = false; } else { buf.append(","); } buf.append(info.variable.getName()); } } buf.append(")"); PsiNewExpression newClassExpression = (PsiNewExpression)JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory().createExpressionFromText(buf.toString(), null); newClassExpression = (PsiNewExpression)newExpr.replace(newClassExpression); if (PsiDiamondTypeUtil.canCollapseToDiamond(newClassExpression, newClassExpression, newClassExpression.getType())) { PsiDiamondTypeUtil.replaceExplicitWithDiamond(newClassExpression.getClassOrAnonymousClassReference().getParameterList()); } }
@Override protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { PsiDiamondTypeUtil.replaceDiamondWithExplicitTypes(element); }
@Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { PsiDiamondTypeUtil.replaceExplicitWithDiamond(descriptor.getPsiElement()); }
private static void changeNewOperatorType(PsiNewExpression originalExpression, PsiType toType, final Editor editor) throws IncorrectOperationException { PsiNewExpression newExpression; PsiElementFactory factory = JavaPsiFacade.getInstance(originalExpression.getProject()).getElementFactory(); int caretOffset; TextRange selection; if (toType instanceof PsiArrayType) { final PsiExpression[] originalExpressionArrayDimensions = originalExpression.getArrayDimensions(); caretOffset = 0; @NonNls String text = "new " + toType.getDeepComponentType().getCanonicalText() + "["; if (originalExpressionArrayDimensions.length > 0) { text += originalExpressionArrayDimensions[0].getText(); } else { text += "0"; caretOffset = -2; } text += "]"; for (int i = 1; i < toType.getArrayDimensions(); i++) { text += "["; String arrayDimension = ""; if (originalExpressionArrayDimensions.length > i) { arrayDimension = originalExpressionArrayDimensions[i].getText(); text += arrayDimension; } text += "]"; if (caretOffset < 0) { caretOffset -= arrayDimension.length() + 2; } } newExpression = (PsiNewExpression)factory.createExpressionFromText(text, originalExpression); if (caretOffset < 0) { selection = new TextRange(caretOffset, caretOffset+1); } else { selection = null; } } else { final PsiAnonymousClass anonymousClass = originalExpression.getAnonymousClass(); newExpression = (PsiNewExpression)factory.createExpressionFromText("new " + toType.getCanonicalText() + "()" + (anonymousClass != null ? "{}" : ""), originalExpression); PsiExpressionList argumentList = originalExpression.getArgumentList(); if (argumentList == null) return; newExpression.getArgumentList().replace(argumentList); if (anonymousClass == null) { //just to prevent useless inference if (PsiDiamondTypeUtil.canCollapseToDiamond(newExpression, originalExpression, toType)) { final PsiElement paramList = PsiDiamondTypeUtil.replaceExplicitWithDiamond(newExpression.getClassOrAnonymousClassReference().getParameterList()); newExpression = PsiTreeUtil.getParentOfType(paramList, PsiNewExpression.class); } } if (anonymousClass != null) { PsiAnonymousClass newAnonymousClass = newExpression.getAnonymousClass(); final PsiElement childInside = anonymousClass.getLBrace().getNextSibling(); if (childInside != null) { newAnonymousClass.addRange(childInside, anonymousClass.getRBrace().getPrevSibling()); } } selection = null; caretOffset = -1; } PsiElement element = originalExpression.replace(newExpression); editor.getCaretModel().moveToOffset(element.getTextRange().getEndOffset() + caretOffset); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); if (selection != null) { selection = selection.shiftRight(element.getTextRange().getEndOffset()); editor.getSelectionModel().setSelection(selection.getStartOffset(), selection.getEndOffset()); } }