@Nullable private static PsiType guessElementTypeFromReference( MethodPatternMap methodPatternMap, PsiElement ref, TextRange rangeToIgnore) { PsiElement refParent = ref.getParent(); if (refParent instanceof PsiReferenceExpression) { PsiReferenceExpression parentExpr = (PsiReferenceExpression) refParent; if (ref.equals(parentExpr.getQualifierExpression()) && parentExpr.getParent() instanceof PsiMethodCallExpression) { String methodName = parentExpr.getReferenceName(); PsiMethodCallExpression methodCall = (PsiMethodCallExpression) parentExpr.getParent(); PsiExpression[] args = methodCall.getArgumentList().getExpressions(); MethodPattern pattern = methodPatternMap.findPattern(methodName, args.length); if (pattern != null) { if (pattern.parameterIndex < 0) { // return value if (methodCall.getParent() instanceof PsiTypeCastExpression && (rangeToIgnore == null || !rangeToIgnore.contains(methodCall.getTextRange()))) { return ((PsiTypeCastExpression) methodCall.getParent()).getType(); } } else { return args[pattern.parameterIndex].getType(); } } } } return null; }
@Override public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiIdentifier name = (PsiIdentifier) descriptor.getPsiElement(); final PsiReferenceExpression expression = (PsiReferenceExpression) name.getParent(); if (expression == null) { return; } final PsiMethodCallExpression call = (PsiMethodCallExpression) expression.getParent(); final String methodName = expression.getReferenceName(); if (call == null) { return; } final PsiMethod method = call.resolveMethod(); if (method == null) { return; } final PsiClass containingClass = method.getContainingClass(); final PsiExpressionList argumentList = call.getArgumentList(); if (containingClass == null) { return; } final String containingClassName = containingClass.getQualifiedName(); final String argText = argumentList.getText(); PsiReplacementUtil.replaceExpressionAndShorten( call, containingClassName + '.' + methodName + argText); }
@Nullable public static PsiField getParameterAssignedToField(final PsiParameter parameter) { for (PsiReference reference : ReferencesSearch.search( parameter, new LocalSearchScope(parameter.getDeclarationScope()), false)) { if (!(reference instanceof PsiReferenceExpression)) continue; final PsiReferenceExpression expression = (PsiReferenceExpression) reference; if (!(expression.getParent() instanceof PsiAssignmentExpression)) continue; final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) expression.getParent(); if (assignmentExpression.getRExpression() != expression) continue; final PsiExpression lExpression = assignmentExpression.getLExpression(); if (!(lExpression instanceof PsiReferenceExpression)) continue; final PsiElement element = ((PsiReferenceExpression) lExpression).resolve(); if (element instanceof PsiField) return (PsiField) element; } return null; }
public static boolean insertTail( InsertionContext context, LookupElement item, TailType tailType, boolean hasTail) { TailType toInsert = tailType; LookupItem<?> lookupItem = item.as(LookupItem.CLASS_CONDITION_KEY); if (lookupItem == null || lookupItem.getAttribute(LookupItem.TAIL_TYPE_ATTR) != TailType.UNKNOWN) { if (!hasTail && item.getObject() instanceof PsiMethod && ((PsiMethod) item.getObject()).getReturnType() == PsiType.VOID) { PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments(); if (psiElement() .beforeLeaf(psiElement().withText(".")) .accepts(context.getFile().findElementAt(context.getTailOffset() - 1))) { return false; } boolean insertAdditionalSemicolon = true; final PsiReferenceExpression referenceExpression = PsiTreeUtil.getTopmostParentOfType( context.getFile().findElementAt(context.getStartOffset()), PsiReferenceExpression.class); if (referenceExpression instanceof PsiMethodReferenceExpression && LambdaHighlightingUtil.insertSemicolon(referenceExpression.getParent())) { insertAdditionalSemicolon = false; } else if (referenceExpression != null) { PsiElement parent = referenceExpression.getParent(); if (parent instanceof PsiMethodCallExpression) { parent = parent.getParent(); } if (parent instanceof PsiLambdaExpression && !LambdaHighlightingUtil.insertSemicolonAfter((PsiLambdaExpression) parent)) { insertAdditionalSemicolon = false; } } if (insertAdditionalSemicolon) { toInsert = TailType.SEMICOLON; } } } toInsert.processTail(context.getEditor(), context.getTailOffset()); return true; }
@Override protected LocalQuickFix createRemoveAssignmentFix(PsiReferenceExpression expression) { final PsiElement parent = expression.getParent(); if (parent instanceof PsiVariable) { final PsiVariable variable = (PsiVariable) parent; if (variable.hasModifierProperty(PsiModifier.FINAL)) { return null; } } return new RemoveSillyAssignmentFix(); }
@Override public void visitReferenceExpression(PsiReferenceExpression expression) { if (argumentsContainCatchParameter || !visited.add(expression)) { return; } super.visitReferenceExpression(expression); final PsiElement target = expression.resolve(); if (!parameter.equals(target)) { if (target instanceof PsiLocalVariable) { final PsiLocalVariable variable = (PsiLocalVariable) target; final Query<PsiReference> query = ReferencesSearch.search(variable, variable.getUseScope(), false); query.forEach( reference -> { final PsiElement element = reference.getElement(); final PsiElement parent = PsiTreeUtil.skipParentsOfType(element, PsiParenthesizedExpression.class); if (!(parent instanceof PsiReferenceExpression)) { return true; } final PsiElement grandParent = parent.getParent(); if (!(grandParent instanceof PsiMethodCallExpression)) { return true; } final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) grandParent; final PsiExpressionList argumentList = methodCallExpression.getArgumentList(); final PsiExpression[] arguments = argumentList.getExpressions(); for (PsiExpression argument : arguments) { argument.accept(ReferenceFinder.this); } return true; }); final PsiExpression initializer = variable.getInitializer(); if (initializer != null) { initializer.accept(this); } } return; } if (ignoreGetMessage) { argumentsContainCatchParameter = true; } else { final PsiElement parent = expression.getParent(); if (parent instanceof PsiReferenceExpression) { final PsiElement grandParent = parent.getParent(); if (grandParent instanceof PsiMethodCallExpression) { return; } } argumentsContainCatchParameter = true; } }
@Nullable public NonCodeUsageSearchInfo findUsages( @NotNull final PsiElement element, @NotNull final PsiElement[] allElementsToDelete, @NotNull final List<UsageInfo> usages) { Condition<PsiElement> insideDeletedCondition = getUsageInsideDeletedFilter(allElementsToDelete); if (element instanceof PsiClass) { findClassUsages((PsiClass) element, allElementsToDelete, usages); if (element instanceof PsiTypeParameter) { findTypeParameterExternalUsages((PsiTypeParameter) element, usages); } } else if (element instanceof PsiMethod) { insideDeletedCondition = findMethodUsages((PsiMethod) element, allElementsToDelete, usages); } else if (element instanceof PsiField) { insideDeletedCondition = findFieldUsages((PsiField) element, usages, allElementsToDelete); } else if (element instanceof PsiParameter) { LOG.assertTrue(((PsiParameter) element).getDeclarationScope() instanceof PsiMethod); findParameterUsages((PsiParameter) element, usages); } else if (element instanceof PsiLocalVariable) { for (PsiReference reference : ReferencesSearch.search(element)) { PsiReferenceExpression referencedElement = (PsiReferenceExpression) reference.getElement(); final PsiStatement statement = PsiTreeUtil.getParentOfType(referencedElement, PsiStatement.class); boolean isSafeToDelete = PsiUtil.isAccessedForWriting(referencedElement); boolean hasSideEffects = false; if (PsiUtil.isOnAssignmentLeftHand(referencedElement)) { hasSideEffects = RemoveUnusedVariableUtil.checkSideEffects( ((PsiAssignmentExpression) referencedElement.getParent()).getRExpression(), ((PsiLocalVariable) element), new ArrayList<>()); } usages.add( new SafeDeleteReferenceJavaDeleteUsageInfo( statement, element, isSafeToDelete && !hasSideEffects)); } } return new NonCodeUsageSearchInfo(insideDeletedCondition, element); }
private static boolean isLeftSideOfSimpleAssignment(PsiReferenceExpression reference) { if (reference == null) { return false; } final PsiElement parent = reference.getParent(); if (!(parent instanceof PsiAssignmentExpression)) { return false; } final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) parent; final IElementType tokenType = assignmentExpression.getOperationTokenType(); if (!JavaTokenType.EQ.equals(tokenType)) { return false; } final PsiExpression lExpression = assignmentExpression.getLExpression(); if (!reference.equals(lExpression)) { return false; } final PsiExpression rExpression = assignmentExpression.getRExpression(); if (rExpression instanceof PsiAssignmentExpression) { return false; } final PsiElement grandParent = parent.getParent(); return grandParent instanceof PsiExpressionStatement; }
private void findUsagesForMethod( PsiMethod overridingMethod, List<FixableUsageInfo> usages, boolean changeSignature) { final PsiCodeBlock body = overridingMethod.getBody(); final String baseParameterName = StringUtil.decapitalize(className); final String fixedParamName = body != null ? JavaCodeStyleManager.getInstance(myProject) .suggestUniqueVariableName(baseParameterName, body.getLBrace(), true) : JavaCodeStyleManager.getInstance(myProject) .propertyNameToVariableName(baseParameterName, VariableKind.PARAMETER); usages.add( new MergeMethodArguments( overridingMethod, className, packageName, fixedParamName, paramsToMerge, typeParams, keepMethodAsDelegate, myCreateInnerClass ? method.getContainingClass() : null, changeSignature)); final ParamUsageVisitor visitor = new ParamUsageVisitor(overridingMethod, paramsToMerge); overridingMethod.accept(visitor); final Set<PsiReferenceExpression> values = visitor.getParameterUsages(); for (PsiReferenceExpression paramUsage : values) { final PsiParameter parameter = (PsiParameter) paramUsage.resolve(); assert parameter != null; final PsiMethod containingMethod = (PsiMethod) parameter.getDeclarationScope(); final int index = containingMethod.getParameterList().getParameterIndex(parameter); final PsiParameter replacedParameter = method.getParameterList().getParameters()[index]; final ParameterChunk parameterChunk = ParameterChunk.getChunkByParameter(parameter, parameters); @NonNls String getter = parameterChunk != null ? parameterChunk.getter : null; final String paramName = parameterChunk != null ? parameterChunk.parameter.name : replacedParameter.getName(); final PsiType paramType = parameterChunk != null ? parameterChunk.parameter.type : replacedParameter.getType(); if (getter == null) { getter = GenerateMembersUtil.suggestGetterName(paramName, paramType, myProject); paramsNeedingGetters.add(replacedParameter); } @NonNls String setter = parameterChunk != null ? parameterChunk.setter : null; if (setter == null) { setter = GenerateMembersUtil.suggestSetterName(paramName, paramType, myProject); } if (RefactoringUtil.isPlusPlusOrMinusMinus(paramUsage.getParent())) { usages.add( new ReplaceParameterIncrementDecrement(paramUsage, fixedParamName, setter, getter)); if (parameterChunk == null || parameterChunk.setter == null) { paramsNeedingSetters.add(replacedParameter); } } else if (RefactoringUtil.isAssignmentLHS(paramUsage)) { usages.add( new ReplaceParameterAssignmentWithCall(paramUsage, fixedParamName, setter, getter)); if (parameterChunk == null || parameterChunk.setter == null) { paramsNeedingSetters.add(replacedParameter); } } else { usages.add(new ReplaceParameterReferenceWithCall(paramUsage, fixedParamName, getter)); } } }
@Override public void visitReferenceExpression(PsiReferenceExpression expression) { if (myWritten && myRead) { return; } super.visitReferenceExpression(expression); final PsiElement target = expression.resolve(); if (target != myVariable) { return; } if (PsiUtil.isAccessedForWriting(expression)) { final PsiElement parent = PsiTreeUtil.skipParentsOfType(expression, PsiParenthesizedExpression.class); if (parent instanceof PsiAssignmentExpression) { final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) parent; final PsiExpression rhs = assignmentExpression.getRExpression(); if (isComplexArrayExpression(rhs)) { myWritten = true; myRead = true; } else if (!isSimpleArrayExpression(rhs)) { myWritten = true; } } return; } myIsReferenced = true; PsiElement parent = getParent(expression); if (parent instanceof PsiArrayAccessExpression) { PsiArrayAccessExpression arrayAccessExpression = (PsiArrayAccessExpression) parent; parent = getParent(parent); while (parent instanceof PsiArrayAccessExpression) { arrayAccessExpression = (PsiArrayAccessExpression) parent; parent = getParent(parent); } final PsiType type = arrayAccessExpression.getType(); if (type != null) { final int dimensions = type.getArrayDimensions(); if (dimensions > 0 && dimensions != myVariable.getType().getArrayDimensions()) { myWritten = true; } } if (PsiUtil.isAccessedForWriting(arrayAccessExpression)) { myWritten = true; } if (PsiUtil.isAccessedForReading(arrayAccessExpression)) { myRead = true; } } else if (parent instanceof PsiReferenceExpression) { final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) parent; final String name = referenceExpression.getReferenceName(); if ("length".equals(name) || ("clone".equals(name) && referenceExpression.getParent() instanceof PsiMethodCallExpression)) { myRead = true; } } else if (parent instanceof PsiForeachStatement) { final PsiForeachStatement foreachStatement = (PsiForeachStatement) parent; final PsiExpression iteratedValue = foreachStatement.getIteratedValue(); if (PsiTreeUtil.isAncestor(iteratedValue, expression, false)) { myRead = true; } } else if (parent instanceof PsiExpressionList) { final PsiExpressionList expressionList = (PsiExpressionList) parent; parent = parent.getParent(); if (parent instanceof PsiMethodCallExpression) { final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) parent; final PsiMethod method = methodCallExpression.resolveMethod(); if (method != null) { final PsiClass aClass = method.getContainingClass(); if (aClass != null) { final String methodName = method.getName(); final String qualifiedName = aClass.getQualifiedName(); if ("java.lang.System".equals(qualifiedName)) { if ("arraycopy".equals(methodName)) { final PsiExpression[] expressions = expressionList.getExpressions(); if (expressions.length == 5) { if (PsiTreeUtil.isAncestor(expressions[0], expression, false)) { myRead = true; return; } else if (PsiTreeUtil.isAncestor(expressions[2], expression, false)) { myWritten = true; return; } } } } else if (CommonClassNames.JAVA_UTIL_ARRAYS.equals(qualifiedName)) { if ("fill".equals(methodName) || "parallelPrefix".equals(methodName) || "parallelSetAll".equals(methodName) || "parallelSort".equals(methodName) || "setAll".equals(methodName) || "sort".equals(methodName)) { myWritten = true; } else { myRead = true; } return; } } } } myRead = true; myWritten = true; } else { myWritten = true; myRead = true; } }
private static void reportConstantReferenceValues( ProblemsHolder holder, StandardInstructionVisitor visitor, Set<PsiElement> reportedAnchors) { for (Pair<PsiReferenceExpression, DfaConstValue> pair : visitor.getConstantReferenceValues()) { PsiReferenceExpression ref = pair.first; if (ref.getParent() instanceof PsiReferenceExpression || !reportedAnchors.add(ref)) { continue; } final Object value = pair.second.getValue(); PsiVariable constant = pair.second.getConstant(); final String presentableName = constant != null ? constant.getName() : String.valueOf(value); final String exprText = String.valueOf(value); if (presentableName == null || exprText == null) { continue; } holder.registerProblem( ref, "Value <code>#ref</code> #loc is always '" + presentableName + "'", new LocalQuickFix() { @NotNull @Override public String getName() { return "Replace with '" + presentableName + "'"; } @NotNull @Override public String getFamilyName() { return "Replace with constant value"; } @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { if (!FileModificationService.getInstance() .preparePsiElementsForWrite(descriptor.getPsiElement())) { return; } PsiElement problemElement = descriptor.getPsiElement(); if (problemElement == null) return; PsiMethodCallExpression call = problemElement.getParent() instanceof PsiExpressionList && problemElement.getParent().getParent() instanceof PsiMethodCallExpression ? (PsiMethodCallExpression) problemElement.getParent().getParent() : null; PsiMethod targetMethod = call == null ? null : call.resolveMethod(); JavaPsiFacade facade = JavaPsiFacade.getInstance(project); problemElement.replace( facade.getElementFactory().createExpressionFromText(exprText, null)); if (targetMethod != null) { ExtractMethodUtil.addCastsToEnsureResolveTarget(targetMethod, call); } } }); } }
private void findUsagesForField(PsiField field, List<FixableUsageInfo> usages) { final PsiManager psiManager = field.getManager(); final Project project = psiManager.getProject(); final GlobalSearchScope scope = GlobalSearchScope.allScope(project); final String qualifiedName = getQualifiedName(); @NonNls String getter = null; if (myGenerateAccessors) { getter = GenerateMembersUtil.suggestGetterName(field); } else { final PsiMethod fieldGetter = PropertyUtil.findPropertyGetter(sourceClass, field.getName(), false, false); if (fieldGetter != null && isInMovedElement(fieldGetter)) { getter = fieldGetter.getName(); } } @NonNls String setter = null; if (myGenerateAccessors) { setter = GenerateMembersUtil.suggestSetterName(field); } else { final PsiMethod fieldSetter = PropertyUtil.findPropertySetter(sourceClass, field.getName(), false, false); if (fieldSetter != null && isInMovedElement(fieldSetter)) { setter = fieldSetter.getName(); } } final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC); for (PsiReference reference : ReferencesSearch.search(field, scope)) { final PsiElement element = reference.getElement(); if (isInMovedElement(element)) { continue; } if (element instanceof PsiReferenceExpression) { final PsiReferenceExpression exp = (PsiReferenceExpression) element; if (RefactoringUtil.isPlusPlusOrMinusMinus(exp.getParent())) { usages.add( isStatic ? new ReplaceStaticVariableIncrementDecrement(exp, qualifiedName) : new ReplaceInstanceVariableIncrementDecrement( exp, delegateFieldName, setter, getter, field.getName())); } else if (RefactoringUtil.isAssignmentLHS(exp)) { usages.add( isStatic ? new ReplaceStaticVariableAssignment(exp, qualifiedName) : new ReplaceInstanceVariableAssignment( PsiTreeUtil.getParentOfType(exp, PsiAssignmentExpression.class), delegateFieldName, setter, getter, field.getName())); } else { usages.add( isStatic ? new ReplaceStaticVariableAccess( exp, qualifiedName, enumConstants.contains(field)) : new ReplaceInstanceVariableAccess( exp, delegateFieldName, getter, field.getName())); } if (!isStatic) { delegationRequired = true; } } else if (element instanceof PsiDocTagValue) { usages.add(new BindJavadocReference(element, qualifiedName, field.getName())); } } }
@Override public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) { super.visitClassObjectAccessExpression(expression); PsiElement parent = expression.getParent(); if (parent instanceof PsiReferenceExpression) { final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) parent; if (!expression.equals(referenceExpression.getQualifierExpression())) { return; } @NonNls final String name = referenceExpression.getReferenceName(); if (!"getName".equals(name)) { return; } final PsiElement grandParent = referenceExpression.getParent(); if (!(grandParent instanceof PsiMethodCallExpression)) { return; } final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) grandParent; final PsiExpressionList list = methodCallExpression.getArgumentList(); if (list.getExpressions().length != 0) { return; } parent = methodCallExpression.getParent(); } if (!(parent instanceof PsiExpressionList)) { return; } final PsiElement grandParent = parent.getParent(); if (!(grandParent instanceof PsiMethodCallExpression)) { return; } final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) grandParent; final PsiExpressionList argumentList = methodCallExpression.getArgumentList(); final PsiExpression[] expressions = argumentList.getExpressions(); if (expressions.length != 1) { return; } final PsiClass containingClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class); if (containingClass == null) { return; } final String containingClassName = containingClass.getName(); if (containingClassName == null) { return; } final PsiMethod method = methodCallExpression.resolveMethod(); if (method == null) { return; } final PsiClass aClass = method.getContainingClass(); if (aClass == null) { return; } final String className = aClass.getQualifiedName(); final int index = loggerFactoryClassNames.indexOf(className); if (index < 0) { return; } final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); final String referenceName = methodExpression.getReferenceName(); final String loggerFactoryMethodName = loggerFactoryMethodNames.get(index); if (!loggerFactoryMethodName.equals(referenceName)) { return; } final PsiTypeElement operand = expression.getOperand(); final PsiType type = operand.getType(); if (!(type instanceof PsiClassType)) { return; } final PsiClassType classType = (PsiClassType) type; final PsiClass initializerClass = classType.resolve(); if (initializerClass == null) { return; } if (containingClass.equals(initializerClass)) { return; } registerError(expression, containingClassName); }
@Override protected void doFix(Project project, ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); final PsiClass aClass = ClassUtils.getContainingStaticClass(element); if (aClass == null) { return; } final PsiElement parent = element.getParent(); if (!(parent instanceof PsiReferenceExpression)) { return; } final PsiReferenceExpression methodExpression = (PsiReferenceExpression) parent; final PsiElement grandParent = methodExpression.getParent(); if (!(grandParent instanceof PsiMethodCallExpression)) { return; } final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) grandParent; final PsiExpressionList list = methodCallExpression.getArgumentList(); final PsiExpression[] expressions = list.getExpressions(); @NonNls final StringBuilder fieldText = new StringBuilder( "private static final java.util.regex.Pattern PATTERN = java.util.regex.Pattern.compile("); final int expressionsLength = expressions.length; if (expressionsLength > 0) { fieldText.append(expressions[0].getText()); } @NonNls final String methodName = methodExpression.getReferenceName(); final boolean literalReplacement = "replace".equals(methodName); if (literalReplacement) { fieldText.append(", java.util.regex.Pattern.LITERAL"); } fieldText.append(");"); @NonNls final StringBuilder expressionText = new StringBuilder("PATTERN."); final PsiExpression qualifier = methodExpression.getQualifierExpression(); @NonNls final String qualifierText = (qualifier == null) ? "this" : qualifier.getText(); if ("split".equals(methodName)) { expressionText.append(methodName); expressionText.append('('); expressionText.append(qualifierText); for (int i = 1; i < expressionsLength; i++) { expressionText.append(',').append(expressions[i].getText()); } expressionText.append(')'); } else { expressionText.append("matcher(").append(qualifierText).append(")."); if (literalReplacement) { expressionText.append("replaceAll"); } else { expressionText.append(methodName); } expressionText.append('('); if (literalReplacement) { expressionText.append("java.util.regex.Matcher.quoteReplacement("); } if (expressionsLength > 1) { expressionText.append(expressions[1].getText()); for (int i = 2; i < expressionsLength; i++) { expressionText.append(',').append(expressions[i].getText()); } } if (literalReplacement) { expressionText.append(')'); } expressionText.append(')'); } final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); final PsiField newField = factory.createFieldFromText(fieldText.toString(), element); final PsiElement field = aClass.add(newField); final PsiExpression newExpression = factory.createExpressionFromText(expressionText.toString(), element); PsiMethodCallExpression newMethodCallExpression = (PsiMethodCallExpression) methodCallExpression.replace(newExpression); newMethodCallExpression = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(newMethodCallExpression); final PsiReferenceExpression reference = getReference(newMethodCallExpression); HighlightUtils.showRenameTemplate(aClass, (PsiNameIdentifierOwner) field, reference); }
protected void changeExternalUsage(UsageInfo usage, PsiElementFactory factory) throws IncorrectOperationException { final PsiElement element = usage.getElement(); if (!(element instanceof PsiReferenceExpression)) return; PsiReferenceExpression methodRef = (PsiReferenceExpression) element; PsiElement parent = methodRef.getParent(); PsiExpression instanceRef; instanceRef = methodRef.getQualifierExpression(); PsiElement newQualifier; final PsiClass memberClass = myMember.getContainingClass(); if (instanceRef == null || instanceRef instanceof PsiSuperExpression) { PsiClass contextClass = PsiTreeUtil.getParentOfType(element, PsiClass.class); if (!InheritanceUtil.isInheritorOrSelf(contextClass, memberClass, true)) { instanceRef = factory.createExpressionFromText(memberClass.getQualifiedName() + ".this", null); } else { instanceRef = factory.createExpressionFromText("this", null); } newQualifier = null; } else { newQualifier = factory.createReferenceExpression(memberClass); } if (mySettings.getNewParametersNumber() > 1) { int copyingSafetyLevel = RefactoringUtil.verifySafeCopyExpression(instanceRef); if (copyingSafetyLevel == RefactoringUtil.EXPR_COPY_PROHIBITED) { String tempVar = RefactoringUtil.createTempVar(instanceRef, parent, true); instanceRef = factory.createExpressionFromText(tempVar, null); } } PsiElement anchor = null; PsiExpressionList argList = null; PsiExpression[] exprs = PsiExpression.EMPTY_ARRAY; if (parent instanceof PsiMethodCallExpression) { argList = ((PsiMethodCallExpression) parent).getArgumentList(); exprs = argList.getExpressions(); if (mySettings.isMakeClassParameter()) { if (exprs.length > 0) { anchor = argList.addBefore(instanceRef, exprs[0]); } else { anchor = argList.add(instanceRef); } } } if (mySettings.isMakeFieldParameters()) { List<Settings.FieldParameter> parameters = mySettings.getParameterOrderList(); for (Settings.FieldParameter fieldParameter : parameters) { PsiReferenceExpression fieldRef; if (newQualifier != null) { fieldRef = (PsiReferenceExpression) factory.createExpressionFromText("a." + fieldParameter.field.getName(), null); fieldRef.getQualifierExpression().replace(instanceRef); } else { fieldRef = (PsiReferenceExpression) factory.createExpressionFromText(fieldParameter.field.getName(), null); } if (anchor != null) { anchor = argList.addAfter(fieldRef, anchor); } else if (argList != null) { if (exprs.length > 0) { anchor = argList.addBefore(fieldRef, exprs[0]); } else { anchor = argList.add(fieldRef); } } } } if (newQualifier != null) { methodRef.getQualifierExpression().replace(newQualifier); } }
public boolean processUsage( @NotNull EncapsulateFieldUsageInfo usage, @NotNull EncapsulateFieldsDescriptor descriptor, PsiMethod setter, PsiMethod getter) { final PsiElement element = usage.getElement(); if (!(element instanceof PsiReferenceExpression)) return false; final FieldDescriptor fieldDescriptor = usage.getFieldDescriptor(); PsiField field = fieldDescriptor.getField(); boolean processGet = descriptor.isToEncapsulateGet(); boolean processSet = descriptor.isToEncapsulateSet() && !field.hasModifierProperty(PsiModifier.FINAL); if (!processGet && !processSet) return true; PsiElementFactory factory = JavaPsiFacade.getInstance(descriptor.getTargetClass().getProject()).getElementFactory(); try { final PsiReferenceExpression expr = (PsiReferenceExpression) element; final PsiElement parent = expr.getParent(); if (parent instanceof PsiAssignmentExpression && expr.equals(((PsiAssignmentExpression) parent).getLExpression())) { PsiAssignmentExpression assignment = (PsiAssignmentExpression) parent; if (assignment.getRExpression() == null) return true; PsiJavaToken opSign = assignment.getOperationSign(); IElementType opType = opSign.getTokenType(); if (opType == JavaTokenType.EQ) { { if (!processSet) return true; final PsiExpression setterArgument = assignment.getRExpression(); PsiMethodCallExpression methodCall = createSetterCall( fieldDescriptor, setterArgument, expr, descriptor.getTargetClass(), setter); if (methodCall != null) { assignment.replace(methodCall); } // TODO: check if value is used!!! } } else if (opType == JavaTokenType.ASTERISKEQ || opType == JavaTokenType.DIVEQ || opType == JavaTokenType.PERCEQ || opType == JavaTokenType.PLUSEQ || opType == JavaTokenType.MINUSEQ || opType == JavaTokenType.LTLTEQ || opType == JavaTokenType.GTGTEQ || opType == JavaTokenType.GTGTGTEQ || opType == JavaTokenType.ANDEQ || opType == JavaTokenType.OREQ || opType == JavaTokenType.XOREQ) { { // Q: side effects of qualifier??! String opName = opSign.getText(); LOG.assertTrue(StringUtil.endsWithChar(opName, '=')); opName = opName.substring(0, opName.length() - 1); PsiExpression getExpr = expr; if (processGet) { final PsiMethodCallExpression getterCall = createGetterCall(fieldDescriptor, expr, descriptor.getTargetClass(), getter); if (getterCall != null) { getExpr = getterCall; } } @NonNls String text = "a" + opName + "b"; PsiBinaryExpression binExpr = (PsiBinaryExpression) factory.createExpressionFromText(text, expr); binExpr.getLOperand().replace(getExpr); binExpr.getROperand().replace(assignment.getRExpression()); PsiExpression setExpr; if (processSet) { setExpr = createSetterCall( fieldDescriptor, binExpr, expr, descriptor.getTargetClass(), setter); } else { text = "a = b"; PsiAssignmentExpression assignment1 = (PsiAssignmentExpression) factory.createExpressionFromText(text, null); assignment1.getLExpression().replace(expr); assignment1.getRExpression().replace(binExpr); setExpr = assignment1; } assignment.replace(setExpr); // TODO: check if value is used!!! } } } else if (RefactoringUtil.isPlusPlusOrMinusMinus(parent)) { IElementType sign; if (parent instanceof PsiPrefixExpression) { sign = ((PsiPrefixExpression) parent).getOperationTokenType(); } else { sign = ((PsiPostfixExpression) parent).getOperationTokenType(); } PsiExpression getExpr = expr; if (processGet) { final PsiMethodCallExpression getterCall = createGetterCall(fieldDescriptor, expr, descriptor.getTargetClass(), getter); if (getterCall != null) { getExpr = getterCall; } } @NonNls String text; if (sign == JavaTokenType.PLUSPLUS) { text = "a+1"; } else { text = "a-1"; } PsiBinaryExpression binExpr = (PsiBinaryExpression) factory.createExpressionFromText(text, null); binExpr.getLOperand().replace(getExpr); PsiExpression setExpr; if (processSet) { setExpr = createSetterCall(fieldDescriptor, binExpr, expr, descriptor.getTargetClass(), setter); } else { text = "a = b"; PsiAssignmentExpression assignment = (PsiAssignmentExpression) factory.createExpressionFromText(text, null); assignment.getLExpression().replace(expr); assignment.getRExpression().replace(binExpr); setExpr = assignment; } parent.replace(setExpr); } else { if (!processGet) return true; PsiMethodCallExpression methodCall = createGetterCall(fieldDescriptor, expr, descriptor.getTargetClass(), getter); if (methodCall != null) { expr.replace(methodCall); } } } catch (IncorrectOperationException e) { LOG.error(e); } return true; }