avoid search by offset in copy, use marker instead

This commit is contained in:
Anna.Kozlova
2017-11-30 14:49:59 +01:00
parent e67db80f4c
commit a683df3efd
6 changed files with 30 additions and 25 deletions
@@ -149,11 +149,12 @@ public class AnonymousCanBeLambdaInspection extends AbstractBaseJavaLocalInspect
final PsiCall call = LambdaUtil.treeWalkUp(topExpr);
if (call != null && call.resolveMethod() != null) {
final int offsetInTopCall = aClass.getTextRange().getStartOffset() - call.getTextRange().getStartOffset();
Object marker = new Object();
PsiTreeUtil.mark(aClass, marker);
PsiCall copyCall = LambdaUtil.copyTopLevelCall(call);
if (copyCall == null) return null;
final PsiAnonymousClass classArg = PsiTreeUtil.getParentOfType(copyCall.findElementAt(offsetInTopCall), PsiAnonymousClass.class);
if (classArg != null) {
final PsiElement classArg = PsiTreeUtil.releaseMark(copyCall, marker);
if (classArg instanceof PsiAnonymousClass) {
PsiExpression lambda = JavaPsiFacade.getElementFactory(aClass.getProject())
.createExpressionFromText(ReplaceWithLambdaFix.composeLambdaText(method), expression);
lambda = (PsiExpression)classArg.getParent().replace(lambda);
@@ -75,11 +75,12 @@ public class RedundantLambdaCodeBlockInspection extends AbstractBaseJavaLocalIns
final PsiCall call = LambdaUtil.treeWalkUp(body);
PsiMethod oldTarget;
if (call != null && (oldTarget = call.resolveMethod()) != null) {
final int offsetInTopCall = body.getTextRange().getStartOffset() - call.getTextRange().getStartOffset();
Object marker = new Object();
PsiTreeUtil.mark(body, marker);
PsiCall copyCall = LambdaUtil.copyTopLevelCall(call);
if (copyCall == null) return null;
final PsiCodeBlock codeBlock = PsiTreeUtil.getParentOfType(copyCall.findElementAt(offsetInTopCall), PsiCodeBlock.class);
if (codeBlock != null) {
final PsiElement codeBlock = PsiTreeUtil.releaseMark(copyCall, marker);
if (codeBlock instanceof PsiCodeBlock) {
final PsiElement parent = codeBlock.getParent();
if (parent instanceof PsiLambdaExpression) {
codeBlock.replace(psiExpression);
@@ -367,8 +367,10 @@ public class RedundantCastUtil {
else {
final PsiCall call = LambdaUtil.treeWalkUp(expression);
if (call != null) {
Object marker = new Object();
PsiTreeUtil.mark(argumentList, marker);
final PsiCall callCopy = (PsiCall)call.copy();
newCall = PsiTreeUtil.getParentOfType(callCopy.findElementAt(argumentList.getTextRange().getStartOffset() - call.getTextRange().getStartOffset()), expression.getClass());
newCall = PsiTreeUtil.getParentOfType(PsiTreeUtil.releaseMark(callCopy, marker), expression.getClass(), false);
}
else {
newCall = (PsiCall)expression.copy();
@@ -77,7 +77,7 @@ public class PsiDiamondTypeUtil {
final PsiElement resolve = classReference.resolve();
if (resolve instanceof PsiClass) {
final PsiTypeParameter[] typeParameters = ((PsiClass)resolve).getTypeParameters();
return areTypeArgumentsRedundant(typeArguments, expression, true, method, typeParameters);
return areTypeArgumentsRedundant(typeArguments, context, true, method, typeParameters);
}
}
}
@@ -160,43 +160,44 @@ public class PsiDiamondTypeUtil {
}
public static boolean areTypeArgumentsRedundant(PsiType[] typeArguments,
PsiExpression expression,
PsiExpression context,
boolean constructorRef,
@Nullable PsiMethod method,
PsiTypeParameter[] typeParameters) {
try {
final PsiElement copy;
final PsiType typeByParent = PsiTypesUtil.getExpectedTypeByParent(expression);
final PsiType typeByParent = PsiTypesUtil.getExpectedTypeByParent(context);
if (typeByParent != null) {
if (isAugmented(expression)) {
if (isAugmented(context)) {
return false;
}
final String arrayInitializer = "new " + typeByParent.getCanonicalText() + "[]{0}";
final Project project = expression.getProject();
final Project project = context.getProject();
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
PsiNewExpression newExpr = (PsiNewExpression)elementFactory.createExpressionFromText(arrayInitializer, expression);
PsiNewExpression newExpr = (PsiNewExpression)elementFactory.createExpressionFromText(arrayInitializer, context);
//ensure refs to inner classes are collapsed to avoid raw types (container type would be raw in qualified text)
newExpr = (PsiNewExpression)JavaCodeStyleManager.getInstance(project).shortenClassReferences(newExpr);
final PsiArrayInitializerExpression initializer = newExpr.getArrayInitializer();
LOG.assertTrue(initializer != null);
copy = initializer.getInitializers()[0].replace(expression);
copy = initializer.getInitializers()[0].replace(context);
}
else {
final PsiExpressionList argumentList = expression instanceof PsiCallExpression ? ((PsiCallExpression)expression).getArgumentList() : null;
final int offset = (argumentList != null ? argumentList : expression).getTextRange().getStartOffset();
final PsiCall call = LambdaUtil.treeWalkUp(expression);
final PsiExpressionList argumentList = context instanceof PsiCallExpression ? ((PsiCallExpression)context).getArgumentList() : null;
final Object marker = new Object();
PsiTreeUtil.mark(argumentList != null ? argumentList : context, marker);
final PsiCall call = LambdaUtil.treeWalkUp(context);
if (call != null) {
final PsiCall callCopy = LambdaUtil.copyTopLevelCall(call);
copy = callCopy != null ? callCopy.findElementAt(offset - call.getTextRange().getStartOffset()) : null;
copy = callCopy != null ? PsiTreeUtil.releaseMark(callCopy, marker) : null;
}
else {
final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(expression.getProject());
if (injectedLanguageManager.getInjectionHost(expression) != null) {
final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(context.getProject());
if (injectedLanguageManager.getInjectionHost(context) != null) {
return false;
}
final PsiFile containingFile = expression.getContainingFile();
final PsiFile containingFile = context.getContainingFile();
final PsiFile fileCopy = (PsiFile)containingFile.copy();
copy = fileCopy.findElementAt(offset);
copy = PsiTreeUtil.releaseMark(fileCopy, marker);
if (method != null && method.getContainingFile() == containingFile) {
final PsiElement startMethodElementInCopy = fileCopy.findElementAt(method.getTextOffset());
method = PsiTreeUtil.getParentOfType(startMethodElementInCopy, PsiMethod.class);
@@ -207,7 +208,7 @@ public class PsiDiamondTypeUtil {
}
}
}
if (expression instanceof PsiMethodReferenceExpression) {
if (context instanceof PsiMethodReferenceExpression) {
PsiMethodReferenceExpression methodRefCopy = PsiTreeUtil.getParentOfType(copy, PsiMethodReferenceExpression.class, false);
if (methodRefCopy != null && !isInferenceEquivalent(typeArguments, typeParameters, method, methodRefCopy)) {
return false;
@@ -7,6 +7,6 @@ class Foo<T> {
class Constructors {
public static void main(String[] args) {
Foo<Number> foo2 = new Foo<>(1);
Foo<Number> foo2 = new Foo<Number>(1);
}
}
@@ -203,7 +203,7 @@ public class JavaFxFieldToPropertyIntention extends PsiElementBaseIntentionActio
myField.setInitializer(newInitializer);
final PsiType fieldType = myField.getType();
if (PsiDiamondTypeUtil.canCollapseToDiamond(newInitializer, newInitializer, fieldType)) {
if (PsiDiamondTypeUtil.canCollapseToDiamond(newInitializer, (PsiNewExpression)myField.getInitializer(), fieldType)) {
final PsiJavaCodeReferenceElement classReference = newInitializer.getClassOrAnonymousClassReference();
if (classReference != null) {
PsiDiamondTypeUtil.replaceExplicitWithDiamond(classReference.getParameterList());