From f11480e276cd17395472f28d03cdf068312a64ce Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Fri, 12 Oct 2012 18:09:50 +0400 Subject: [PATCH 1/9] ProjectTemplate validation IDEA-92573 New Project/Module Wizard: Create from template: "Next" button should be disabled if template version is not specified due to no Internet connection; RE at GithubProjectGeneratorPeer.getSettings() --- .../ide/util/newProjectWizard/SelectTemplateStep.java | 8 +++++++- .../platform/templates/ArchivedProjectTemplate.java | 8 ++++++++ .../platform/templates/EmptyModuleTemplatesFactory.java | 7 +++++++ .../ide/util/projectWizard/WebModuleGenerationStep.java | 6 +++++- .../ide/util/projectWizard/WebProjectTemplate.java | 8 ++++++++ .../boilerplate/GithubProjectGeneratorPeer.java | 6 +++++- .../src/com/intellij/platform/ProjectTemplate.java | 7 +++++++ 7 files changed, 47 insertions(+), 3 deletions(-) diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java index 13e2419da3a5..59d67f4a8ca0 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java @@ -26,6 +26,7 @@ import com.intellij.openapi.actionSystem.CustomShortcutSet; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.ValidationInfo; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.SystemInfo; @@ -251,9 +252,14 @@ public class SelectTemplateStep extends ModuleWizardStep { @Override public boolean validate() throws ConfigurationException { - if (getSelectedTemplate() == null) { + ProjectTemplate template = getSelectedTemplate(); + if (template == null) { throw new ConfigurationException(ProjectBundle.message("project.new.wizard.from.template.error", myContext.getPresentationName())); } + ValidationInfo info = template.validateSettings(); + if (info != null) { + throw new ConfigurationException(info.message); + } return true; } diff --git a/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java b/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java index 74d4e42b831c..8e26316e3a52 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java +++ b/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java @@ -25,6 +25,7 @@ import com.intellij.openapi.module.ModuleWithNameAlreadyExists; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.ui.ValidationInfo; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.io.StreamUtil; @@ -36,6 +37,7 @@ import com.intellij.platform.templates.github.ZipUtil; import com.intellij.util.containers.ContainerUtil; import org.jdom.JDOMException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.io.File; @@ -129,6 +131,12 @@ public class ArchivedProjectTemplate implements ProjectTemplate { }; } + @Nullable + @Override + public ValidationInfo validateSettings() { + return null; + } + private ZipInputStream getStream() throws IOException { return new ZipInputStream(myArchivePath.openStream()); } diff --git a/java/idea-ui/src/com/intellij/platform/templates/EmptyModuleTemplatesFactory.java b/java/idea-ui/src/com/intellij/platform/templates/EmptyModuleTemplatesFactory.java index aa2c0450e09b..934420591f08 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/EmptyModuleTemplatesFactory.java +++ b/java/idea-ui/src/com/intellij/platform/templates/EmptyModuleTemplatesFactory.java @@ -17,6 +17,7 @@ package com.intellij.platform.templates; import com.intellij.ide.util.projectWizard.ModuleBuilder; import com.intellij.ide.util.projectWizard.WizardContext; +import com.intellij.openapi.ui.ValidationInfo; import com.intellij.platform.ProjectTemplate; import com.intellij.platform.ProjectTemplatesFactory; import com.intellij.util.Function; @@ -72,6 +73,12 @@ public class EmptyModuleTemplatesFactory implements ProjectTemplatesFactory { public ModuleBuilder createModuleBuilder() { return builder; } + + @Nullable + @Override + public ValidationInfo validateSettings() { + return null; + } }; } }); diff --git a/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebModuleGenerationStep.java b/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebModuleGenerationStep.java index a1a85e3389d8..ad52821d9e56 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebModuleGenerationStep.java +++ b/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebModuleGenerationStep.java @@ -189,7 +189,11 @@ public class WebModuleGenerationStep extends ModuleWizardStep { if (peer == null) { throw new ConfigurationException("Peer should be not-null for " + myCurrentGenerator.getName()); } - return peer.validate() == null; + ValidationInfo validate = peer.validate(); + if (validate != null) { + throw new ConfigurationException(validate.message); + } + return true; } @SuppressWarnings("unchecked") diff --git a/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebProjectTemplate.java b/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebProjectTemplate.java index 01fb8ed639f1..f3f85ee4225a 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebProjectTemplate.java +++ b/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebProjectTemplate.java @@ -23,10 +23,12 @@ import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.ui.ValidationInfo; import com.intellij.openapi.util.NotNullLazyValue; import com.intellij.platform.ProjectTemplate; import com.intellij.platform.WebProjectGenerator; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.List; @@ -76,4 +78,10 @@ public abstract class WebProjectTemplate extends WebProjectGenerator imple } }; } + + @Nullable + @Override + public ValidationInfo validateSettings() { + return myPeer.getValue().validate(); + } } diff --git a/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/GithubProjectGeneratorPeer.java b/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/GithubProjectGeneratorPeer.java index f3e0e6243d16..475fc679a7cc 100644 --- a/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/GithubProjectGeneratorPeer.java +++ b/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/GithubProjectGeneratorPeer.java @@ -157,7 +157,11 @@ public class GithubProjectGeneratorPeer implements WebProjectGenerator.Generator @Override @Nullable public ValidationInfo validate() { - return null; + Object obj = myComboBox.getSelectedItem(); + if (obj instanceof GithubTagInfo) { + return null; + } + return new ValidationInfo("Can't handle selected version: " + obj); } @Override diff --git a/platform/platform-impl/src/com/intellij/platform/ProjectTemplate.java b/platform/platform-impl/src/com/intellij/platform/ProjectTemplate.java index baaaa66f02b8..c4dbc87f7e4c 100644 --- a/platform/platform-impl/src/com/intellij/platform/ProjectTemplate.java +++ b/platform/platform-impl/src/com/intellij/platform/ProjectTemplate.java @@ -16,6 +16,7 @@ package com.intellij.platform; import com.intellij.ide.util.projectWizard.ModuleBuilder; +import com.intellij.openapi.ui.ValidationInfo; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -38,4 +39,10 @@ public interface ProjectTemplate { @NotNull ModuleBuilder createModuleBuilder(); + + /** + * @return null if ok, error message otherwise + */ + @Nullable + ValidationInfo validateSettings(); } From 94d8f9c42e3f66039c11c7ff70fa58ac03dc9a7e Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Fri, 12 Oct 2012 18:21:43 +0400 Subject: [PATCH 2/9] renames, set "include assets from libraries" option to true for existing project and false for new projects by default --- .../android/util/AndroidCommonUtils.java | 1 + .../jps/android/AndroidPackagingBuilder.java | 4 +-- .../model/JpsAndroidModuleExtension.java | 2 +- .../impl/JpsAndroidModuleExtensionImpl.java | 4 +-- .../impl/JpsAndroidModuleProperties.java | 5 +-- .../AndroidResourcesPackagingCompiler.java | 2 +- .../compiler/ResourcesValidityState.java | 2 +- .../facet/AndroidFacetConfiguration.java | 34 +++++++++++++------ .../android/facet/AndroidFacetEditorTab.java | 6 ++-- .../maven/AndroidFacetImporterBase.java | 2 +- 10 files changed, 39 insertions(+), 23 deletions(-) diff --git a/plugins/android/common/src/org/jetbrains/android/util/AndroidCommonUtils.java b/plugins/android/common/src/org/jetbrains/android/util/AndroidCommonUtils.java index dacb858218b8..08d47344bd7b 100644 --- a/plugins/android/common/src/org/jetbrains/android/util/AndroidCommonUtils.java +++ b/plugins/android/common/src/org/jetbrains/android/util/AndroidCommonUtils.java @@ -82,6 +82,7 @@ public class AndroidCommonUtils { }; @NonNls public static final String INCLUDE_SYSTEM_PROGUARD_FILE_ELEMENT_NAME = "includeSystemProguardFile"; + @NonNls public static final String INCLUDE_ASSETS_FROM_LIBRARIES_ELEMENT_NAME = "includeAssetsFromLibraraies"; @NonNls public static final String ADDITIONAL_NATIVE_LIBS_ELEMENT = "additionalNativeLibs"; @NonNls public static final String ITEM_ELEMENT = "item"; @NonNls public static final String ARCHITECTURE_ATTRIBUTE = "architecture"; diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidPackagingBuilder.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidPackagingBuilder.java index 8f8a995d5453..85c2ec4a95a9 100644 --- a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidPackagingBuilder.java +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidPackagingBuilder.java @@ -257,7 +257,7 @@ public class AndroidPackagingBuilder extends TargetBuilder RES_OVERLAY_FOLDERS = new ArrayList(); diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidResourcesPackagingCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidResourcesPackagingCompiler.java index 5926f0358b0b..34e2d75fa8be 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidResourcesPackagingCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidResourcesPackagingCompiler.java @@ -102,7 +102,7 @@ public class AndroidResourcesPackagingCompiler implements ClassPostProcessingCom if (assetsDir != null) { result.add(FileUtil.toSystemDependentName(assetsDir.getPath())); } - if (facet.getConfiguration().PACK_ASSETS_FROM_LIBRARIES) { + if (facet.getConfiguration().isIncludeAssetsFromLibraries()) { for (AndroidFacet depFacet : AndroidUtils.getAllAndroidDependencies(facet.getModule(), true)) { final VirtualFile depAssetsDir = AndroidRootUtil.getAssetsDir(depFacet); diff --git a/plugins/android/src/org/jetbrains/android/compiler/ResourcesValidityState.java b/plugins/android/src/org/jetbrains/android/compiler/ResourcesValidityState.java index 65c601323f96..f9ae4db84044 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/ResourcesValidityState.java +++ b/plugins/android/src/org/jetbrains/android/compiler/ResourcesValidityState.java @@ -77,7 +77,7 @@ public class ResourcesValidityState implements ValidityState { if (depResDir != null) { collectFiles(depResDir); } - if (configuration.PACK_ASSETS_FROM_LIBRARIES) { + if (configuration.isIncludeAssetsFromLibraries()) { final VirtualFile depAssetDir = AndroidRootUtil.getAssetsDir(depFacet); if (depAssetDir != null) { collectFiles(depAssetDir); diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java index 0febbe48859d..ac3a7436225f 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java @@ -62,8 +62,6 @@ public class AndroidFacetConfiguration implements FacetConfiguration { public String ASSETS_FOLDER_RELATIVE_PATH = "/" + SdkConstants.FD_ASSETS; public String LIBS_FOLDER_RELATIVE_PATH = "/" + SdkConstants.FD_NATIVE_LIBS; - public boolean PACK_ASSETS_FROM_LIBRARIES = false; - public List RES_OVERLAY_FOLDERS = Arrays.asList("/res-overlay"); public boolean USE_CUSTOM_APK_RESOURCE_FOLDER = false; @@ -88,6 +86,7 @@ public class AndroidFacetConfiguration implements FacetConfiguration { public String PROGUARD_CFG_PATH = "/" + AndroidCompileUtil.PROGUARD_CFG_FILE_NAME; private boolean myIncludeSystemProguardCfgPath = true; + private boolean myIncludeAssetsFromLibraries = false; private List myAdditionalNativeLibraries = Collections.emptyList(); @@ -167,15 +166,18 @@ public class AndroidFacetConfiguration implements FacetConfiguration { } final Element includeSystemProguardFile = element.getChild(AndroidCommonUtils.INCLUDE_SYSTEM_PROGUARD_FILE_ELEMENT_NAME); - if (includeSystemProguardFile != null) { - final String includeSystemProguardFileValue = includeSystemProguardFile.getValue(); + final String includeSystemProguardFileValue = includeSystemProguardFile != null + ? includeSystemProguardFile.getValue() + : null; + myIncludeSystemProguardCfgPath = includeSystemProguardFileValue != null && + Boolean.parseBoolean(includeSystemProguardFileValue); - if (includeSystemProguardFileValue != null) { - myIncludeSystemProguardCfgPath = Boolean.parseBoolean(includeSystemProguardFileValue); - return; - } - } - myIncludeSystemProguardCfgPath = false; + final Element includeAssetsFromLibraries = element.getChild(AndroidCommonUtils.INCLUDE_ASSETS_FROM_LIBRARIES_ELEMENT_NAME); + final String includeAssetsFromLibrariesValue = includeAssetsFromLibraries != null + ? includeAssetsFromLibraries.getValue() + : null; + myIncludeAssetsFromLibraries = includeAssetsFromLibrariesValue == null || + Boolean.parseBoolean(includeAssetsFromLibrariesValue); } public void writeExternal(Element element) throws WriteExternalException { @@ -186,6 +188,10 @@ public class AndroidFacetConfiguration implements FacetConfiguration { includeSystemProguerdFile.setText(Boolean.toString(myIncludeSystemProguardCfgPath)); element.addContent(includeSystemProguerdFile); + final Element includeAssetsFromLibraries = new Element(AndroidCommonUtils.INCLUDE_ASSETS_FROM_LIBRARIES_ELEMENT_NAME); + includeAssetsFromLibraries.setText(Boolean.toString(myIncludeAssetsFromLibraries)); + element.addContent(includeAssetsFromLibraries); + final Element additionalNativeLibs = new Element(AndroidCommonUtils.ADDITIONAL_NATIVE_LIBS_ELEMENT); for (AndroidNativeLibData lib : myAdditionalNativeLibraries) { @@ -238,4 +244,12 @@ public class AndroidFacetConfiguration implements FacetConfiguration { public void setAdditionalNativeLibraries(@NotNull List additionalNativeLibraries) { myAdditionalNativeLibraries = additionalNativeLibraries; } + + public boolean isIncludeAssetsFromLibraries() { + return myIncludeAssetsFromLibraries; + } + + public void setIncludeAssetsFromLibraries(boolean includeAssetsFromLibraries) { + myIncludeAssetsFromLibraries = includeAssetsFromLibraries; + } } diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java index e464c58c4e98..1fb52fc130b4 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java @@ -316,7 +316,7 @@ public class AndroidFacetEditorTab extends FacetEditorTab { if (myConfiguration.PACK_TEST_CODE != myIncludeTestCodeAndCheckBox.isSelected()) { return true; } - if (myConfiguration.PACK_ASSETS_FROM_LIBRARIES != myIncludeAssetsFromLibraries.isSelected()) { + if (myConfiguration.isIncludeAssetsFromLibraries() != myIncludeAssetsFromLibraries.isSelected()) { return true; } @@ -437,7 +437,7 @@ public class AndroidFacetEditorTab extends FacetEditorTab { myConfiguration.PACK_TEST_CODE = myIncludeTestCodeAndCheckBox.isSelected(); - myConfiguration.PACK_ASSETS_FROM_LIBRARIES = myIncludeAssetsFromLibraries.isSelected(); + myConfiguration.setIncludeAssetsFromLibraries(myIncludeAssetsFromLibraries.isSelected()); String absProguardPath = myProguardConfigFileTextField.getText().trim(); if (absProguardPath.length() == 0) { @@ -566,7 +566,7 @@ public class AndroidFacetEditorTab extends FacetEditorTab { myGenerateUnsignedApk.setSelected(myConfiguration.GENERATE_UNSIGNED_APK); myIncludeTestCodeAndCheckBox.setSelected(myConfiguration.PACK_TEST_CODE); - myIncludeAssetsFromLibraries.setSelected(myConfiguration.PACK_ASSETS_FROM_LIBRARIES); + myIncludeAssetsFromLibraries.setSelected(myConfiguration.isIncludeAssetsFromLibraries()); updateAptPanel(); diff --git a/plugins/android/src/org/jetbrains/android/maven/AndroidFacetImporterBase.java b/plugins/android/src/org/jetbrains/android/maven/AndroidFacetImporterBase.java index 2b6d23ca47e8..6cb5352becf2 100644 --- a/plugins/android/src/org/jetbrains/android/maven/AndroidFacetImporterBase.java +++ b/plugins/android/src/org/jetbrains/android/maven/AndroidFacetImporterBase.java @@ -119,7 +119,7 @@ public abstract class AndroidFacetImporterBase extends FacetImporter Date: Fri, 12 Oct 2012 19:06:28 +0400 Subject: [PATCH 3/9] IDEA-92375, IDEA-62134 console result tabs should be closeable with middle-click --- .../ui/layout/impl/GridCellImpl.java | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java index 6671454b81c0..1a850c04d0a4 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java @@ -17,6 +17,7 @@ package com.intellij.execution.ui.layout.impl; import com.intellij.execution.ui.layout.*; +import com.intellij.execution.ui.layout.actions.CloseViewAction; import com.intellij.execution.ui.layout.actions.MinimizeViewAction; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.DataProvider; @@ -119,7 +120,7 @@ public class GridCellImpl implements GridCell { myTabs.addTabMouseListener(new MouseAdapter() { public void mousePressed(final MouseEvent e) { if (UIUtil.isCloseClick(e)) { - minimize(e); + minimizeOrClose(e); } } }); @@ -250,7 +251,8 @@ public class GridCellImpl implements GridCell { if (myTabs.getSelectedInfo() != tab) { if (activate) { tab.fireAlert(); - } else { + } + else { tab.stopAlerting(); } } @@ -337,7 +339,8 @@ public class GridCellImpl implements GridCell { tab.setDetached(myPlaceInGrid, false); } myContext.detachTo(window, this).notifyWhenDone(result); - } else { + } + else { result.setDone(); } @@ -432,7 +435,7 @@ public class GridCellImpl implements GridCell { public Dimension getSize() { return DimensionService.getInstance().getSize(getDimensionKey(), myContext.getProject()); } - + private String getDimensionKey() { return "GridCell.Tab." + myContainer.getTab().getIndex() + "." + myPlaceInGrid.name(); } @@ -445,12 +448,16 @@ public class GridCellImpl implements GridCell { minimize(new Content[]{content}); } - public void minimize(MouseEvent e) { - if (!MinimizeViewAction.isEnabled(myContext, getContents(), ViewContext.CELL_TOOLBAR_PLACE)) return; - + public void minimizeOrClose(MouseEvent e) { TabInfo tabInfo = myTabs.findInfo(e); - if (tabInfo != null) { - minimize(getContentFor(tabInfo)); + if (tabInfo == null) return; + + Content content = getContentFor(tabInfo); + if (MinimizeViewAction.isEnabled(myContext, getContents(), ViewContext.CELL_TOOLBAR_PLACE)) { + minimize(content); + } + else if (CloseViewAction.isEnabled(new Content[]{content})) { + CloseViewAction.perform(myContext, content); } } From 59d8eafbcea35a42284e85b49b16e9756db7deee Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 12 Oct 2012 15:47:30 +0200 Subject: [PATCH 4/9] NPE (IDEA-92859) --- .../AnonymousCanBeMethodReferenceInspection.java | 2 +- .../codeInspection/LambdaCanBeMethReferenceInspection.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java b/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java index 6dba43ed261f..2952f93ebfdc 100644 --- a/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java @@ -116,7 +116,7 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaLocalInspec final PsiCallExpression callExpression = LambdaCanBeMethReferenceInspection.canBeMethodReferenceProblem(methods[0].getBody(), parameters, anonymousClass.getBaseClassType()); if (callExpression == null) return; final String methodRefText = - LambdaCanBeMethReferenceInspection.createMethodReferenceText(callExpression, parameters, anonymousClass.getBaseClassType()); + LambdaCanBeMethReferenceInspection.createMethodReferenceText(callExpression, anonymousClass.getBaseClassType()); if (methodRefText != null) { final String canonicalText = anonymousClass.getBaseClassType().getCanonicalText(); diff --git a/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java b/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java index ca7fe43fd5d2..8c61532d14e9 100644 --- a/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java @@ -168,12 +168,12 @@ public class LambdaCanBeMethReferenceInspection extends BaseJavaLocalInspectionT } @Nullable - protected static String createMethodReferenceText(PsiElement element, final PsiParameter[] parameters, PsiType functionalInterfaceType) { + protected static String createMethodReferenceText(PsiElement element, PsiType functionalInterfaceType) { String methodRefText = null; if (element instanceof PsiMethodCallExpression) { final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)element; final PsiMethod psiMethod = methodCall.resolveMethod(); - LOG.assertTrue(psiMethod != null); + if (psiMethod == null) return null; final PsiClass containingClass = psiMethod.getContainingClass(); LOG.assertTrue(containingClass != null); final PsiReferenceExpression methodExpression = methodCall.getMethodExpression(); @@ -227,7 +227,7 @@ public class LambdaCanBeMethReferenceInspection extends BaseJavaLocalInspectionT final PsiElement element = descriptor.getPsiElement(); final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class); if (lambdaExpression == null) return; - final String methodRefText = createMethodReferenceText(element, lambdaExpression.getParameterList().getParameters(), lambdaExpression.getFunctionalInterfaceType()); + final String methodRefText = createMethodReferenceText(element, lambdaExpression.getFunctionalInterfaceType()); if (methodRefText != null) { final PsiExpression psiExpression = From 289ee1d04c6a37555f1df258659919b1b92bef17 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 12 Oct 2012 17:09:59 +0200 Subject: [PATCH 5/9] lambda: do not override already inferred types from parent (IDEA-92733) --- .../source/resolve/PsiResolveHelperImpl.java | 5 ++++- .../IncompatibleFormalParameterTypes.java | 19 +++++++++++++++++++ .../daemon/lambda/LambdaHighlightingTest.java | 6 +++++- 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompatibleFormalParameterTypes.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java index d193ee56081d..a346115cbea3 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java @@ -993,7 +993,10 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { if (method == null || methodParamsDependOn(typeParameter, expression, functionalInterfaceType, method.getParameterList().getParameters(), LambdaUtil.getSubstitutor(method, resolveResult))) { - return getFailedInferenceConstraint(typeParameter); + if (expression instanceof PsiMethodReferenceExpression) { + return getFailedInferenceConstraint(typeParameter); + } + return null; } } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompatibleFormalParameterTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompatibleFormalParameterTypes.java new file mode 100644 index 000000000000..ce112bb0b0b6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompatibleFormalParameterTypes.java @@ -0,0 +1,19 @@ +class LambdaTest { + + public void highlightsTheBug(Stream stream) { + stream.flatMap((Block sink, String element) -> {}); + } + + public interface Block { + void apply(B t); + } + + public interface Stream { + Stream flatMap(FlatMapper mapper); + + } + + public interface FlatMapper { + void flatMapInto(Block sink, F element); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java index a4fa1a498b3e..6dac84473075 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java @@ -152,7 +152,11 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { public void testRecursiveAccess() throws Exception { doTest(); } - + + public void testIncompatibleFormalParameterTypes() throws Exception { + doTest(); + } + private void doTest() throws Exception { doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false); } From 486c88b0491cad0ab9cf2436212475e3f07c6e58 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 12 Oct 2012 17:29:12 +0200 Subject: [PATCH 6/9] method refs -> lambda: correctly remove type element type arguments (IDEA-92862) --- .../ReplaceMethodRefWithLambdaIntention.java | 17 ++++++++++++----- .../methodRefs2lambda/TypeElementOnTheLeft.java | 9 +++++++++ .../TypeElementOnTheLeft_after.java | 9 +++++++++ ...eMethodReferenceWithLambdaIntentionTest.java | 4 ++++ 4 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/TypeElementOnTheLeft.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/TypeElementOnTheLeft_after.java diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java index ebf101b6b8e3..d54828570e2c 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java @@ -92,11 +92,18 @@ public class ReplaceMethodRefWithLambdaIntention extends Intention { final PsiElement referenceNameElement = referenceExpression.getReferenceNameElement(); if (isReceiver){ buf.append(parameters[0].getName()).append("."); - } else if (qualifier != null && - !(qualifier instanceof PsiThisExpression && ((PsiThisExpression)qualifier).getQualifier() == null) && - !(referenceNameElement instanceof PsiKeyword)){ - buf.append(qualifier.getText()).append("."); - } + } else { + if (!(referenceNameElement instanceof PsiKeyword)) { + if (qualifier instanceof PsiTypeElement) { + final PsiJavaCodeReferenceElement referenceElement = ((PsiTypeElement)qualifier).getInnermostComponentReferenceElement(); + LOG.assertTrue(referenceElement != null); + buf.append(referenceElement.getReferenceName()).append("."); + } + else if (qualifier != null && !(qualifier instanceof PsiThisExpression && ((PsiThisExpression)qualifier).getQualifier() == null)) { + buf.append(qualifier.getText()).append("."); + } + } + } //new or method name buf.append(referenceExpression.getReferenceName()); diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/TypeElementOnTheLeft.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/TypeElementOnTheLeft.java new file mode 100644 index 000000000000..f3549e6c0c9c --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/TypeElementOnTheLeft.java @@ -0,0 +1,9 @@ +class Test { + static void foo() {} +} + +class Bar { + void test() { + Runnable runnable = Test::foo; + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/TypeElementOnTheLeft_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/TypeElementOnTheLeft_after.java new file mode 100644 index 000000000000..6bf7b8d8d586 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/TypeElementOnTheLeft_after.java @@ -0,0 +1,9 @@ +class Test { + static void foo() {} +} + +class Bar { + void test() { + Runnable runnable = () -> Test.foo(); + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceMethodReferenceWithLambdaIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceMethodReferenceWithLambdaIntentionTest.java index 713fda56916a..bbc28d89732d 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceMethodReferenceWithLambdaIntentionTest.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceMethodReferenceWithLambdaIntentionTest.java @@ -81,4 +81,8 @@ public class ReplaceMethodReferenceWithLambdaIntentionTest extends IPPTestCase { public void testSubst() throws Exception { doTest(); } + + public void testTypeElementOnTheLeft() throws Exception { + doTest(); + } } From f4bea5007012cc6eb682062aa3861828c17cdbcf Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 12 Oct 2012 19:36:37 +0400 Subject: [PATCH 7/9] IDEA-18659 Debugger log tabs must be closable with middle click --- .../execution/ui/layout/impl/GridCellImpl.java | 13 +++++++------ .../execution/ui/layout/impl/RunnerContentUi.java | 10 ++++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java index 1a850c04d0a4..f63aa608a776 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java @@ -120,7 +120,8 @@ public class GridCellImpl implements GridCell { myTabs.addTabMouseListener(new MouseAdapter() { public void mousePressed(final MouseEvent e) { if (UIUtil.isCloseClick(e)) { - minimizeOrClose(e); + // see RunnerContentUi tabMouseListener as well + closeOrMinimize(e); } } }); @@ -448,17 +449,17 @@ public class GridCellImpl implements GridCell { minimize(new Content[]{content}); } - public void minimizeOrClose(MouseEvent e) { + public void closeOrMinimize(MouseEvent e) { TabInfo tabInfo = myTabs.findInfo(e); if (tabInfo == null) return; Content content = getContentFor(tabInfo); - if (MinimizeViewAction.isEnabled(myContext, getContents(), ViewContext.CELL_TOOLBAR_PLACE)) { - minimize(content); - } - else if (CloseViewAction.isEnabled(new Content[]{content})) { + if (CloseViewAction.isEnabled(new Content[]{content})) { CloseViewAction.perform(myContext, content); } + else if (MinimizeViewAction.isEnabled(myContext, getContents(), ViewContext.CELL_TOOLBAR_PLACE)) { + minimize(content); + } } ActionCallback restore(Content content) { diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java index 68ae02d5a523..f010e6c71741 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java @@ -19,6 +19,7 @@ package com.intellij.execution.ui.layout.impl; import com.intellij.execution.ui.RunnerLayoutUi; import com.intellij.execution.ui.layout.*; import com.intellij.execution.ui.layout.actions.CloseViewAction; +import com.intellij.execution.ui.layout.actions.MinimizeViewAction; import com.intellij.execution.ui.layout.actions.RestoreViewAction; import com.intellij.ide.DataManager; import com.intellij.openapi.Disposable; @@ -249,11 +250,16 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac public void mousePressed(MouseEvent e) { if (UIUtil.isCloseClick(e)) { final TabInfo tabInfo = myTabs.findInfo(e); - final GridImpl grid = getGridFor(tabInfo); + final GridImpl grid = tabInfo == null? null : getGridFor(tabInfo); final Content[] contents = grid != null ? CONTENT_KEY.getData(grid) : null; - if (contents != null && CloseViewAction.isEnabled(contents)) { + if (contents == null) return; + // see GridCellImpl.closeOrMinimize as well + if (CloseViewAction.isEnabled(contents)) { CloseViewAction.perform(RunnerContentUi.this, contents[0]); } + else if (MinimizeViewAction.isEnabled(RunnerContentUi.this, contents, ViewContext.TAB_TOOLBAR_PLACE)) { + grid.getCellFor(contents[0]).minimize(contents[0]); + } } } }); From 71fa3b8250c216f40a55aaad6ee40b74365fd2bf Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 12 Oct 2012 14:27:48 +0200 Subject: [PATCH 8/9] rounding seconds for build duration --- jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java index 8706efd46000..d8d5bc982a1d 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java @@ -138,7 +138,7 @@ public class Utils { public static String formatDuration(long duration) { final long minutes = duration / 60000; - final long seconds = (duration % 60000) / 1000; + final long seconds = ((duration + 500L) % 60000) / 1000; if (minutes > 0L) { return minutes + " min " + seconds + " sec"; } From 2138432b895bbba052285425029e4772c7ce5859 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 12 Oct 2012 17:34:45 +0200 Subject: [PATCH 9/9] do not let ProcessCanceledException stop DumbService's thread unexpectedly --- .../openapi/project/CacheUpdateRunner.java | 49 ++++++++--------- .../openapi/project/DumbServiceImpl.java | 35 +++++++----- .../openapi/project/FileContentQueue.java | 54 +++++++++++-------- 3 files changed, 78 insertions(+), 60 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java b/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java index 46e586cfc845..97fbbf98162b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java @@ -212,44 +212,45 @@ class CacheUpdateRunner { public void run() { while (true) { - if (myProject.isDisposed()) return; - if (myInnerIndicator.isCanceled()) return; - - final FileContent fileContent = myQueue.take(); - if (fileContent == null) { - myFinished.set(Boolean.TRUE); + if (myProject.isDisposed() || myInnerIndicator.isCanceled()) { return; } - try { - myQueue.waitForOtherContentReleaseToPreventOOM(myInnerIndicator, fileContent); + final FileContent fileContent = myQueue.take(myInnerIndicator); + if (fileContent == null) { + myFinished.set(Boolean.TRUE); + return; + } + final Runnable action = new Runnable() { public void run() { myInnerIndicator.checkCanceled(); - - if (myProject.isDisposed()) return; - - final VirtualFile file = fileContent.getVirtualFile(); - myProgressUpdater.consume(file); - mySession.processFile(fileContent); + if (!myProject.isDisposed()) { + final VirtualFile file = fileContent.getVirtualFile(); + myProgressUpdater.consume(file); + mySession.processFile(fileContent); + } } }; - if (myProcessInReadAction) { - myApplication.runReadAction(action); + try { + if (myProcessInReadAction) { + myApplication.runReadAction(action); + } + else { + action.run(); + } } - else { - action.run(); + catch (ProcessCanceledException e) { + myQueue.pushback(fileContent); + return; + } + finally { + myQueue.release(fileContent); } } catch (ProcessCanceledException e) { - myQueue.pushback(fileContent); return; } - finally { - if (fileContent != null) { - myQueue.release(fileContent); - } - } } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java index eabc98414002..149b09a1d1be 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java @@ -292,7 +292,7 @@ public class DumbServiceImpl extends DumbService { private volatile int myTotalItems; private double myCurrentBaseTotal; - public IndexUpdateRunnable(CacheUpdateRunner action) { + public IndexUpdateRunnable(@NotNull CacheUpdateRunner action) { myAction = action; myTotalItems = 0; myCurrentBaseTotal = 0; @@ -359,21 +359,28 @@ public class DumbServiceImpl extends DumbService { private void runAction(ProgressIndicator indicator, CacheUpdateRunner updateRunner) { while (updateRunner != null) { - indicator.setIndeterminate(true); - indicator.setText(IdeBundle.message("progress.indexing.scanning")); - int count = updateRunner.queryNeededFiles(indicator); + try { + indicator.checkCanceled(); + indicator.setIndeterminate(true); + indicator.setText(IdeBundle.message("progress.indexing.scanning")); + int count = updateRunner.queryNeededFiles(indicator); - myCurrentBaseTotal = count; - myTotalItems += count; + myCurrentBaseTotal = count; + myTotalItems += count; - indicator.setIndeterminate(false); - indicator.setText(IdeBundle.message("progress.indexing.updating")); - if (count > 0) { - updateRunner.processFiles(indicator, true); + indicator.setIndeterminate(false); + indicator.setText(IdeBundle.message("progress.indexing.updating")); + if (count > 0) { + updateRunner.processFiles(indicator, true); + } + updateRunner.updatingDone(); + myProcessedItems += count; + } + catch (ProcessCanceledException ignored) { + } + catch (Throwable unexpected) { + LOG.error(unexpected); } - updateRunner.updatingDone(); - myProcessedItems += count; - updateRunner = getNextUpdateRunner(); } } @@ -398,7 +405,7 @@ public class DumbServiceImpl extends DumbService { // try to obtain the next action or terminate if no actions left while (!myProject.isDisposed()) { try { - Ref ref = actionQueue.poll(500, TimeUnit.MILLISECONDS); + Ref ref = actionQueue.poll(500L, TimeUnit.MILLISECONDS); if (ref != null) { return ref.get(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/project/FileContentQueue.java b/platform/platform-impl/src/com/intellij/openapi/project/FileContentQueue.java index 7033f496f972..bc626fb6f19f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/FileContentQueue.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/FileContentQueue.java @@ -139,36 +139,46 @@ public class FileContentQueue { } } - void waitForOtherContentReleaseToPreventOOM(ProgressIndicator indicator, FileContent content) { - final long length = content.getLength(); - while (true) { - indicator.checkCanceled(); - synchronized (this) { - boolean requestingLargeSize = length > LARGE_SIZE_REQUEST_THRESHOLD; - if (requestingLargeSize) { - myLargeSizeRequested = true; - } + @Nullable + public FileContent take(@NotNull ProgressIndicator indicator) throws ProcessCanceledException{ + final FileContent content = doTake(); + if (content != null) { + final long length = content.getLength(); + while (true) { try { - if (myLargeSizeRequested && !requestingLargeSize || - myTakenSize + length > Math.max(TAKEN_FILES_THRESHOLD, length)) - wait(300L); - else { - myTakenSize += length; - if (requestingLargeSize) { - myLargeSizeRequested = false; - } - return; - } + indicator.checkCanceled(); } - catch (InterruptedException ignore) { - + catch (ProcessCanceledException e) { + pushback(content); + throw e; + } + synchronized (this) { + final boolean requestingLargeSize = length > LARGE_SIZE_REQUEST_THRESHOLD; + if (requestingLargeSize) { + myLargeSizeRequested = true; + } + try { + if (myLargeSizeRequested && !requestingLargeSize || myTakenSize + length > Math.max(TAKEN_FILES_THRESHOLD, length)) { + wait(300L); + } + else { + myTakenSize += length; + if (requestingLargeSize) { + myLargeSizeRequested = false; + } + return content; + } + } + catch (InterruptedException ignore) { + } } } } + return content; } @Nullable - FileContent take() { + private FileContent doTake() { FileContent result; synchronized (this) { result = myPushbackBuffer.poll();