mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+35
-33
@@ -55,7 +55,14 @@ public class ContractInference {
|
||||
@Nullable
|
||||
@Override
|
||||
public Result<List<MethodContract>> compute() {
|
||||
return Result.create(new ContractInferenceInterpreter(method).inferContracts(), method);
|
||||
List<MethodContract> result = RecursionManager.doPreventingRecursion(method, true, new Computable<List<MethodContract>>() {
|
||||
@Override
|
||||
public List<MethodContract> compute() {
|
||||
return new ContractInferenceInterpreter(method).inferContracts();
|
||||
}
|
||||
});
|
||||
if (result == null) result = Collections.emptyList();
|
||||
return Result.create(result, method);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -134,47 +141,42 @@ class ContractInferenceInterpreter {
|
||||
if (targetMethod == null) return Collections.emptyList();
|
||||
|
||||
final PsiExpression[] arguments = expression.getArgumentList().getExpressions();
|
||||
return RecursionManager.doPreventingRecursion(myMethod, true, new Computable<List<MethodContract>>() {
|
||||
final boolean notNull = NullableNotNullManager.isNotNull(targetMethod);
|
||||
List<MethodContract> fromDelegate = ContainerUtil.mapNotNull(ControlFlowAnalyzer.getMethodContracts(targetMethod), new NullableFunction<MethodContract, MethodContract>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public List<MethodContract> compute() {
|
||||
final boolean notNull = NullableNotNullManager.isNotNull(targetMethod);
|
||||
List<MethodContract> fromDelegate = ContainerUtil.mapNotNull(ControlFlowAnalyzer.getMethodContracts(targetMethod), new NullableFunction<MethodContract, MethodContract>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public MethodContract fun(MethodContract delegateContract) {
|
||||
ValueConstraint[] answer = myEmptyConstraints;
|
||||
for (int i = 0; i < delegateContract.arguments.length; i++) {
|
||||
if (i >= arguments.length) return null;
|
||||
public MethodContract fun(MethodContract delegateContract) {
|
||||
ValueConstraint[] answer = myEmptyConstraints;
|
||||
for (int i = 0; i < delegateContract.arguments.length; i++) {
|
||||
if (i >= arguments.length) return null;
|
||||
|
||||
ValueConstraint argConstraint = delegateContract.arguments[i];
|
||||
if (argConstraint != ANY_VALUE) {
|
||||
int paramIndex = resolveParameter(arguments[i]);
|
||||
if (paramIndex < 0) {
|
||||
if (argConstraint != getLiteralConstraint(arguments[i])) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
answer = withConstraint(answer, paramIndex, argConstraint);
|
||||
if (answer == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
ValueConstraint argConstraint = delegateContract.arguments[i];
|
||||
if (argConstraint != ANY_VALUE) {
|
||||
int paramIndex = resolveParameter(arguments[i]);
|
||||
if (paramIndex < 0) {
|
||||
if (argConstraint != getLiteralConstraint(arguments[i])) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
ValueConstraint returnValue = negated ? negateConstraint(delegateContract.returnValue) : delegateContract.returnValue;
|
||||
if (notNull && returnValue != THROW_EXCEPTION) {
|
||||
returnValue = NOT_NULL_VALUE;
|
||||
else {
|
||||
answer = withConstraint(answer, paramIndex, argConstraint);
|
||||
if (answer == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return answer == null ? null : new MethodContract(answer, returnValue);
|
||||
}
|
||||
});
|
||||
if (notNull) {
|
||||
return ContainerUtil.concat(fromDelegate, Arrays.asList(new MethodContract(myEmptyConstraints, NOT_NULL_VALUE)));
|
||||
}
|
||||
return fromDelegate;
|
||||
ValueConstraint returnValue = negated ? negateConstraint(delegateContract.returnValue) : delegateContract.returnValue;
|
||||
if (notNull && returnValue != THROW_EXCEPTION) {
|
||||
returnValue = NOT_NULL_VALUE;
|
||||
}
|
||||
return answer == null ? null : new MethodContract(answer, returnValue);
|
||||
}
|
||||
});
|
||||
if (notNull) {
|
||||
return ContainerUtil.concat(fromDelegate, Arrays.asList(new MethodContract(myEmptyConstraints, NOT_NULL_VALUE)));
|
||||
}
|
||||
return fromDelegate;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+2
-2
@@ -1510,11 +1510,11 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiAnnotation findContractAnnotation(PsiMethod method) {
|
||||
public static PsiAnnotation findContractAnnotation(@NotNull PsiMethod method) {
|
||||
return AnnotationUtil.findAnnotationInHierarchy(method, Collections.singleton(ORG_JETBRAINS_ANNOTATIONS_CONTRACT));
|
||||
}
|
||||
|
||||
public static boolean isPure(PsiMethod method) {
|
||||
public static boolean isPure(@NotNull PsiMethod method) {
|
||||
PsiAnnotation anno = findContractAnnotation(method);
|
||||
return anno != null && Boolean.TRUE.equals(AnnotationUtil.getBooleanAttributeValue(anno, "pure"));
|
||||
}
|
||||
|
||||
@@ -450,7 +450,7 @@ public class JavaCompletionUtil {
|
||||
PsiType returnType = method.getReturnType();
|
||||
if (method.getSignature(plainSub).equals(method.getSignature(castSub)) &&
|
||||
returnType != null &&
|
||||
castSub.substitute(returnType).isAssignableFrom(plainSub.substitute(returnType)) &&
|
||||
toRaw(castSub.substitute(returnType)).isAssignableFrom(toRaw(plainSub.substitute(returnType))) &&
|
||||
processor.isAccessible(plainClass.findMethodBySignature(method, true))
|
||||
) {
|
||||
return item;
|
||||
@@ -494,6 +494,10 @@ public class JavaCompletionUtil {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static PsiType toRaw(@NotNull PsiType type) {
|
||||
return type instanceof PsiClassType ? ((PsiClassType)type).rawType() : type;
|
||||
}
|
||||
|
||||
public static LookupElement highlightIfNeeded(PsiType qualifierType, LookupElement item, Object object) {
|
||||
return containsMember(qualifierType, object) ? highlight(item) : item;
|
||||
|
||||
@@ -192,7 +192,7 @@ public class AnnotationUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiAnnotation findAnnotationInHierarchy(final PsiModifierListOwner listOwner, @NotNull Set<String> annotationNames) {
|
||||
public static PsiAnnotation findAnnotationInHierarchy(@NotNull final PsiModifierListOwner listOwner, @NotNull Set<String> annotationNames) {
|
||||
PsiAnnotation directAnnotation = findAnnotation(listOwner, annotationNames);
|
||||
if (directAnnotation != null) return directAnnotation;
|
||||
|
||||
|
||||
+27
-6
@@ -13,13 +13,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.psi.CommonClassNames;
|
||||
import com.intellij.psi.JavaCodeFragmentFactory;
|
||||
package com.intellij.codeInsight.completion
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes
|
||||
import com.intellij.psi.CommonClassNames
|
||||
import com.intellij.psi.JavaCodeFragmentFactory
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.PsiExpression
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import com.intellij.util.PairFunction
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -97,5 +100,23 @@ public class FragmentCompletionTest extends LightCodeInsightFixtureTestCase {
|
||||
myFixture.checkResult("o instanceof String && ((String) o).substring(<caret>)");
|
||||
}
|
||||
|
||||
public void testNoGenericQualifierCastingWithRuntimeType() throws Throwable {
|
||||
final ctxText = "import java.util.*; class Bar {{ Map<Integer,Integer> map = new HashMap<Integer,Integer>(); map=null; }}"
|
||||
final ctxFile = createLightFile(StdFileTypes.JAVA, ctxText)
|
||||
final context = ctxFile.findElementAt(ctxText.indexOf("map="))
|
||||
assert context
|
||||
|
||||
PsiFile file = JavaCodeFragmentFactory.getInstance(project).createExpressionCodeFragment("map.entry<caret>", context, null, true);
|
||||
myFixture.configureFromExistingVirtualFile(file.getVirtualFile());
|
||||
myFixture.file.putCopyableUserData(JavaCompletionUtil.DYNAMIC_TYPE_EVALUATOR, new PairFunction<PsiExpression, CompletionParameters, PsiType>() {
|
||||
@Override
|
||||
PsiType fun(PsiExpression t, CompletionParameters v) {
|
||||
return JavaPsiFacade.getElementFactory(t.project).createTypeByFQClassName(CommonClassNames.JAVA_UTIL_HASH_MAP)
|
||||
}
|
||||
})
|
||||
assert !myFixture.completeBasic()
|
||||
myFixture.checkResult("map.entrySet()<caret>");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user