Merge branch 'origin/master'

This commit is contained in:
Elizaveta Shashkova
2015-02-24 17:45:54 +03:00
17 changed files with 154 additions and 57 deletions
@@ -307,7 +307,10 @@ public abstract class SourcePosition implements Navigatable{
}
public static SourcePosition createFromElement(PsiElement element) {
final PsiElement navigationElement = element.getNavigationElement();
ApplicationManager.getApplication().assertReadAccessAllowed();
PsiElement navigationElement = element.getNavigationElement();
final SmartPsiElementPointer<PsiElement> pointer =
SmartPointerManager.getInstance(navigationElement.getProject()).createSmartPsiElementPointer(navigationElement);
final PsiFile psiFile;
if (JspPsiUtil.isInJspFile(navigationElement)) {
psiFile = JspPsiUtil.getJspFile(navigationElement);
@@ -318,12 +321,19 @@ public abstract class SourcePosition implements Navigatable{
return new SourcePositionCache(psiFile) {
@Override
protected PsiElement calcPsiElement() {
return navigationElement;
ApplicationManager.getApplication().assertReadAccessAllowed();
return pointer.getElement();
}
@Override
protected int calcOffset() {
return navigationElement.getTextOffset();
return ApplicationManager.getApplication().runReadAction(new Computable<Integer>() {
@Override
public Integer compute() {
PsiElement elem = pointer.getElement();
return elem != null ? elem.getTextOffset() : -1;
}
});
}
};
}
@@ -263,13 +263,14 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
if (element instanceof PsiMethodCallExpression) {
final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)element;
final PsiMethod psiMethod = methodCall.resolveMethod();
JavaResolveResult result = methodCall.resolveMethodGenerics();
final PsiMethod psiMethod = (PsiMethod)result.getElement();
if (psiMethod == null) {
return null;
}
final PsiReferenceExpression methodExpression = methodCall.getMethodExpression();
final String qualifierByMethodCall = getQualifierTextByMethodCall(methodCall, functionalInterfaceType, parameters, psiMethod);
final String qualifierByMethodCall = getQualifierTextByMethodCall(methodCall, functionalInterfaceType, parameters, psiMethod, result.getSubstitutor());
if (qualifierByMethodCall != null) {
return qualifierByMethodCall + "::" + ((PsiMethodCallExpression)element).getTypeArgumentList().getText() + methodExpression.getReferenceName();
}
@@ -324,7 +325,8 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
private static String getQualifierTextByMethodCall(final PsiMethodCallExpression methodCall,
final PsiType functionalInterfaceType,
final PsiParameter[] parameters,
final PsiMethod psiMethod) {
final PsiMethod psiMethod,
final PsiSubstitutor substitutor) {
final PsiExpression qualifierExpression = methodCall.getMethodExpression().getQualifierExpression();
@@ -332,7 +334,7 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
LOG.assertTrue(containingClass != null);
if (qualifierExpression != null) {
boolean isReceiverType = PsiMethodReferenceUtil.isReceiverType(functionalInterfaceType, containingClass, psiMethod);
boolean isReceiverType = PsiMethodReferenceUtil.isReceiverType(PsiMethodReferenceUtil.getFirstParameterType(functionalInterfaceType, methodCall), containingClass, substitutor);
return isReceiverType ? composeReceiverQualifierText(parameters, psiMethod, containingClass, qualifierExpression)
: qualifierExpression.getText();
}
@@ -422,7 +424,6 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
if (lambdaExpression == null) return;
PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType();
if (functionalInterfaceType == null || !functionalInterfaceType.isValid()) return;
String functionalTypeText = functionalInterfaceType.getCanonicalText();
final String methodRefText = createMethodReferenceText(element, functionalInterfaceType,
lambdaExpression.getParameterList().getParameters());
@@ -30,10 +30,10 @@ public class PsiMethodReferenceUtil {
public static final Logger LOG = Logger.getInstance("#" + PsiMethodReferenceUtil.class.getName());
public static boolean hasReceiver(PsiType[] parameterTypes, QualifierResolveResult qualifierResolveResult, PsiMethodReferenceExpression methodRef) {
if (parameterTypes.length > 0 &&
if (parameterTypes.length > 0 &&
!methodRef.isConstructor() &&
isReceiverType(parameterTypes[0], qualifierResolveResult.getContainingClass(), qualifierResolveResult.getSubstitutor()) &&
isStaticallyReferenced(methodRef)) {
isStaticallyReferenced(methodRef) &&
isReceiverType(parameterTypes[0], qualifierResolveResult.getContainingClass(), qualifierResolveResult.getSubstitutor())) {
return true;
}
return false;
@@ -46,7 +46,7 @@ public class PsiMethodReferenceUtil {
LOG.assertTrue(containingClass != null);
PsiSubstitutor subst = result.getSubstitutor();
PsiClass qContainingClass = getQualifierResolveResult(expression).getContainingClass();
if (qContainingClass != null && isReceiverType(functionalInterfaceType, containingClass, (PsiMethod)resolve)) {
if (qContainingClass != null && isReceiverType(getFirstParameterType(functionalInterfaceType, expression), qContainingClass, subst)) {
subst = TypeConversionUtil.getClassSubstitutor(containingClass, qContainingClass, subst);
LOG.assertTrue(subst != null);
}
@@ -202,53 +202,27 @@ public class PsiMethodReferenceUtil {
return true;
}
public static boolean isReceiverType(@Nullable PsiClass aClass, @Nullable PsiClass containingClass) {
return InheritanceUtil.isInheritorOrSelf(aClass, containingClass, true);
}
public static boolean isReceiverType(PsiType receiverType, @Nullable PsiClass containingClass, PsiSubstitutor psiSubstitutor) {
if (containingClass != null) {
receiverType = getExpandedType(receiverType, containingClass);
//if P1, ..., Pn is not empty and P1 is a subtype of ReferenceType, then the method reference expression is treated as
// if it were a method invocation expression with argument expressions of types P2, ...,Pn.
public static boolean isReceiverType(@Nullable PsiType receiverType, PsiClass containingClass, PsiSubstitutor psiSubstitutor) {
if (receiverType == null) {
return false;
}
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(receiverType);
final PsiClass receiverClass = resolveResult.getElement();
if (receiverClass != null && isReceiverType(receiverClass, containingClass)) {
if (emptyOrRaw(containingClass, psiSubstitutor)) {
return true;
}
final PsiSubstitutor derivedSubstitutor = TypeConversionUtil.getClassSubstitutor(containingClass, receiverClass, psiSubstitutor);
return derivedSubstitutor != null && TypeConversionUtil.isAssignable(JavaPsiFacade.getElementFactory(containingClass.getProject()).createType(containingClass, derivedSubstitutor), receiverType);
}
return false;
return TypeConversionUtil.isAssignable(JavaPsiFacade.getElementFactory(containingClass.getProject()).createType(containingClass, psiSubstitutor),
getExpandedType(receiverType, containingClass));
}
private static boolean emptyOrRaw(PsiClass containingClass, PsiSubstitutor psiSubstitutor) {
return PsiUtil.isRawSubstitutor(containingClass, psiSubstitutor) ||
psiSubstitutor.getSubstitutionMap().isEmpty();
}
public static boolean isReceiverType(PsiType functionalInterfaceType, PsiClass containingClass, @Nullable PsiMethod referencedMethod) {
public static PsiType getFirstParameterType(PsiType functionalInterfaceType, PsiElement context) {
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
final MethodSignature function = LambdaUtil.getFunction(resolveResult.getElement());
if (function != null) {
final int interfaceMethodParamsLength = function.getParameterTypes().length;
if (interfaceMethodParamsLength > 0) {
final PsiType firstParamType = resolveResult.getSubstitutor().substitute(function.getParameterTypes()[0]);
boolean isReceiver = isReceiverType(firstParamType,
containingClass, PsiUtil.resolveGenericsClassInType(firstParamType).getSubstitutor());
if (isReceiver) {
if (referencedMethod == null){
if (interfaceMethodParamsLength == 1) return true;
return false;
}
if (referencedMethod.getParameterList().getParametersCount() != interfaceMethodParamsLength - 1) {
return false;
}
return true;
}
PsiType type = resolveResult.getSubstitutor().substitute(function.getParameterTypes()[0]);
return type != null ? PsiUtil.captureToplevelWildcards(type, context) : null;
}
}
return false;
return null;
}
private static PsiType getExpandedType(PsiType type, @NotNull PsiElement typeElement) {
@@ -176,7 +176,7 @@ public class CheckedExceptionCompatibilityConstraint extends InputOutputConstrai
private static boolean isAddressed(List<PsiType> expectedThrownTypes, PsiType thrownType) {
for (PsiType expectedThrownType : expectedThrownTypes) {
if (TypeConversionUtil.isAssignable(expectedThrownType, thrownType)) {
if (TypeConversionUtil.isAssignable(TypeConversionUtil.erasure(thrownType), expectedThrownType)) {
return true;
}
}
@@ -20,7 +20,6 @@ import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
@@ -480,7 +479,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
PsiClass qContainingClass = PsiMethodReferenceUtil.getQualifierResolveResult(this).getContainingClass();
if (qContainingClass != null && containingClass != null &&
PsiMethodReferenceUtil.isReceiverType(left, containingClass, (PsiMethod)resolve)) {
PsiMethodReferenceUtil.isReceiverType(PsiMethodReferenceUtil.getFirstParameterType(left, this), qContainingClass, subst)) {
subst = TypeConversionUtil.getClassSubstitutor(containingClass, qContainingClass, subst);
LOG.assertTrue(subst != null);
}
@@ -0,0 +1,38 @@
import java.io.IOException;
class Test {
interface B<K, E extends Throwable> {
K l(K k) throws E;
}
<R> void bar(B<R, IOException> b) {}
<E extends Exception, T> T baz(T l) throws E {
return null;
}
{
bar(l -> baz(l));
bar(this::baz);
}
}
class Test1 {
interface B<K, E extends Throwable> {
K l(K k) throws E;
}
<R> void bar(B<R, IOException> b) {}
class MyEx extends Exception{}
<E extends MyEx, T> T baz(T l) throws E {
return null;
}
{
bar(l -> baz<error descr="'baz(java.lang.Object)' in 'Test1' cannot be applied to '(<lambda parameter>)'">(l)</error>);
bar(<error descr="Unhandled exception: Test1.MyEx">this::baz</error>);
}
}
@@ -0,0 +1,28 @@
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
class Test {
static class Base {
public BigDecimal getTotal() {
return null;
}
}
public static void foo(List<? extends Base> list, List<Base> list1) {
System.out.println(add(list, Base::getTotal));
list1.forEach(Base::getTotal);
}
public static <T> BigDecimal add(Collection<T> objectsThatHaveBigDecimals, Function<T, ? extends BigDecimal> functionToGet) {
return objectsThatHaveBigDecimals == null ? null : objectsThatHaveBigDecimals.stream().map(functionToGet).reduce(null, Test::add);
}
public static BigDecimal add(BigDecimal... sequence) {
return null;
}
}
@@ -0,0 +1,9 @@
import java.util.Collection;
import java.util.function.ToIntFunction;
import java.util.stream.Collectors;
class Test {
public static <T> int sum(Collection<? extends T> collection, ToIntFunction<? super T> mapper) {
return collection.stream().collect(Collectors.summingInt(mapper));
}
}
@@ -35,6 +35,10 @@ public class Java8RegressionTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testIDEA136887() throws Exception {
doTest();
}
private void doTest() {
doTest(false);
}
@@ -142,6 +142,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testCheckedExceptionsConstraintsSubstitutions1() throws Exception {
doTest();
}
public void testCheckedExceptionsConstraintsSubstitutionsDeepInBody() throws Exception {
doTest();
}
@@ -382,6 +382,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest(false);
}
public void testSecondSearchIfFirstParameterIsASubtypeOfReferenceTypeFromExpressionDeclaration() throws Exception {
doTest();
}
private void doTest() {
doTest(false);
}
Binary file not shown.
@@ -22,6 +22,8 @@ import com.intellij.openapi.project.DumbModeTask;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.util.SimpleModificationTracker;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -36,6 +38,11 @@ public class MockDumbService extends DumbService {
myProject = project;
}
@Override
public ModificationTracker getModificationTracker() {
return new SimpleModificationTracker();
}
@Override
public boolean isDumb() {
return false;
@@ -289,7 +289,6 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
}
advanceProgress(1);
tool.inspectionFinished(session, holder);
if (holder.hasResults()) {
appendDescriptors(myFile, holder.getResults(), toolWrapper);
}
@@ -308,6 +308,7 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
if (mySearchResults.getMatchesCount() >= mySearchResults.getMatchesLimit())
return;
for (FindResult range : mySearchResults.getOccurrences()) {
if (range.getEndOffset() > mySearchResults.getEditor().getDocument().getTextLength()) continue;
TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.TEXT_SEARCH_RESULT_ATTRIBUTES);
if (range.getLength() == 0) {
attributes = attributes.clone();
@@ -1773,8 +1773,8 @@ public class UIUtil {
}
private static int THEME_BASED_TEXT_LCD_CONTRAST = 0;
private static int BEST_DARK_LCD_CONTRAST = 100;
private static int BEST_LIGHT_LCD_CONTRAST = 200;
private static int BEST_DARK_LCD_CONTRAST = 250;
private static int BEST_LIGHT_LCD_CONTRAST = 100;
public static void setHintingForLCDText(Graphics2D g2d) {
@@ -1,3 +1,18 @@
/*
* Copyright 2000-2015 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.coverage.view;
import com.intellij.coverage.*;
@@ -235,9 +250,13 @@ public class JavaCoverageViewExtension extends CoverageViewExtension {
: PsiFile.EMPTY_ARRAY;
}
});
for (PsiFile file : childFiles) {
for (final PsiFile file : childFiles) {
if (file instanceof PsiJavaFile) {
PsiClass[] classes = ((PsiJavaFile)file).getClasses();
PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() {
public PsiClass[] compute() {
return ((PsiJavaFile) file).getClasses();
}
});
if (classes.length > 0) {
PsiClass aClass = classes[0];
if (!(node instanceof CoverageListRootNode) && getClassCoverageInfo(aClass) == null) continue;