From a026cc2dd1bca630317412b6f65edb3c75e426f0 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 17 Dec 2014 15:50:18 +0100 Subject: [PATCH 1/8] new overload resolution: check only functional arguments in isFunctionalTypeMoreSpecific (IDEA-134328) --- .../graphInference/InferenceSession.java | 2 +- ...entsWhenCheckIfFunctionalMoreSpecific.java | 22 +++++++++++++++++++ .../daemon/lambda/OverloadResolutionTest.java | 4 ++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IgnoreNonFunctionalArgumentsWhenCheckIfFunctionalMoreSpecific.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index fee1f269c130..c143693c91e2 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -1201,7 +1201,7 @@ public class InferenceSession { continue; } if (LambdaUtil.isFunctionalType(sType) && LambdaUtil.isFunctionalType(tType) && !relates(sType, tType)) { - if (!isFunctionalTypeMoreSpecific(sType, tType, session, args)) { + if (!isFunctionalTypeMoreSpecific(sType, tType, session, args[i])) { return false; } } else { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IgnoreNonFunctionalArgumentsWhenCheckIfFunctionalMoreSpecific.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IgnoreNonFunctionalArgumentsWhenCheckIfFunctionalMoreSpecific.java new file mode 100644 index 000000000000..6df40239a3d6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IgnoreNonFunctionalArgumentsWhenCheckIfFunctionalMoreSpecific.java @@ -0,0 +1,22 @@ +import java.util.List; +import java.util.function.Function; + +class Test { + + { + transform(1, (String l) -> null); + } + + public static void transform(int input, Function function) { + System.out.println(input); + System.out.println(function); + } + + interface IFunction { + List apply(F var1); + } + public static void transform(int input, IFunction function) { + System.out.println(input); + System.out.println(function); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java index a1507016f82d..82f04e789907 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java @@ -51,6 +51,10 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testIgnoreNonFunctionalArgumentsWhenCheckIfFunctionalMoreSpecific() throws Exception { + doTest(); + } + private void doTest() { doTest(true); } From 7b69b00b2bcce6ca4a9bff0ade24b7da5e91a731 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 17 Dec 2014 16:50:30 +0100 Subject: [PATCH 2/8] capture failure diff: not greedy, skip multiple groups in one message (IDEA-134384) --- .../com/intellij/junit4/JUnit4TestResultsSender.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestResultsSender.java b/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestResultsSender.java index 35de5849f05a..4e10a3cd048b 100644 --- a/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestResultsSender.java +++ b/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestResultsSender.java @@ -128,10 +128,10 @@ public class JUnit4TestResultsSender extends RunListener { notification = createExceptionNotification(assertion, message, "\nExpected: (.*)\n\\s*got: (.*)"); } if (notification == null) { - notification = createExceptionNotification(assertion, message, "\\s*expected same:<(.*)> was not:<(.*)>"); + notification = createExceptionNotification(assertion, message, ".*?\\s*expected same:<(.*)> was not:<(.*)>"); } if (notification == null) { - notification = createExceptionNotification(assertion, message, ".*\\s*expected:<(.*)> but was:<(.*)>"); + notification = createExceptionNotification(assertion, message, ".*?\\s*expected:<(.*?)> but was:<(.*?)>"); } if (notification == null) { notification = createExceptionNotification(assertion, message, "\nExpected: \"(.*)\"\n\\s*but: was \"(.*)\""); @@ -148,6 +148,13 @@ public class JUnit4TestResultsSender extends RunListener { private static PacketFactory createExceptionNotification(Throwable assertion, String message, final String regex) { final Matcher matcher = Pattern.compile(regex, Pattern.DOTALL | Pattern.CASE_INSENSITIVE).matcher(message); + + boolean found = false; + while (matcher.find()) { + if (found) return null; + found = true; + } + if (matcher.matches()) { return ComparisonDetailsExtractor.create(assertion, matcher.group(1).replaceAll("\\\\n", "\n"), matcher.group(2).replaceAll("\\\\n", "\n")); } From ef013da0190d87e2186cf673955a4c430275926a Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 17 Dec 2014 17:38:06 +0100 Subject: [PATCH 3/8] introduce field: check initializer if it has refs on parameter/locals so setup option is not valid; allow to introduce field in constructor if all used refs are final fields (IDEA-134348) --- .../IntroduceFieldCentralPanel.java | 86 ++++++++++++------- .../IntroduceFieldDialogPanel.java | 6 +- .../IntroduceFieldPopupPanel.java | 8 +- 3 files changed, 65 insertions(+), 35 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java index da5be799dace..78e643427769 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java @@ -18,6 +18,7 @@ package com.intellij.refactoring.introduceField; import com.intellij.codeInsight.TestFrameworks; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Ref; import com.intellij.psi.*; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; @@ -28,12 +29,15 @@ import com.intellij.refactoring.ui.TypeSelectorManager; import com.intellij.ui.NonFocusableCheckBox; import com.intellij.ui.StateRestoringCheckBox; import com.intellij.util.Processor; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.TestOnly; import javax.swing.*; import java.awt.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import java.util.HashSet; +import java.util.Set; /** * User: anna @@ -87,45 +91,69 @@ public abstract class IntroduceFieldCentralPanel { myTypeSelectorManager = typeSelectorManager; } - protected boolean setEnabledInitializationPlaces(PsiElement initializerPart, PsiElement initializer) { - if (initializerPart instanceof PsiReferenceExpression) { - PsiReferenceExpression refExpr = (PsiReferenceExpression)initializerPart; - if (refExpr.getQualifierExpression() == null) { - PsiElement refElement = refExpr.resolve(); - if (refElement == null || - (refElement instanceof PsiLocalVariable || - refElement instanceof PsiParameter || - (refElement instanceof PsiField && !((PsiField)refElement).hasInitializer())) && - !PsiTreeUtil.isAncestor(initializer, refElement, true)) { - return updateInitializationPlaceModel(initializedInSetUp(refElement)); + protected boolean setEnabledInitializationPlaces(@NotNull final PsiElement initializer) { + final Set fields = new HashSet(); + final Ref refsLocal = new Ref(false); + initializer.accept(new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitReferenceExpression(PsiReferenceExpression expression) { + super.visitReferenceExpression(expression); + if (expression.getQualifierExpression() == null) { + final PsiElement resolve = expression.resolve(); + if (resolve == null || + resolve instanceof PsiVariable && !PsiTreeUtil.isAncestor(initializer, resolve, true)) { + if (resolve instanceof PsiField) { + if (!((PsiField)resolve).hasInitializer()) { + fields.add((PsiField)resolve); + } + } + else { + refsLocal.set(true); + stopWalking(); + } + } } } + }); + + final boolean locals = refsLocal.get(); + if (!locals && fields.isEmpty()) { + return true; } - PsiElement[] children = initializerPart.getChildren(); - for (PsiElement child : children) { - if (!setEnabledInitializationPlaces(child, initializer)) return false; + return updateInitializationPlaceModel(!locals && initializedInSetUp(fields), + !locals && initializedInConstructor(fields)); + } + + private static boolean initializedInConstructor(Set fields) { + for (PsiField field : fields) { + if (!field.hasModifierProperty(PsiModifier.FINAL)) { + return false; + } } return true; } - private boolean initializedInSetUp(PsiElement refElement) { - if (refElement instanceof PsiField && hasSetUpChoice()) { - final PsiMethod setUpMethod = TestFrameworks.getInstance().findSetUpMethod(((PsiField)refElement).getContainingClass()); - if (setUpMethod != null) { - final Processor initializerSearcher = new Processor() { - @Override - public boolean process(PsiReference reference) { - final PsiElement referenceElement = reference.getElement(); - if (referenceElement instanceof PsiExpression) { - return !PsiUtil.isAccessedForWriting((PsiExpression)referenceElement); + private boolean initializedInSetUp(Set fields) { + if (hasSetUpChoice()) { + for (PsiField field : fields) { + final PsiMethod setUpMethod = TestFrameworks.getInstance().findSetUpMethod((field).getContainingClass()); + if (setUpMethod != null) { + final Processor initializerSearcher = new Processor() { + @Override + public boolean process(PsiReference reference) { + final PsiElement referenceElement = reference.getElement(); + if (referenceElement instanceof PsiExpression) { + return !PsiUtil.isAccessedForWriting((PsiExpression)referenceElement); + } + return true; } - return true; + }; + if (ReferencesSearch.search(field, new LocalSearchScope(setUpMethod)).forEach(initializerSearcher)) { + return false; } - }; - if (!ReferencesSearch.search(refElement, new LocalSearchScope(setUpMethod)).forEach(initializerSearcher)) { - return true; } } + return true; } return false; } @@ -305,7 +333,7 @@ public abstract class IntroduceFieldCentralPanel { } } - protected abstract boolean updateInitializationPlaceModel(boolean initializedInsetup); + protected abstract boolean updateInitializationPlaceModel(boolean initializedInsetup, boolean initializedInConstructor); protected abstract boolean hasSetUpChoice(); } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialogPanel.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialogPanel.java index ad5ccbc6fa18..8efa43227333 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialogPanel.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialogPanel.java @@ -63,7 +63,7 @@ public class IntroduceFieldDialogPanel extends IntroduceFieldCentralPanel { protected void initializeInitializerPlace(PsiExpression initializerExpression, BaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace) { if (initializerExpression != null) { - setEnabledInitializationPlaces(initializerExpression, initializerExpression); + setEnabledInitializationPlaces(initializerExpression); if (!myAllowInitInMethod) { myRbInCurrentMethod.setEnabled(false); } @@ -195,9 +195,9 @@ public class IntroduceFieldDialogPanel extends IntroduceFieldCentralPanel { } @Override - protected boolean updateInitializationPlaceModel(boolean initializedInSetup) { + protected boolean updateInitializationPlaceModel(boolean initializedInSetup, boolean initializedInConstructor) { myRbInFieldDeclaration.setEnabled(false); - myRbInConstructor.setEnabled(false); + myRbInConstructor.setEnabled(initializedInConstructor); enableFinal(false); if (myRbInSetUp != null){ if (!initializedInSetup) { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java index 0583a16b5bdb..470ecf920a51 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java @@ -57,7 +57,7 @@ public class IntroduceFieldPopupPanel extends IntroduceFieldCentralPanel { protected void initializeInitializerPlace(PsiExpression initializerExpression, BaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace) { if (initializerExpression != null) { - setEnabledInitializationPlaces(initializerExpression, initializerExpression); + setEnabledInitializationPlaces(initializerExpression); if (!myAllowInitInMethod) { myInitialisersPlaceModel.removeElement(BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD); } @@ -187,9 +187,11 @@ public class IntroduceFieldPopupPanel extends IntroduceFieldCentralPanel { } @Override - protected boolean updateInitializationPlaceModel(boolean initializedInSetup) { + protected boolean updateInitializationPlaceModel(boolean initializedInSetup, boolean initializedInConstructor) { myInitialisersPlaceModel.removeElement(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION); - myInitialisersPlaceModel.removeElement(BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR); + if (!initializedInConstructor) { + myInitialisersPlaceModel.removeElement(BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR); + } if (!initializedInSetup) { myInitialisersPlaceModel.removeElement(BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD); } else { From 7343c62b7e753094205aa2af01565a81496ea6d6 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 17 Dec 2014 18:59:57 +0100 Subject: [PATCH 4/8] new inference: infer exceptions for inner lambda body calls (IDEA-134225) --- .../intellij/codeInsight/ExceptionUtil.java | 7 +++++-- ...onsConstraintsSubstitutionsDeepInBody.java | 20 +++++++++++++++++++ .../lambda/NewLambdaHighlightingTest.java | 4 ++++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/CheckedExceptionsConstraintsSubstitutionsDeepInBody.java diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java index abb7d3fc5038..fb7f7653a16a 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java @@ -465,12 +465,15 @@ public class ExceptionUtil { final PsiLambdaExpression expression = PsiTreeUtil.getParentOfType(methodCall, PsiLambdaExpression.class); final PsiSubstitutor substitutor; if (expression != null) { - substitutor = ourThrowsGuard.doPreventingRecursion(expression, false, new Computable() { + final PsiElement parent = methodCall.getParent(); + final boolean callInReturnStatement = parent == expression || + parent instanceof PsiReturnStatement && PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class, true, PsiMethod.class) == expression; + substitutor = callInReturnStatement ? ourThrowsGuard.doPreventingRecursion(expression, false, new Computable() { @Override public PsiSubstitutor compute() { return result.getSubstitutor(); } - }); + }) : result.getSubstitutor(); } else { substitutor = result.getSubstitutor(); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/CheckedExceptionsConstraintsSubstitutionsDeepInBody.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/CheckedExceptionsConstraintsSubstitutionsDeepInBody.java new file mode 100644 index 000000000000..42ceb7b84b17 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/CheckedExceptionsConstraintsSubstitutionsDeepInBody.java @@ -0,0 +1,20 @@ +import java.io.IOException; +import java.util.Optional; + +class Test { + + interface Extractor { + T extractData() throws IOException; + } + + public static T query(Extractor rse) { + return null; + } + + static { + final Optional query = query(() -> { + final String type = Optional.empty().orElseThrow(null); + return null; + }); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java index 5df6f0907d6e..9ed3666e622f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java @@ -140,6 +140,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testCheckedExceptionsConstraintsSubstitutionsDeepInBody() throws Exception { + doTest(); + } + public void testIDEA130129() throws Exception { doTest(); } From 24a7a43f7c2a85e12838608fe239c43fffadc393 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 17 Dec 2014 19:19:31 +0100 Subject: [PATCH 5/8] redundant lambda code block: ensure conflicts between same param numbers are checked --- .../RedundantLambdaCodeBlockInspection.java | 5 +++- .../JavaMethodsConflictResolver.java | 6 ++--- .../afterVarargsNoConflict.java | 23 +++++++++++++++++ .../beforeVarargsNoConflict.java | 25 +++++++++++++++++++ 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/afterVarargsNoConflict.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/beforeVarargsNoConflict.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java index 6b45deb9654e..55f9a254bce9 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java @@ -88,7 +88,10 @@ public class RedundantLambdaCodeBlockInspection extends BaseJavaBatchLocalInspec final List info = new ArrayList(Arrays.asList(candidates)); final LanguageLevel level = PsiUtil.getLanguageLevel(parent); final JavaMethodsConflictResolver conflictResolver = new JavaMethodsConflictResolver((PsiExpressionList)parent, level); - conflictResolver.checkSpecifics(info, MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY, level); + final PsiExpressionList argumentList = ((PsiCallExpression)gParent).getArgumentList(); + if (argumentList == null) return; + JavaMethodsConflictResolver.checkParametersNumber(info, argumentList.getExpressions().length, false); + conflictResolver.checkSpecifics(info, MethodCandidateInfo.ApplicabilityLevel.VARARGS, level); if (info.size() > 1) { return; } diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java index 7e29a1bd448d..9127c8bcaa0a 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java @@ -308,9 +308,9 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ return ((MethodCandidateInfo)info).getPertinentApplicabilityLevel() != MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE; } - private static boolean checkParametersNumber(@NotNull List conflicts, - final int argumentsCount, - boolean ignoreIfStaticsProblem) { + public static boolean checkParametersNumber(@NotNull List conflicts, + final int argumentsCount, + boolean ignoreIfStaticsProblem) { boolean atLeastOneMatch = false; TIntArrayList unmatchedIndices = null; for (int i = 0; i < conflicts.size(); i++) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/afterVarargsNoConflict.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/afterVarargsNoConflict.java new file mode 100644 index 000000000000..3094a7aa6dea --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/afterVarargsNoConflict.java @@ -0,0 +1,23 @@ +// "Replace with expression lambda" "true" +import java.util.HashSet; +import java.util.Set; + +class Test { + public static void main(String[] args) { + Set strings = new HashSet<>(); + new Test().query("", pResultSet -> strings.add("Col1")); + } + + public Object query(String s, final ResultSetExtractor rse) { + return null; + } + + public Object query(String s, final ResultSetExtractor rse, Object.. args) { + return null; + } +} + +interface ResultSetExtractor { + Object extractData(ResultSet var1); +} +class ResultSet {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/beforeVarargsNoConflict.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/beforeVarargsNoConflict.java new file mode 100644 index 000000000000..4eb05a829f3a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/beforeVarargsNoConflict.java @@ -0,0 +1,25 @@ +// "Replace with expression lambda" "true" +import java.util.HashSet; +import java.util.Set; + +class Test { + public static void main(String[] args) { + Set strings = new HashSet<>(); + new Test().query("", pResultSet -> { + strings.add("Col1"); + }); + } + + public Object query(String s, final ResultSetExtractor rse) { + return null; + } + + public Object query(String s, final ResultSetExtractor rse, Object.. args) { + return null; + } +} + +interface ResultSetExtractor { + Object extractData(ResultSet var1); +} +class ResultSet {} \ No newline at end of file From 0be4af00e07236c43ba9800225136b19962780f1 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 17 Dec 2014 20:45:29 +0100 Subject: [PATCH 6/8] new overload resolution: block can complete normally if the last statement could throw exception (IDEA-134103) --- .../psi/controlFlow/ControlFlowUtil.java | 2 +- ...yWithCallWithExceptionAsLastStatement.java | 28 +++++++++++++++++++ .../daemon/lambda/OverloadResolutionTest.java | 4 +++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/VoidValueCompatibilityCanCompleteNormallyWithCallWithExceptionAsLastStatement.java diff --git a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java index 9eca6e8736b2..712fd868ab94 100644 --- a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java @@ -728,7 +728,7 @@ public class ControlFlowUtil { int throwToOffset = instruction.offset; boolean isNormal; if (throwToOffset == nextOffset) { - isNormal = throwToOffset <= endOffset && !isLeaf(nextOffset) && canCompleteNormally[nextOffset]; + isNormal = nextOffset == endOffset || throwToOffset <= endOffset && !isLeaf(nextOffset) && canCompleteNormally[nextOffset]; } else { isNormal = canCompleteNormally[nextOffset]; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/VoidValueCompatibilityCanCompleteNormallyWithCallWithExceptionAsLastStatement.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/VoidValueCompatibilityCanCompleteNormallyWithCallWithExceptionAsLastStatement.java new file mode 100644 index 000000000000..0551b2bcca1b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/VoidValueCompatibilityCanCompleteNormallyWithCallWithExceptionAsLastStatement.java @@ -0,0 +1,28 @@ +import java.io.IOException; + +class Test { + { + query(() -> { + process(); + }); + } + + public static void process() throws IOException {} + + private void query(B var2) { + System.out.println(var2); + + } + + private void query( A rch) { + System.out.println(rch); + } + + interface A { + void m() throws IOException; + } + + interface B { + T n() throws IOException; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java index 82f04e789907..1b27e3539a9a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java @@ -43,6 +43,10 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testVoidValueCompatibilityCanCompleteNormallyWithCallWithExceptionAsLastStatement() throws Exception { + doTest(); + } + public void testIDEA102800() throws Exception { doTest(); } From 2c51acf8dfb7f6460181d36d7b0c0af35640f061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20C=C3=A9bron?= Date: Wed, 17 Dec 2014 21:50:57 +0100 Subject: [PATCH 7/8] DomStubUsingTest: remove duplication --- .../util/xml/stubs/DomStubUsingTest.java | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/xml/dom-tests/tests/com/intellij/util/xml/stubs/DomStubUsingTest.java b/xml/dom-tests/tests/com/intellij/util/xml/stubs/DomStubUsingTest.java index 221b9f346982..cd00fc62143e 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/stubs/DomStubUsingTest.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/stubs/DomStubUsingTest.java @@ -126,33 +126,27 @@ public class DomStubUsingTest extends DomStubTest { final DomFileElement fileElement = prepare("foo.xml", Foo.class); final Bar bar = fileElement.getRootElement().getBars().get(0); - assertNotNull(bar); - assertTrue(bar.exists()); - - new WriteCommandAction.Simple(null) { - @Override - protected void run() throws Throwable { - bar.undefine(); - } - }.execute().throwException(); - - assertFalse(bar.exists()); + assertUndefine(bar); } public void testRootElementUndefineNotExisting() { final DomFileElement fileElement = prepare("foo.xml", Foo.class); final DomElement rootElement = fileElement.getRootElement(); - assertNotNull(rootElement); - assertTrue(rootElement.exists()); + assertUndefine(rootElement); + } + + private static void assertUndefine(final DomElement domElement) { + assertNotNull(domElement); + assertTrue(domElement.exists()); new WriteCommandAction.Simple(null) { @Override protected void run() throws Throwable { - rootElement.undefine(); + domElement.undefine(); } }.execute().throwException(); - assertFalse(rootElement.exists()); + assertFalse(domElement.exists()); } } From 0f54629d8375ee8e53a6ad9efcfcb005d4eda2a3 Mon Sep 17 00:00:00 2001 From: Michael Golubev Date: Wed, 17 Dec 2014 22:32:21 +0100 Subject: [PATCH 8/8] Docker integration - logs --- .../util/CloudServerRuntimeInstance.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudServerRuntimeInstance.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudServerRuntimeInstance.java index ae6d30da651f..8b9cc7f52029 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudServerRuntimeInstance.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudServerRuntimeInstance.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -23,11 +23,13 @@ import com.intellij.remoteServer.agent.util.CloudRemoteApplication; import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration; import com.intellij.remoteServer.runtime.ServerTaskExecutor; import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance; +import com.intellij.util.Function; import com.intellij.util.ThrowableRunnable; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import java.io.File; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -86,7 +88,7 @@ public abstract class CloudServerRuntimeInstance } @Override - public void computeDeployments(@NotNull final ServerRuntimeInstance.ComputeDeploymentsCallback callback) { + public void computeDeployments(@NotNull final ComputeDeploymentsCallback callback) { getTaskExecutor().submit(new ThrowableRunnable() { @Override @@ -109,11 +111,16 @@ public abstract class CloudServerRuntimeInstance @Override public List compute() { - List result = new ArrayList(); - for (CloudRemoteApplication application : getAgent().getApplications()) { - result.add(createApplicationRuntime(application)); + CloudRemoteApplication[] applications = getAgent().getApplications(); + if (applications == null) { + return Collections.emptyList(); } - return result; + return ContainerUtil.map(applications, new Function() { + @Override + public CloudApplicationRuntime fun(CloudRemoteApplication application) { + return createApplicationRuntime(application); + } + }); } }); }