mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
diamonds: allow in invocation context in java 8
This commit is contained in:
+1
-71
@@ -17,88 +17,18 @@ package com.intellij.psi.impl.source.resolve;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.ExpectedTypesProvider;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.scope.MethodProcessorSetupFailedException;
|
||||
import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
|
||||
import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class CompletionParameterTypeInferencePolicy extends ParameterTypeInferencePolicy {
|
||||
public class CompletionParameterTypeInferencePolicy extends ProcessCandidateParameterTypeInferencePolicy {
|
||||
public static final CompletionParameterTypeInferencePolicy INSTANCE = new CompletionParameterTypeInferencePolicy();
|
||||
|
||||
private CompletionParameterTypeInferencePolicy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiCallExpression innerMethodCall,
|
||||
PsiExpressionList expressionList,
|
||||
PsiCallExpression contextCall,
|
||||
PsiTypeParameter typeParameter) {
|
||||
final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(contextCall);
|
||||
try {
|
||||
//can't call resolve() since it obtains full substitution, that may result in infinite recursion
|
||||
PsiScopesUtil.setupAndRunProcessor(processor, contextCall, false);
|
||||
PsiExpression[] expressions = expressionList.getExpressions();
|
||||
int i = ArrayUtil.find(expressions, innerMethodCall);
|
||||
assert i >= 0;
|
||||
final JavaResolveResult[] results = processor.getResult();
|
||||
PsiMethod owner = (PsiMethod)typeParameter.getOwner();
|
||||
if (owner == null) return null;
|
||||
|
||||
final PsiType innerReturnType = owner.getReturnType();
|
||||
for (final JavaResolveResult result : results) {
|
||||
final PsiSubstitutor substitutor;
|
||||
if (result instanceof MethodCandidateInfo) {
|
||||
List<PsiExpression> leftArgs = Arrays.asList(expressions).subList(0, i);
|
||||
substitutor = ((MethodCandidateInfo)result).inferTypeArguments(this, leftArgs.toArray(new PsiExpression[leftArgs.size()]));
|
||||
} else {
|
||||
substitutor = result.getSubstitutor();
|
||||
}
|
||||
|
||||
final PsiElement element = result.getElement();
|
||||
if (element instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)element;
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
PsiParameter parameter = null;
|
||||
if (parameters.length > i) {
|
||||
parameter = parameters[i];
|
||||
}
|
||||
else if (method.isVarArgs()) {
|
||||
parameter = parameters[parameters.length - 1];
|
||||
}
|
||||
if (parameter != null) {
|
||||
final PsiParameter finalParameter = parameter;
|
||||
PsiType type = PsiResolveHelperImpl.ourGuard.doPreventingRecursion(innerMethodCall, true, new Computable<PsiType>() {
|
||||
@Override
|
||||
public PsiType compute() {
|
||||
return substitutor.substitute(finalParameter.getType());
|
||||
}
|
||||
});
|
||||
final Pair<PsiType, ConstraintType> constraint =
|
||||
PsiResolveHelperImpl.getSubstitutionForTypeParameterConstraint(typeParameter, innerReturnType, type, false,
|
||||
PsiUtil.getLanguageLevel(innerMethodCall));
|
||||
if (constraint != null) return constraint;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MethodProcessorSetupFailedException ev) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiType getDefaultExpectedType(PsiCallExpression methodCall) {
|
||||
ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getExpectedTypes(methodCall, true);
|
||||
|
||||
-3
@@ -25,9 +25,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
public class DefaultParameterTypeInferencePolicy extends ParameterTypeInferencePolicy {
|
||||
public static final DefaultParameterTypeInferencePolicy INSTANCE = new DefaultParameterTypeInferencePolicy();
|
||||
|
||||
private DefaultParameterTypeInferencePolicy() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiCallExpression innerMethodCall,
|
||||
|
||||
@@ -19,7 +19,9 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.source.resolve.ProcessCandidateParameterTypeInferencePolicy;
|
||||
import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -254,7 +256,8 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
|
||||
final PsiExpressionList argumentList = expression.getArgumentList();
|
||||
final PsiExpression[] expressions = argumentList.getExpressions();
|
||||
return resolveHelper
|
||||
.inferTypeArguments(staticFactoryMethod.getTypeParameters(), parameters, expressions, PsiSubstitutor.EMPTY, parent, DefaultParameterTypeInferencePolicy.INSTANCE);
|
||||
.inferTypeArguments(staticFactoryMethod.getTypeParameters(), parameters, expressions, PsiSubstitutor.EMPTY, parent,
|
||||
PsiUtil.getLanguageLevel(parent).isAtLeast(LanguageLevel.JDK_1_8) ? ProcessCandidateParameterTypeInferencePolicy.INSTANCE : DefaultParameterTypeInferencePolicy.INSTANCE);
|
||||
}
|
||||
|
||||
public static boolean hasDefaultConstructor(@NotNull final PsiClass psiClass) {
|
||||
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.impl.source.resolve;
|
||||
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.scope.MethodProcessorSetupFailedException;
|
||||
import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
|
||||
import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 7/18/12
|
||||
*/
|
||||
public class ProcessCandidateParameterTypeInferencePolicy extends DefaultParameterTypeInferencePolicy {
|
||||
public static final ProcessCandidateParameterTypeInferencePolicy INSTANCE = new ProcessCandidateParameterTypeInferencePolicy();
|
||||
|
||||
@Override
|
||||
public Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiCallExpression innerMethodCall,
|
||||
PsiExpressionList expressionList,
|
||||
PsiCallExpression contextCall,
|
||||
PsiTypeParameter typeParameter) {
|
||||
final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(contextCall);
|
||||
try {
|
||||
//can't call resolve() since it obtains full substitution, that may result in infinite recursion
|
||||
PsiScopesUtil.setupAndRunProcessor(processor, contextCall, false);
|
||||
PsiExpression[] expressions = expressionList.getExpressions();
|
||||
int i = ArrayUtil.find(expressions, innerMethodCall);
|
||||
assert i >= 0;
|
||||
final JavaResolveResult[] results = processor.getResult();
|
||||
PsiMethod owner = (PsiMethod)typeParameter.getOwner();
|
||||
if (owner == null) return null;
|
||||
|
||||
final PsiType innerReturnType = owner.getReturnType();
|
||||
for (final JavaResolveResult result : results) {
|
||||
final PsiSubstitutor substitutor;
|
||||
if (result instanceof MethodCandidateInfo) {
|
||||
List<PsiExpression> leftArgs = Arrays.asList(expressions).subList(0, i);
|
||||
substitutor = ((MethodCandidateInfo)result).inferTypeArguments(this, leftArgs.toArray(new PsiExpression[leftArgs.size()]));
|
||||
}
|
||||
else {
|
||||
substitutor = result.getSubstitutor();
|
||||
}
|
||||
|
||||
final PsiElement element = result.getElement();
|
||||
if (element instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)element;
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
PsiParameter parameter = null;
|
||||
if (parameters.length > i) {
|
||||
parameter = parameters[i];
|
||||
}
|
||||
else if (method.isVarArgs()) {
|
||||
parameter = parameters[parameters.length - 1];
|
||||
}
|
||||
if (parameter != null) {
|
||||
final PsiParameter finalParameter = parameter;
|
||||
PsiType type = PsiResolveHelperImpl.ourGuard.doPreventingRecursion(innerMethodCall, true, new Computable<PsiType>() {
|
||||
@Override
|
||||
public PsiType compute() {
|
||||
return substitutor.substitute(finalParameter.getType());
|
||||
}
|
||||
});
|
||||
final Pair<PsiType, ConstraintType> constraint =
|
||||
PsiResolveHelperImpl.getSubstitutionForTypeParameterConstraint(typeParameter, innerReturnType, type, false,
|
||||
PsiUtil.getLanguageLevel(innerMethodCall));
|
||||
if (constraint != null) return constraint;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MethodProcessorSetupFailedException ev) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+10
-1
@@ -93,7 +93,16 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testDiamondNeg12() throws Exception { doTest(false, false); }
|
||||
public void testDiamondNeg13() throws Exception { doTest(false, false); }
|
||||
public void testDiamondNeg14() throws Exception { doTest(false, false); }
|
||||
public void testDiamondMisc() throws Exception { doTest(false, false); }
|
||||
public void testDiamondMisc() throws Exception {
|
||||
final LanguageLevel oldLevel = getLanguageLevel();
|
||||
try {
|
||||
setLanguageLevel(LanguageLevel.JDK_1_7);
|
||||
doTest(false, false);
|
||||
}
|
||||
finally {
|
||||
setLanguageLevel(oldLevel);
|
||||
}
|
||||
}
|
||||
public void testHighlightInaccessibleFromClassModifierList() throws Exception { doTest(false, false); }
|
||||
public void testInnerInTypeArguments() throws Exception { doTest(false, false); }
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInsight.CodeInsightUtil;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.util.Pass;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.psi.PsiLocalVariable;
|
||||
@@ -272,7 +273,14 @@ public class IntroduceParameterTest extends LightRefactoringTestCase {
|
||||
}
|
||||
|
||||
public void testDiamondOccurrences() throws Exception {
|
||||
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, true, false, true, false);
|
||||
final LanguageLevel oldLevel = getLanguageLevel();
|
||||
try {
|
||||
setLanguageLevel(LanguageLevel.JDK_1_7);
|
||||
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, true, false, true, false);
|
||||
}
|
||||
finally {
|
||||
setLanguageLevel(oldLevel);
|
||||
}
|
||||
}
|
||||
|
||||
public void testPreserveDiamondOccurrences() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user