diff --git a/bin/linux/libnotifywrapper.so b/bin/linux/libnotifywrapper.so index b7a4abd40b6e..7ed0beb2ceb7 100755 Binary files a/bin/linux/libnotifywrapper.so and b/bin/linux/libnotifywrapper.so differ diff --git a/bin/linux/libnotifywrapper64.so b/bin/linux/libnotifywrapper64.so index f7593a8e5c9e..d78fba9c994e 100755 Binary files a/bin/linux/libnotifywrapper64.so and b/bin/linux/libnotifywrapper64.so differ diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java index 66df588dac4d..b1164e51e9a0 100644 --- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java +++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java @@ -36,7 +36,9 @@ import com.intellij.ui.CollectionListModel; import com.intellij.ui.ColoredListCellRenderer; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.components.JBList; +import com.intellij.util.Function; import com.intellij.util.containers.ConcurrentMultiMap; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.FactoryMap; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; @@ -88,45 +90,7 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act myModulesProvider = modulesProvider; myTemplatesMap = new ConcurrentMultiMap(); - myTemplatesMap.putAllValues(CreateFromTemplateMode.getTemplatesMap(context, false)); - - for (ProjectCategory category : ProjectCategory.EXTENSION_POINT_NAME.getExtensions()) { - myTemplatesMap.put(new TemplatesGroup(category), new ArrayList()); - } - if (context.isCreatingNewProject()) { - MultiMap localTemplates = loadLocalTemplates(); - for (TemplatesGroup group : myTemplatesMap.keySet()) { - myTemplatesMap.putValues(group, localTemplates.get(group.getId())); - } - } - - // remove empty groups - for (Iterator>> iterator = myTemplatesMap.entrySet().iterator(); - iterator.hasNext(); ) { - Map.Entry> entry = iterator.next(); - if (entry.getValue().isEmpty()) { - iterator.remove(); - } - } - - List groups = new ArrayList(myTemplatesMap.keySet()); - Collections.sort(groups); - - // move subgroups - MultiMap subGroups = new MultiMap(); - for (ListIterator iterator = groups.listIterator(); iterator.hasNext(); ) { - TemplatesGroup group = iterator.next(); - if (group.getParentGroup() != null) { - subGroups.putValue(group.getParentGroup(), group); - iterator.remove(); - } - } - for (ListIterator iterator = groups.listIterator(); iterator.hasNext(); ) { - TemplatesGroup group = iterator.next(); - for (TemplatesGroup subGroup : subGroups.get(group.getName())) { - iterator.add(subGroup); - } - } + List groups = fillTemplatesMap(context); myProjectTypeList.setModel(new CollectionListModel(groups)); myProjectTypeList.setCellRenderer(new ColoredListCellRenderer() { @@ -137,9 +101,9 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act } else { setBorder(IdeBorderFactory.createEmptyBorder(3, 10, 3, 5)); + setIcon(value.getIcon()); } append(value.getName()); - setIcon(value.getIcon()); } }); @@ -165,6 +129,56 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act myProjectTypeList.setSelectedIndex(0); } + private List fillTemplatesMap(WizardContext context) { + myTemplatesMap.putAllValues(CreateFromTemplateMode.getTemplatesMap(context)); + + for (ProjectCategory category : ProjectCategory.EXTENSION_POINT_NAME.getExtensions()) { + myTemplatesMap.put(new TemplatesGroup(category), new ArrayList()); + } + if (context.isCreatingNewProject()) { + MultiMap localTemplates = loadLocalTemplates(); + for (TemplatesGroup group : myTemplatesMap.keySet()) { + myTemplatesMap.putValues(group, localTemplates.get(group.getId())); + } + } + + // remove empty groups + for (Iterator>> iterator = myTemplatesMap.entrySet().iterator(); + iterator.hasNext(); ) { + Map.Entry> entry = iterator.next(); + if (entry.getValue().isEmpty()) { + iterator.remove(); + } + } + + List groups = new ArrayList(myTemplatesMap.keySet()); + Collections.sort(groups); + Set groupNames = ContainerUtil.map2Set(groups, new Function() { + @Override + public String fun(TemplatesGroup group) { + return group.getName(); + } + }); + + // move subgroups + MultiMap subGroups = new MultiMap(); + for (ListIterator iterator = groups.listIterator(); iterator.hasNext(); ) { + TemplatesGroup group = iterator.next(); + String parentGroup = group.getParentGroup(); + if (parentGroup != null && groupNames.contains(parentGroup) && !group.getName().equals(parentGroup)) { + subGroups.putValue(parentGroup, group); + iterator.remove(); + } + } + for (ListIterator iterator = groups.listIterator(); iterator.hasNext(); ) { + TemplatesGroup group = iterator.next(); + for (TemplatesGroup subGroup : subGroups.get(group.getName())) { + iterator.add(subGroup); + } + } + return groups; + } + // new category or template is selected public void projectTypeChanged() { diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java index a48dd3a94e37..fc44fa57cad9 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java @@ -24,7 +24,6 @@ import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.platform.ProjectTemplate; import com.intellij.platform.ProjectTemplatesFactory; -import com.intellij.platform.templates.ArchivedTemplatesFactory; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,11 +40,10 @@ public class CreateFromTemplateMode extends WizardMode { private SelectTemplateStep mySelectTemplateStep; - public static MultiMap getTemplatesMap(WizardContext context, boolean includeArchived) { + public static MultiMap getTemplatesMap(WizardContext context) { ProjectTemplatesFactory[] factories = ProjectTemplatesFactory.EP_NAME.getExtensions(); final MultiMap groups = new MultiMap(); for (ProjectTemplatesFactory factory : factories) { - if (!includeArchived && (factory instanceof ArchivedTemplatesFactory)) continue; for (String group : factory.getGroups()) { ProjectTemplate[] templates = factory.createTemplates(group, context); List values = Arrays.asList(templates); @@ -79,7 +77,7 @@ public class CreateFromTemplateMode extends WizardMode { @Nullable @Override protected StepSequence createSteps(@NotNull WizardContext context, @NotNull ModulesProvider modulesProvider) { - MultiMap map = getTemplatesMap(context, true); + MultiMap map = getTemplatesMap(context); StepSequence sequence = new StepSequence(); for (ProjectTemplate template : map.values()) { sequence.addStepsForBuilder(template.createModuleBuilder(), context, modulesProvider); diff --git a/java/idea-ui/src/com/intellij/platform/templates/ArchivedTemplatesFactory.java b/java/idea-ui/src/com/intellij/platform/templates/ArchivedTemplatesFactory.java index b2ea5025efd2..c51dbd6fbb8d 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/ArchivedTemplatesFactory.java +++ b/java/idea-ui/src/com/intellij/platform/templates/ArchivedTemplatesFactory.java @@ -16,8 +16,6 @@ package com.intellij.platform.templates; import com.intellij.ide.fileTemplates.impl.UrlUtil; -import com.intellij.ide.plugins.IdeaPluginDescriptor; -import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; @@ -48,22 +46,21 @@ public class ArchivedTemplatesFactory extends ProjectTemplatesFactory { @Override protected MultiMap> compute() { MultiMap> map = new MultiMap>(); - IdeaPluginDescriptor[] plugins = PluginManagerCore.getPlugins(); Map urls = new HashMap(); - for (IdeaPluginDescriptor plugin : plugins) { - if (!plugin.isEnabled()) continue; - try { - ClassLoader loader = plugin.getPluginClassLoader(); - Enumeration resources = loader.getResources("resources/projectTemplates"); - ArrayList list = Collections.list(resources); - for (URL url : list) { - urls.put(url, loader); - } - } - catch (IOException e) { - LOG.error(e); - } - } + //for (IdeaPluginDescriptor plugin : plugins) { + // if (!plugin.isEnabled()) continue; + // try { + // ClassLoader loader = plugin.getPluginClassLoader(); + // Enumeration resources = loader.getResources("resources/projectTemplates"); + // ArrayList list = Collections.list(resources); + // for (URL url : list) { + // urls.put(url, loader); + // } + // } + // catch (IOException e) { + // LOG.error(e); + // } + //} URL configURL = getCustomTemplatesURL(); if (configURL != null) { diff --git a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java index fda11fd67b11..394d42ab7989 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -544,27 +544,35 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM final XmlTag rootTag = document.getRootTag(); final String externalName = getExternalName(listOwner, false); if (rootTag != null) { + XmlTag anchor = null; for (XmlTag item : rootTag.getSubTags()) { - if (Comparing.strEqual(StringUtil.unescapeXml(item.getAttributeValue("name")), externalName)) { + int compare = Comparing.compare(externalName, StringUtil.unescapeXml(item.getAttributeValue("name"))); + if (compare == 0) { + anchor = null; for (XmlTag annotation : item.getSubTags()) { - if (Comparing.strEqual(annotation.getAttributeValue("name"), annotationFQName)) { + compare = Comparing.compare(annotationFQName, annotation.getAttributeValue("name")); + if (compare == 0) { annotation.delete(); break; } + if (compare < 0) break; + anchor = annotation; } XmlTag newTag = XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText( createAnnotationTag(annotationFQName, values)); - item.add(newTag); + item.addAfter(newTag, anchor); commitChanges(xmlFile); notifyAfterAnnotationChanging(listOwner, annotationFQName, true); return; } + if (compare < 0) break; + anchor = item; } @NonNls String text = "\n"; text += createAnnotationTag(annotationFQName, values); text += ""; - rootTag.add(XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText(text)); + rootTag.addAfter(XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText(text), anchor); } } commitChanges(xmlFile); @@ -604,7 +612,8 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM } } - Collections.sort(itemTags, new Comparator() { + List sorted = new ArrayList(itemTags); + Collections.sort(sorted, new Comparator() { @Override public int compare(XmlTag item1, XmlTag item2) { String externalName1 = item1.getAttributeValue("name"); @@ -613,9 +622,11 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM return externalName1.compareTo(externalName2); } }); - for (XmlTag item : itemTags) { - rootTag.addAfter(item, null); - item.delete(); + if (!sorted.equals(itemTags)) { + for (XmlTag item : sorted) { + rootTag.addAfter(item, null); + item.delete(); + } } } diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java b/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java index 496703dd354f..a7d98ade4c45 100644 --- a/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java +++ b/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java @@ -131,7 +131,8 @@ public class MethodGroupingRule implements UsageGroupingRule { @Override public FileStatus getFileStatus() { - return isValid() ? NavigationItemFileStatus.get(getMethod()) : null; + PsiFile file = myMethodPointer.getContainingFile(); + return file == null ? null : NavigationItemFileStatus.get(file); } @Override diff --git a/java/java-tests/testData/codeInsight/externalAnnotations/content/anno/p/annotations.xml b/java/java-tests/testData/codeInsight/externalAnnotations/content/anno/p/annotations.xml index 4d905a4befdb..5daf0fa19a40 100644 --- a/java/java-tests/testData/codeInsight/externalAnnotations/content/anno/p/annotations.xml +++ b/java/java-tests/testData/codeInsight/externalAnnotations/content/anno/p/annotations.xml @@ -1,8 +1,8 @@ - - - - - - + + + + + + \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/externalAnnotations/content/anno/suppressed/annotations.xml b/java/java-tests/testData/codeInsight/externalAnnotations/content/anno/suppressed/annotations.xml index 01443638aa18..d25dd2fd44d9 100644 --- a/java/java-tests/testData/codeInsight/externalAnnotations/content/anno/suppressed/annotations.xml +++ b/java/java-tests/testData/codeInsight/externalAnnotations/content/anno/suppressed/annotations.xml @@ -1,10 +1,10 @@ - - - - - - - - + + + + + + + + \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/externalAnnotations/content/annoMultiRoot/root1/multiRoot/annotations.xml b/java/java-tests/testData/codeInsight/externalAnnotations/content/annoMultiRoot/root1/multiRoot/annotations.xml index 36aa8d8050c6..baa0a3a9ba3c 100644 --- a/java/java-tests/testData/codeInsight/externalAnnotations/content/annoMultiRoot/root1/multiRoot/annotations.xml +++ b/java/java-tests/testData/codeInsight/externalAnnotations/content/annoMultiRoot/root1/multiRoot/annotations.xml @@ -1,7 +1,7 @@ - - - - - + + + + + \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/externalAnnotations/content/annoMultiRoot/root2/multiRoot/annotations.xml b/java/java-tests/testData/codeInsight/externalAnnotations/content/annoMultiRoot/root2/multiRoot/annotations.xml index e497a6ea84d4..606162592b30 100644 --- a/java/java-tests/testData/codeInsight/externalAnnotations/content/annoMultiRoot/root2/multiRoot/annotations.xml +++ b/java/java-tests/testData/codeInsight/externalAnnotations/content/annoMultiRoot/root2/multiRoot/annotations.xml @@ -1,7 +1,7 @@ - - - - - + + + + + \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/NewPostfixTemplateTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/NewPostfixTemplateTest.java index e5d94573bb1b..4f5d484c9223 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/NewPostfixTemplateTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/NewPostfixTemplateTest.java @@ -22,13 +22,13 @@ public class NewPostfixTemplateTest extends PostfixTemplateTestCase { @Override protected String getSuffix() { return "new"; } - public void testNew01() { doTest(); } - public void testNew02() { doTest(); } - public void testNew03() { doTest(); } - public void testNew04() { doTest(); } - public void testNew05() { doTest(); } - public void testNew06() { doTest(); } - public void testNew07() { doTest(); } - public void testNew08() { doTest(); } - public void testNewOnAssignExpression() { doTest(); } + public void _testNew01() { doTest(); } + public void _testNew02() { doTest(); } + public void _testNew03() { doTest(); } + public void _testNew04() { doTest(); } + public void _testNew05() { doTest(); } + public void _testNew06() { doTest(); } + public void _testNew07() { doTest(); } + public void _testNew08() { doTest(); } + public void _testNewOnAssignExpression() { doTest(); } } diff --git a/java/jdkAnnotations/javax/swing/tree/annotations.xml b/java/jdkAnnotations/javax/swing/tree/annotations.xml index 055cc92a5500..2728e61b3071 100644 --- a/java/jdkAnnotations/javax/swing/tree/annotations.xml +++ b/java/jdkAnnotations/javax/swing/tree/annotations.xml @@ -12,6 +12,9 @@ + + + diff --git a/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java b/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java index e386eb0df3ec..62f57f8f108d 100644 --- a/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java +++ b/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java @@ -109,7 +109,7 @@ public abstract class ProjectWizardTestCase ext } protected Project createProject(Consumer adjuster) throws IOException { - createWizard(getProject()); + createWizard(null); runWizard(adjuster); myCreatedProject = NewProjectUtil.createFromWizard(myWizard, null); return myCreatedProject; diff --git a/native/libnotifywrapper/LibNotifyWrapper.c b/native/libnotifywrapper/LibNotifyWrapper.c index 3d1481a0fabb..e612f8b387b3 100644 --- a/native/libnotifywrapper/LibNotifyWrapper.c +++ b/native/libnotifywrapper/LibNotifyWrapper.c @@ -1,11 +1,5 @@ #include "com_intellij_ui_LibNotifyWrapper.h" - -// to build 32bit version use -// gcc -I/usr/include/gdk-pixbuf-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include/ -I/usr/include/glib-2.0/ -I/jdk/jdk1.6.0_45/include -I/jdk/jdk1.6.0_45/include/linux -fPIC -shared -o libnotifywrapper.so LibNotifyWrapper.c -L/usr/lib/i386-linux-gnu/ -m32 -// do not forget something like "sudo apt-get install libnotify-dev:i386" - -// to build 64 bit version use -// gcc `pkg-config --cflags --libs libnotify` -I/jdk/jdk1.6.0_45/include -I/jdk/jdk1.6.0_45/include/linux -fPIC -shared -o libnotifywrapper64.so LibNotifyWrapper.c -lnotify +#include /* * Class: com_intellij_ui_LibNotifyWrapper @@ -13,14 +7,46 @@ * Signature: (Ljava/lang/String;Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_com_intellij_ui_LibNotifyWrapper_showNotification - (JNIEnv * jEnv, jclass c, jstring jTitle, jstring jDescription) { + (JNIEnv * jEnv, jclass c, jstring jTitle, jstring jDescription, jstring jLogoPath) { + + void *handle; + gboolean (*notify_init_func)(const char *app_name); + void (*notify_uninit_func)(); + NotifyNotification* (*notify_notification_new_func) (const char *summary, + const char *body, + const char *icon); + gboolean (*notify_notification_show_func) (NotifyNotification *notification, + GError **error); + char *error; + + dlerror(); + + handle = dlopen("libnotify.so", RTLD_LAZY); + + if ((error = dlerror()) != NULL) + { + (*jEnv)->ThrowNew(jEnv, (*jEnv)->FindClass(jEnv, "java/lang/UnsatisfiedLinkError"), error); + return; + } + + dlerror(); + + *(void **) (¬ify_init_func) = dlsym(handle, "notify_init"); + *(void **) (¬ify_uninit_func) = dlsym(handle, "notify_init"); + *(void **) (¬ify_notification_new_func) = dlsym(handle, "notify_notification_new"); + *(void **) (¬ify_notification_show_func) = dlsym(handle, "notify_notification_show"); + + (*notify_init_func) ("JetBrains"); + const char *title = (*jEnv)->GetStringUTFChars(jEnv, jTitle, 0); const char *description = (*jEnv)->GetStringUTFChars(jEnv, jDescription, 0); - NotifyNotification * notification = notify_notification_new (title, description, "idea.png"); - notify_init ("JetBrains"); - notify_notification_show (notification, NULL); - notify_uninit(); + const char *logoPath = (*jEnv)->GetStringUTFChars(jEnv, jLogoPath, 0); + NotifyNotification * notification = (*notify_notification_new_func) (title, description, logoPath); + (*notify_notification_show_func) (notification, NULL); + (*notify_uninit_func)(); (*jEnv)->ReleaseStringUTFChars(jEnv, jTitle, title); (*jEnv)->ReleaseStringUTFChars(jEnv, jDescription, description); -} + (*jEnv)->ReleaseStringUTFChars(jEnv, jLogoPath, logoPath); + dlclose(handle); +} diff --git a/native/libnotifywrapper/com_intellij_ui_LibNotifyWrapper.h b/native/libnotifywrapper/com_intellij_ui_LibNotifyWrapper.h index 3e2c893bfe66..cb55eca09ccb 100644 --- a/native/libnotifywrapper/com_intellij_ui_LibNotifyWrapper.h +++ b/native/libnotifywrapper/com_intellij_ui_LibNotifyWrapper.h @@ -11,10 +11,10 @@ extern "C" { /* * Class: com_intellij_ui_LibNotifyWrapper * Method: showNotification - * Signature: (Ljava/lang/String;Ljava/lang/String;)V + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_com_intellij_ui_LibNotifyWrapper_showNotification - (JNIEnv *, jclass, jstring, jstring); + (JNIEnv *, jclass, jstring, jstring, jstring); #ifdef __cplusplus } diff --git a/platform/core-api/src/com/intellij/ide/presentation/VirtualFilePresentation.java b/platform/core-api/src/com/intellij/ide/presentation/VirtualFilePresentation.java index 50fe04372a9a..d2d5ebfc31f4 100644 --- a/platform/core-api/src/com/intellij/ide/presentation/VirtualFilePresentation.java +++ b/platform/core-api/src/com/intellij/ide/presentation/VirtualFilePresentation.java @@ -1,8 +1,24 @@ +/* + * Copyright 2000-2013 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.ide.presentation; import com.intellij.ide.TypePresentationService; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.PlatformIcons; +import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -10,7 +26,7 @@ import javax.swing.*; * @author yole */ public class VirtualFilePresentation { - public static Icon getIcon(VirtualFile vFile) { + public static Icon getIcon(@NotNull VirtualFile vFile) { Icon icon = TypePresentationService.getService().getIcon(vFile); if (icon != null) { return icon; diff --git a/platform/core-api/src/com/intellij/lang/folding/CompositeFoldingBuilder.java b/platform/core-api/src/com/intellij/lang/folding/CompositeFoldingBuilder.java index f94201362037..067badf894bb 100644 --- a/platform/core-api/src/com/intellij/lang/folding/CompositeFoldingBuilder.java +++ b/platform/core-api/src/com/intellij/lang/folding/CompositeFoldingBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -80,4 +80,9 @@ public class CompositeFoldingBuilder extends FoldingBuilderEx implements DumbAwa final FoldingBuilder builder = node.getUserData(FOLDING_BUILDER); return builder != null && builder.isCollapsedByDefault(node); } + + @Override + public String toString() { + return getClass().getSimpleName() + myBuilders; + } } diff --git a/platform/core-api/src/com/intellij/psi/LanguageSubstitutor.java b/platform/core-api/src/com/intellij/psi/LanguageSubstitutor.java index f0a2e9528648..4be3352d0ca7 100644 --- a/platform/core-api/src/com/intellij/psi/LanguageSubstitutor.java +++ b/platform/core-api/src/com/intellij/psi/LanguageSubstitutor.java @@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable; /** * @author peter + * @see com.intellij.psi.LanguageSubstitutors */ public abstract class LanguageSubstitutor { diff --git a/platform/core-api/src/com/intellij/util/IconUtil.java b/platform/core-api/src/com/intellij/util/IconUtil.java index 310971709f47..2b314ca38c76 100644 --- a/platform/core-api/src/com/intellij/util/IconUtil.java +++ b/platform/core-api/src/com/intellij/util/IconUtil.java @@ -121,44 +121,46 @@ public class IconUtil { return new ImageIcon(second); } + private static final NullableFunction ICON_NULLABLE_FUNCTION = new NullableFunction() { + @Override + public Icon fun(final FileIconKey key) { + final VirtualFile file = key.getFile(); + final int flags = key.getFlags(); + final Project project = key.getProject(); + + if (!file.isValid() || project != null && (project.isDisposed() || !wasEverInitialized(project))) return null; + + final Icon providersIcon = getProvidersIcon(file, flags, project); + Icon icon = providersIcon == null ? VirtualFilePresentation.getIcon(file) : providersIcon; + + final boolean dumb = project != null && DumbService.getInstance(project).isDumb(); + for (FileIconPatcher patcher : getPatchers()) { + if (dumb && !DumbService.isDumbAware(patcher)) { + continue; + } + + icon = patcher.patchIcon(icon, file, flags, project); + } + + if ((flags & Iconable.ICON_FLAG_READ_STATUS) != 0 && + (!file.isWritable() || !WritingAccessProvider.isPotentiallyWritable(file, project))) { + icon = new LayeredIcon(icon, PlatformIcons.LOCKED_ICON); + } + if (file.is(VFileProperty.SYMLINK)) { + icon = new LayeredIcon(icon, PlatformIcons.SYMLINK_ICON); + } + + Iconable.LastComputedIcon.put(file, icon, flags); + + return icon; + } + }; + public static Icon getIcon(@NotNull final VirtualFile file, @Iconable.IconFlags final int flags, @Nullable final Project project) { Icon lastIcon = Iconable.LastComputedIcon.get(file, flags); final Icon base = lastIcon != null ? lastIcon : VirtualFilePresentation.getIcon(file); - return IconDeferrer.getInstance().defer(base, new FileIconKey(file, project, flags), new NullableFunction() { - @Override - public Icon fun(final FileIconKey key) { - final VirtualFile file = key.getFile(); - final int flags = key.getFlags(); - final Project project = key.getProject(); - - if (!file.isValid() || project != null && (project.isDisposed() || !wasEverInitialized(project))) return null; - - final Icon providersIcon = getProvidersIcon(file, flags, project); - Icon icon = providersIcon == null ? VirtualFilePresentation.getIcon(file) : providersIcon; - - final boolean dumb = project != null && DumbService.getInstance(project).isDumb(); - for (FileIconPatcher patcher : getPatchers()) { - if (dumb && !DumbService.isDumbAware(patcher)) { - continue; - } - - icon = patcher.patchIcon(icon, file, flags, project); - } - - if ((flags & Iconable.ICON_FLAG_READ_STATUS) != 0 && - (!file.isWritable() || !WritingAccessProvider.isPotentiallyWritable(file, project))) { - icon = new LayeredIcon(icon, PlatformIcons.LOCKED_ICON); - } - if (file.is(VFileProperty.SYMLINK)) { - icon = new LayeredIcon(icon, PlatformIcons.SYMLINK_ICON); - } - - Iconable.LastComputedIcon.put(file, icon, flags); - - return icon; - } - }); + return IconDeferrer.getInstance().defer(base, new FileIconKey(file, project, flags), ICON_NULLABLE_FUNCTION); } @Nullable diff --git a/platform/core-impl/src/com/intellij/indentation/AbstractIndentParser.java b/platform/core-impl/src/com/intellij/indentation/AbstractIndentParser.java index f159acd70915..49058830fc69 100644 --- a/platform/core-impl/src/com/intellij/indentation/AbstractIndentParser.java +++ b/platform/core-impl/src/com/intellij/indentation/AbstractIndentParser.java @@ -218,11 +218,19 @@ public abstract class AbstractIndentParser implements PsiParser { errorMarker.error(message); } - protected void errorUntilEol(String message) { + protected void errorUntilEol(@NotNull String message) { PsiBuilder.Marker errorMarker = mark(); advanceUntilEol(); errorMarker.error(message); } + + protected void errorUntilEof(@NotNull String message) { + PsiBuilder.Marker errorMarker = mark(); + while (!eof()) { + advance(); + } + errorMarker.error(message); + } protected void expectEolOrEof() { if (!isNewLine() && !eof()) { diff --git a/platform/lang-api/src/com/intellij/navigation/NavigationItemFileStatus.java b/platform/lang-api/src/com/intellij/navigation/NavigationItemFileStatus.java index 0661f61af7dd..c9f33fbd9d25 100644 --- a/platform/lang-api/src/com/intellij/navigation/NavigationItemFileStatus.java +++ b/platform/lang-api/src/com/intellij/navigation/NavigationItemFileStatus.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -21,6 +21,7 @@ import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; /** * @author yole @@ -43,11 +44,11 @@ public class NavigationItemFileStatus { return FileStatus.NOT_CHANGED; } - private static FileStatus getPsiElementFileStatus(PsiElement psiElement) { + private static FileStatus getPsiElementFileStatus(@NotNull PsiElement psiElement) { if (!psiElement.isPhysical()) return FileStatus.NOT_CHANGED; PsiFile contFile = psiElement.getContainingFile(); if (contFile == null) return FileStatus.NOT_CHANGED; VirtualFile vFile = contFile.getVirtualFile(); - return vFile != null ? FileStatusManager.getInstance(psiElement.getProject()).getStatus(vFile) : FileStatus.NOT_CHANGED; + return vFile == null ? FileStatus.NOT_CHANGED : FileStatusManager.getInstance(psiElement.getProject()).getStatus(vFile); } } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java index aefccbd1f9a8..67b99f1cc29c 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java @@ -217,6 +217,7 @@ public class ManageCodeStyleSchemesDialog extends DialogWrapper { VirtualFile[] selection = fileChooser.choose(CodeStyleSchemesUIConfiguration.Util.getRecentImportFile(), null); if (selection.length == 1) { VirtualFile selectedFile = selection[0]; + selectedFile.refresh(false, false); CodeStyleSchemesUIConfiguration.Util.setRecentImportFile(selectedFile); try { InputStream nameInputStream = selectedFile.getInputStream(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java index 67ba1afaca67..f1e84e92f29f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -16,6 +16,7 @@ package com.intellij.codeInsight.folding.impl; +import com.intellij.diagnostic.AttachmentFactory; import com.intellij.injected.editor.DocumentWindow; import com.intellij.injected.editor.EditorWindow; import com.intellij.lang.Language; @@ -23,6 +24,7 @@ import com.intellij.lang.folding.FoldingBuilder; import com.intellij.lang.folding.FoldingDescriptor; import com.intellij.lang.folding.LanguageFolding; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Attachment; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; @@ -34,6 +36,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.impl.DebugUtil; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; @@ -206,7 +209,9 @@ public class FoldingUpdate { " made by " + foldingBuilder + " for " +language + " and called on file " + psi + - " is outside document range: " + docRange); + " is outside document range: " + docRange, + AttachmentFactory.createAttachment(document), + new Attachment("psiTree.txt", DebugUtil.psiToString(psi, false, true))); } elementsToFoldMap.putValue(descriptor.getElement().getPsi(), descriptor); } diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java index d1584979a01c..87877463b9a9 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java +++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java @@ -547,9 +547,17 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search int startOffset = cur.getStartOffset(); int endOffset = cur.getEndOffset(); - Point startPoint = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(startOffset)); - Point endPoint = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(endOffset)); - Point point = new Point((startPoint.x + endPoint.x)/2, startPoint.y); + if (startOffset >= myEditor.getDocument().getTextLength()) { + if (!object.isDisposed()) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + object.hide(); + } + }); + } + return null; + } if (!SearchResults.insideVisibleArea(myEditor, cur)) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override @@ -575,6 +583,11 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search myVisibleAreaListenersToRemove.add(visibleAreaListener); } + + Point startPoint = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(startOffset)); + Point endPoint = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(endOffset)); + Point point = new Point((startPoint.x + endPoint.x)/2, startPoint.y); + return new RelativePoint(myEditor.getContentComponent(), point); } } diff --git a/platform/lang-impl/src/com/intellij/ide/GeneratedFileEditingNotificationProvider.java b/platform/lang-impl/src/com/intellij/ide/GeneratedFileEditingNotificationProvider.java new file mode 100644 index 000000000000..5a6606be1c77 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/GeneratedFileEditingNotificationProvider.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2013 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.ide; + +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.EditorNotificationPanel; +import com.intellij.ui.EditorNotifications; +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public class GeneratedFileEditingNotificationProvider extends EditorNotifications.Provider { + private static final Key KEY = Key.create("generated.source.file.editing.notification.panel"); + private final GeneratedSourceFileChangeTracker myChangeTracker; + + public GeneratedFileEditingNotificationProvider(GeneratedSourceFileChangeTracker changeTracker) { + myChangeTracker = changeTracker; + } + + @Override + public Key getKey() { + return KEY; + } + + @Nullable + @Override + public EditorNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) { + if (!myChangeTracker.isEditedGeneratedFile(file)) return null; + + EditorNotificationPanel panel = new EditorNotificationPanel(); + panel.setText("Generated source files should not be edited. The changes will be lost when sources are regenerated."); + return panel; + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/GeneratedSourceFileChangeTracker.java b/platform/lang-impl/src/com/intellij/ide/GeneratedSourceFileChangeTracker.java new file mode 100644 index 000000000000..8a655b8c4a06 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/GeneratedSourceFileChangeTracker.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2013 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.ide; + +import com.intellij.openapi.components.AbstractProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public abstract class GeneratedSourceFileChangeTracker extends AbstractProjectComponent { + @NotNull + public static GeneratedSourceFileChangeTracker getInstance(@NotNull Project project) { + return project.getComponent(GeneratedSourceFileChangeTracker.class); + } + + protected GeneratedSourceFileChangeTracker(Project project) { + super(project); + } + + public abstract boolean isEditedGeneratedFile(@NotNull VirtualFile file); +} diff --git a/platform/lang-impl/src/com/intellij/ide/GeneratedSourceFileChangeTrackerImpl.java b/platform/lang-impl/src/com/intellij/ide/GeneratedSourceFileChangeTrackerImpl.java new file mode 100644 index 000000000000..e1fbe73de8d6 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/GeneratedSourceFileChangeTrackerImpl.java @@ -0,0 +1,143 @@ +/* + * Copyright 2000-2013 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.ide; + +import com.intellij.AppTopics; +import com.intellij.openapi.application.ReadAction; +import com.intellij.openapi.application.Result; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.fileEditor.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.GeneratedSourcesFilter; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.EditorNotifications; +import com.intellij.util.Alarm; +import com.intellij.util.messages.MessageBusConnection; +import com.intellij.util.ui.update.MergingUpdateQueue; +import com.intellij.util.ui.update.Update; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * @author nik + */ +public class GeneratedSourceFileChangeTrackerImpl extends GeneratedSourceFileChangeTracker { + private final FileDocumentManager myDocumentManager; + private final EditorNotifications myEditorNotifications; + private final MergingUpdateQueue myCheckingQueue; + private final Set myFilesToCheck = Collections.synchronizedSet(new HashSet()); + private final Set myEditedGeneratedFiles = Collections.synchronizedSet(new HashSet()); + + public GeneratedSourceFileChangeTrackerImpl(Project project, FileDocumentManager documentManager, EditorNotifications editorNotifications) { + super(project); + myDocumentManager = documentManager; + myEditorNotifications = editorNotifications; + myCheckingQueue = new MergingUpdateQueue("Checking for changes in generated sources", 500, false, null, project, null, Alarm.ThreadToUse.SHARED_THREAD); + } + + @Override + public boolean isEditedGeneratedFile(@NotNull VirtualFile file) { + return myEditedGeneratedFiles.contains(file); + } + + @Override + public void projectOpened() { + final Update check = new Update("check for changes in generated files") { + @Override + public void run() { + checkFiles(); + } + }; + EditorFactory.getInstance().getEventMulticaster().addDocumentListener(new DocumentAdapter() { + @Override + public void documentChanged(DocumentEvent e) { + VirtualFile file = myDocumentManager.getFile(e.getDocument()); + if (file != null) { + myFilesToCheck.add(file); + myCheckingQueue.queue(check); + } + } + }, myProject); + MessageBusConnection connection = myProject.getMessageBus().connect(); + connection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, new FileDocumentManagerAdapter() { + @Override + public void fileContentReloaded(VirtualFile file, @NotNull Document document) { + myFilesToCheck.remove(file); + if (myEditedGeneratedFiles.remove(file)) { + myEditorNotifications.updateNotifications(file); + } + } + }); + connection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerAdapter() { + @Override + public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) { + myEditedGeneratedFiles.remove(file); + } + }); + myCheckingQueue.activate(); + } + + @Override + public void projectClosed() { + myCheckingQueue.deactivate(); + } + + private void checkFiles() { + final VirtualFile[] files; + synchronized (myFilesToCheck) { + files = myFilesToCheck.toArray(new VirtualFile[myFilesToCheck.size()]); + myFilesToCheck.clear(); + } + final List newEditedGeneratedFiles = new ArrayList(); + new ReadAction() { + protected void run(final @NotNull Result result) { + if (myProject.isDisposed()) return; + for (VirtualFile file : files) { + if (isGenerated(file)) { + newEditedGeneratedFiles.add(file); + } + } + } + }.execute(); + + if (!newEditedGeneratedFiles.isEmpty()) { + List toNotify = new ArrayList(); + synchronized (myEditedGeneratedFiles) { + for (VirtualFile file : newEditedGeneratedFiles) { + if (myEditedGeneratedFiles.add(file)) { + toNotify.add(file); + } + } + } + for (VirtualFile file : toNotify) { + myEditorNotifications.updateNotifications(file); + } + } + } + + private boolean isGenerated(VirtualFile file) { + for (GeneratedSourcesFilter filter : GeneratedSourcesFilter.EP_NAME.getExtensions()) { + if (filter.isGeneratedSource(file, myProject)) { + return true; + } + } + return false; + } +} diff --git a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java index 8b7da068f968..764c2a1f834f 100644 --- a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java +++ b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java @@ -511,7 +511,7 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx { @Override public boolean isDisposed() { - return !myDisposed && myDelegate.isDisposed(); + return myDisposed || myDelegate.isDisposed(); } @Override diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java index ccdb32d31537..bed88dd77c19 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -22,6 +22,7 @@ import com.intellij.concurrency.Job; import com.intellij.concurrency.JobLauncher; import com.intellij.injected.editor.DocumentWindow; import com.intellij.injected.editor.DocumentWindowImpl; +import com.intellij.injected.editor.EditorWindow; import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.lang.Language; import com.intellij.lang.injection.InjectedLanguageManager; @@ -41,7 +42,6 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.ProperTextRange; import com.intellij.openapi.util.Segment; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; @@ -67,7 +67,7 @@ import java.util.concurrent.atomic.AtomicReference; /** * @author cdr */ -public class InjectedLanguageManagerImpl extends InjectedLanguageManager implements Disposable{ +public class InjectedLanguageManagerImpl extends InjectedLanguageManager implements Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl"); private final Project myProject; private final DumbService myDumbService; @@ -118,6 +118,7 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager impleme @Override public void dispose() { + EditorWindow.disposeInvalidEditors(); } @Override @@ -236,7 +237,7 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager impleme @Override @NotNull public TextRange injectedToHost(@NotNull PsiElement injectedContext, @NotNull TextRange injectedTextRange) { - ProperTextRange.assertProperRange(injectedTextRange); + TextRange.assertProperRange(injectedTextRange); PsiFile file = injectedContext.getContainingFile(); if (file == null) return injectedTextRange; Document document = PsiDocumentManager.getInstance(file.getProject()).getCachedDocument(file); @@ -488,7 +489,7 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager impleme InjectedLanguagePlaces placesRegistrar = new InjectedLanguagePlaces() { @Override public void addPlace(@NotNull Language language, @NotNull TextRange rangeInsideHost, @NonNls @Nullable String prefix, @NonNls @Nullable String suffix) { - ProperTextRange.assertProperRange(rangeInsideHost); + TextRange.assertProperRange(rangeInsideHost); injectionPlacesRegistrar .startInjecting(language) .addPlace(prefix, suffix, host, rangeInsideHost) diff --git a/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java b/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java index 403a17f9a2d4..7e5b6541f737 100644 --- a/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -22,6 +22,7 @@ package com.intellij.ui; import com.intellij.concurrency.Job; import com.intellij.concurrency.JobLauncher; import com.intellij.ide.PowerSaveMode; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.IndexNotReadyException; @@ -45,6 +46,7 @@ import java.util.Set; public class DeferredIconImpl implements DeferredIcon { private static final RepaintScheduler ourRepaintScheduler = new RepaintScheduler(); + @NotNull private volatile Icon myDelegateIcon; private Function myEvaluator; private volatile boolean myIsScheduled = false; @@ -53,7 +55,7 @@ public class DeferredIconImpl implements DeferredIcon { private final boolean myNeedReadAction; private boolean myDone; - private IconListener myEvalListener; + private final IconListener myEvalListener; private static final TransferToEDTQueue ourLaterInvocator = new TransferToEDTQueue("Deferred icon later invocator", new Processor() { @Override public boolean process(Runnable runnable) { @@ -62,17 +64,22 @@ public class DeferredIconImpl implements DeferredIcon { } }, Condition.FALSE, 200); - public DeferredIconImpl(Icon baseIcon, T param, @NotNull Function evaluator) { - this(baseIcon, param, true, evaluator); + DeferredIconImpl(Icon baseIcon, T param, @NotNull Function evaluator, @NotNull IconListener listener) { + this(baseIcon, param, true, evaluator, listener); } public DeferredIconImpl(Icon baseIcon, T param, final boolean needReadAction, @NotNull Function evaluator) { + this(baseIcon, param, needReadAction, evaluator, null); + } + private DeferredIconImpl(Icon baseIcon, T param, final boolean needReadAction, @NotNull Function evaluator, IconListener listener) { myParam = param; myDelegateIcon = nonNull(baseIcon); myEvaluator = evaluator; myNeedReadAction = needReadAction; + myEvalListener = listener; } + @NotNull private static Icon nonNull(final Icon icon) { return icon == null ? EMPTY_ICON : icon; } @@ -271,18 +278,20 @@ public class DeferredIconImpl implements DeferredIcon { private final Alarm myAlarm = new Alarm(); private final Set myQueue = new LinkedHashSet(); - public void pushDirtyComponent(final Component c, final Rectangle rec) { + public void pushDirtyComponent(@NotNull Component c, final Rectangle rec) { + ApplicationManager.getApplication().assertIsDispatchThread(); // assert myQueue accessed from EDT only myAlarm.cancelAllRequests(); myAlarm.addRequest(new Runnable() { @Override public void run() { for (RepaintRequest each : myQueue) { Rectangle r = each.getRectangle(); - if (r != null) { - each.getComponent().repaint(r.x, r.y, r.width, r.height); - } else { + if (r == null) { each.getComponent().repaint(); } + else { + each.getComponent().repaint(r.x, r.y, r.width, r.height); + } } myQueue.clear(); } @@ -296,11 +305,12 @@ public class DeferredIconImpl implements DeferredIcon { private final Component myComponent; private final Rectangle myRectangle; - private RepaintRequest(Component component, Rectangle rectangle) { + private RepaintRequest(@NotNull Component component, Rectangle rectangle) { myComponent = component; myRectangle = rectangle; } + @NotNull public Component getComponent() { return myComponent; } @@ -310,11 +320,6 @@ public class DeferredIconImpl implements DeferredIcon { } } - public DeferredIconImpl setDoneListener(@NotNull IconListener disposer) { - myEvalListener = disposer; - return this; - } - public interface IconListener { void evalDone(T key, @NotNull Icon result); } diff --git a/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java b/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java index 96f97c0ac710..f0ca2cc4e68a 100644 --- a/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -41,7 +41,8 @@ public class IconDeferrerImpl extends IconDeferrer { } }; private long myLastClearTimestamp = 0; - @SuppressWarnings("UnusedDeclaration") private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() { + @SuppressWarnings("UnusedDeclaration") + private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() { @Override public void run() { clear(); @@ -81,7 +82,7 @@ public class IconDeferrerImpl extends IconDeferrer { Icon result = myIconsCache.get(param); if (result == null) { final long started = myLastClearTimestamp; - result = new DeferredIconImpl(base, param, f).setDoneListener(new DeferredIconImpl.IconListener() { + result = new DeferredIconImpl(base, param, f, new DeferredIconImpl.IconListener() { @Override public void evalDone(T key, @NotNull Icon r) { synchronized (LOCK) { @@ -106,7 +107,7 @@ public class IconDeferrerImpl extends IconDeferrer { } }; - public static void evaluateDeferred(@NotNull Runnable runnable) { + static void evaluateDeferred(@NotNull Runnable runnable) { try { myEvaluationIsInProgress.set(Boolean.TRUE); runnable.run(); diff --git a/platform/lang-impl/testSources/com/intellij/ide/GeneratedSourceFileChangeTrackerTest.java b/platform/lang-impl/testSources/com/intellij/ide/GeneratedSourceFileChangeTrackerTest.java new file mode 100644 index 000000000000..ebed23302c26 --- /dev/null +++ b/platform/lang-impl/testSources/com/intellij/ide/GeneratedSourceFileChangeTrackerTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2000-2013 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.ide; + +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.GeneratedSourcesFilter; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +/** + * @author nik + */ +public class GeneratedSourceFileChangeTrackerTest extends CodeInsightFixtureTestCase { + private final GeneratedSourcesFilter myGeneratedSourcesFilter = new GeneratedSourcesFilter() { + @Override + public boolean isGeneratedSource(@NotNull VirtualFile file, @NotNull Project project) { + return file.getName().startsWith("Gen"); + } + }; + + @Override + protected void setUp() throws Exception { + super.setUp(); + Extensions.getRootArea().getExtensionPoint(GeneratedSourcesFilter.EP_NAME).registerExtension(myGeneratedSourcesFilter); + getTracker().projectOpened(); + } + + @Override + protected void tearDown() throws Exception { + Extensions.getRootArea().getExtensionPoint(GeneratedSourcesFilter.EP_NAME).unregisterExtension(myGeneratedSourcesFilter); + getTracker().projectClosed(); + super.tearDown(); + } + + public void testChangeOrdinary() { + PsiFile file = myFixture.configureByText("Ordinary.txt", ""); + myFixture.type('a'); + assertFalse(isEditedGeneratedFile(file)); + } + + public void testChangeGenerated() { + PsiFile file = myFixture.configureByText("Gen.txt", ""); + myFixture.type('a'); + assertTrue(isEditedGeneratedFile(file)); + } + + public void testChangeGeneratedExternally() throws IOException { + PsiFile file = myFixture.configureByText("Gen.txt", ""); + VfsUtil.saveText(file.getVirtualFile(), "abc"); + assertFalse(isEditedGeneratedFile(file)); + } + + private boolean isEditedGeneratedFile(PsiFile file) { + return getTracker().isEditedGeneratedFile(file.getVirtualFile()); + } + + private GeneratedSourceFileChangeTracker getTracker() { + return GeneratedSourceFileChangeTracker.getInstance(getProject()); + } +} diff --git a/platform/platform-api/src/com/intellij/openapi/vcs/FileStatusManager.java b/platform/platform-api/src/com/intellij/openapi/vcs/FileStatusManager.java index ebf5910b84ae..f2fad70bb48e 100644 --- a/platform/platform-api/src/com/intellij/openapi/vcs/FileStatusManager.java +++ b/platform/platform-api/src/com/intellij/openapi/vcs/FileStatusManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -18,6 +18,7 @@ package com.intellij.openapi.vcs; import com.intellij.openapi.Disposable; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; import java.awt.*; @@ -29,7 +30,7 @@ public abstract class FileStatusManager { return project.getComponent(FileStatusManager.class); } - public abstract FileStatus getStatus(VirtualFile virtualFile); + public abstract FileStatus getStatus(@NotNull VirtualFile virtualFile); public abstract void fileStatusesChanged(); public abstract void fileStatusChanged(VirtualFile file); diff --git a/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java b/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java index 168f4eee6828..132d9b6e55b0 100644 --- a/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java +++ b/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java @@ -45,15 +45,13 @@ public abstract class ColoredTreeCellRenderer extends SimpleColoredComponent imp private boolean myOpaque = true; @Override - public final Component getTreeCellRendererComponent( - JTree tree, - Object value, - boolean selected, - boolean expanded, - boolean leaf, - int row, - boolean hasFocus - ){ + public final Component getTreeCellRendererComponent(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus){ myTree = tree; clear(); @@ -72,20 +70,18 @@ public abstract class ColoredTreeCellRenderer extends SimpleColoredComponent imp setBackground(hasFocus ? UIUtil.getTreeSelectionBackground() : UIUtil.getTreeUnfocusedSelectionBackground()); } } - else { - if (selected) { - setPaintFocusBorder(true); - if (isFocused()) { - setBackground(UIUtil.getTreeSelectionBackground()); - } - else { - setBackground(null); - } + else if (selected) { + setPaintFocusBorder(true); + if (isFocused()) { + setBackground(UIUtil.getTreeSelectionBackground()); } else { setBackground(null); } } + else { + setBackground(null); + } if (value instanceof LoadingNode) { setForeground(JBColor.GRAY); @@ -176,13 +172,11 @@ public abstract class ColoredTreeCellRenderer extends SimpleColoredComponent imp * This method is invoked only for customization of component. * All component attributes are cleared when this method is being invoked. */ - public abstract void customizeCellRenderer( - JTree tree, - Object value, - boolean selected, - boolean expanded, - boolean leaf, - int row, - boolean hasFocus - ); + public abstract void customizeCellRenderer(@NotNull JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus); } diff --git a/platform/platform-api/src/com/intellij/ui/LoadingNode.java b/platform/platform-api/src/com/intellij/ui/LoadingNode.java index d5bd442f5b7b..0ac9102b566c 100644 --- a/platform/platform-api/src/com/intellij/ui/LoadingNode.java +++ b/platform/platform-api/src/com/intellij/ui/LoadingNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -16,6 +16,7 @@ package com.intellij.ui; import com.intellij.ide.IdeBundle; +import org.jetbrains.annotations.NotNull; import javax.swing.tree.DefaultMutableTreeNode; @@ -24,11 +25,12 @@ public class LoadingNode extends DefaultMutableTreeNode { this(getText()); } + @NotNull public static String getText() { return IdeBundle.message("treenode.loading"); } - public LoadingNode(String text) { + public LoadingNode(@NotNull String text) { super(text); } } \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/ui/PaintingParent.java b/platform/platform-api/src/com/intellij/ui/PaintingParent.java index 170acdb5ec16..6211581c5206 100644 --- a/platform/platform-api/src/com/intellij/ui/PaintingParent.java +++ b/platform/platform-api/src/com/intellij/ui/PaintingParent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -15,6 +15,7 @@ */ package com.intellij.ui; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -41,16 +42,16 @@ public interface PaintingParent { * @return a rectangle, if null -- the whole component will be repainted */ @Nullable - Rectangle getChildRec(Component c); + Rectangle getChildRec(@NotNull Component c); class Wrapper extends JPanel implements PaintingParent { - public Wrapper(Component component) { + public Wrapper(@NotNull Component component) { super(new BorderLayout(0,0)); add(component); } @Override - public Rectangle getChildRec(Component c) { + public Rectangle getChildRec(@NotNull Component c) { return null; } } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/DebugLogManager.java b/platform/platform-impl/src/com/intellij/diagnostic/DebugLogManager.java new file mode 100644 index 000000000000..39fa3c23eeb3 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/diagnostic/DebugLogManager.java @@ -0,0 +1,100 @@ +/* + * Copyright 2000-2013 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.diagnostic; + +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import org.apache.log4j.Level; +import org.apache.log4j.LogManager; +import com.intellij.openapi.diagnostic.Logger; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; + +/** + * Allows to apply & persist custom log debug categories which can be turned on by user via the {@link com.intellij.ide.actions.DebugLogConfigureAction}.
+ * Applies these custom categories on startup. + */ +public class DebugLogManager extends ApplicationComponent.Adapter { + + private static final Logger LOG = Logger.getInstance(DebugLogManager.class); + private static final String LOG_DEBUG_CATEGORIES = "log.debug.categories"; + + @Override + public void initComponent() { + List categories = getSavedCategories(); + if (categories.isEmpty()) { + saveCategories(getCurrentCategories()); + } + else { + applyCategories(categories); + } + } + + @NotNull + public List getSavedCategories() { + String value = PropertiesComponent.getInstance().getValue(LOG_DEBUG_CATEGORIES); + return value == null ? Collections.emptyList() : fromString(value); + } + + public void applyCategories(@NotNull List categories) { + for (String category : categories) { + org.apache.log4j.Logger logger = LogManager.getLogger(category); + if (logger != null) { + logger.setLevel(Level.DEBUG); + } + } + LOG.info("Set DEBUG for the following categories: " + categories); + } + + public void saveCategories(@NotNull List categories) { + PropertiesComponent.getInstance().setValue(LOG_DEBUG_CATEGORIES, toString(categories)); + } + + @NotNull + private static List fromString(@NotNull String text) { + return Arrays.asList(StringUtil.splitByLines(text, true)); + } + + @NotNull + private static String toString(@NotNull List categories) { + return StringUtil.join(categories, "\n"); + } + + @NotNull + private static List getCurrentCategories() { + Enumeration currentLoggers = LogManager.getCurrentLoggers(); + return ContainerUtil.mapNotNull(ContainerUtil.toList(currentLoggers), new Function() { + @Override + public String fun(Object o) { + if (o instanceof org.apache.log4j.Logger) { + String category = ((org.apache.log4j.Logger)o).getName(); + if (Logger.getInstance(category).isDebugEnabled()) { + return category; + } + } + return null; + } + }); + } + +} diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java index 61ffde901e44..d5d174d788a1 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java @@ -17,6 +17,7 @@ package com.intellij.ide.actions; import com.intellij.execution.ExecutionException; import com.intellij.execution.util.ExecUtil; +import com.intellij.icons.AllIcons; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; @@ -50,8 +51,6 @@ import static java.util.Arrays.asList; public class CreateDesktopEntryAction extends DumbAwareAction { private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.CreateDesktopEntryAction"); - private static final int MIN_ICON_SIZE = 32; - public static boolean isAvailable() { return SystemInfo.isUnix && SystemInfo.hasXdgOpen(); } @@ -138,7 +137,7 @@ public class CreateDesktopEntryAction extends DumbAwareAction { String name = ApplicationNamesInfo.getInstance().getFullProductName(); if (PlatformUtils.isCommunity()) name += " Community Edition"; - final String iconPath = findIcon(binPath); + final String iconPath = AllIcons.findIcon(binPath); if (iconPath == null) { throw new RuntimeException(ApplicationBundle.message("desktop.entry.icon.missing", binPath)); } @@ -161,34 +160,6 @@ public class CreateDesktopEntryAction extends DumbAwareAction { return entryFile; } - @Nullable - private static String findIcon(final String iconsPath) { - final File iconsDir = new File(iconsPath); - - // 1. look for .svg icon - for (String child : iconsDir.list()) { - if (child.endsWith(".svg")) { - return iconsPath + '/' + child; - } - } - - // 2. look for .png icon of max size - int max = 0; - String iconPath = null; - for (String child : iconsDir.list()) { - if (!child.endsWith(".png")) continue; - final String path = iconsPath + '/' + child; - final Icon icon = new ImageIcon(path); - final int size = icon.getIconHeight(); - if (size >= MIN_ICON_SIZE && size > max && size == icon.getIconWidth()) { - max = size; - iconPath = path; - } - } - - return iconPath; - } - @Nullable private static String findScript(final String binPath) { final String productName = ApplicationNamesInfo.getInstance().getProductName(); diff --git a/platform/platform-impl/src/com/intellij/ide/actions/DebugLogConfigureAction.java b/platform/platform-impl/src/com/intellij/ide/actions/DebugLogConfigureAction.java new file mode 100644 index 000000000000..8cefd4eb320e --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/actions/DebugLogConfigureAction.java @@ -0,0 +1,91 @@ +/* + * Copyright 2000-2013 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.ide.actions; + +import com.intellij.diagnostic.DebugLogManager; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.components.JBLabel; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.List; + +public class DebugLogConfigureAction extends DumbAwareAction { + + @Override + public void actionPerformed(AnActionEvent e) { + Project project = e.getProject() == null ? ProjectManager.getInstance().getDefaultProject() : e.getProject(); + DebugLogManager logCustomizer = ServiceManager.getService(DebugLogManager.class); + DebugLogConfigureDialog dialog = new DebugLogConfigureDialog(project, logCustomizer.getSavedCategories()); + if (dialog.showAndGet()) { + List categories = dialog.getLogCategories(); + logCustomizer.applyCategories(categories); + logCustomizer.saveCategories(categories); + } + } + + private static class DebugLogConfigureDialog extends DialogWrapper { + + private static final String ALL_POSSIBLE_SEPARATORS = "(\n|,|;)+"; + @NotNull private final JTextArea myTextArea; + + protected DebugLogConfigureDialog(@Nullable Project project, List categories) { + super(project, false); + myTextArea = new JTextArea(10, 30); + myTextArea.setText(StringUtil.join(categories, "\n")); + setTitle("Custom Debug Log Configuration"); + init(); + } + + @Nullable + @Override + protected JComponent createNorthPanel() { + return new JBLabel("Add log categories separated by new lines"); + } + + @Nullable + @Override + protected JComponent createCenterPanel() { + return ScrollPaneFactory.createScrollPane(myTextArea); + } + + @NotNull + public List getLogCategories() { + return parseCategories(myTextArea.getText()); + } + + @NotNull + private static List parseCategories(@NotNull String text) { + return ContainerUtil.mapNotNull(text.split(ALL_POSSIBLE_SEPARATORS), new Function() { + @Override + public String fun(String s) { + return StringUtil.isEmptyOrSpaces(s) ? null : s.trim(); + } + }); + } + } + +} diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTree.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTree.java index eeb31e0a581e..1b0c17f3ab4e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTree.java @@ -440,6 +440,7 @@ public class ActionsTree { } private class KeymapsRenderer extends ColoredTreeCellRenderer { + // Make sure that the text rendered by this method is 'searchable' via com.intellij.openapi.keymap.impl.ui.ActionsTree.filter method. public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { final boolean showIcons = UISettings.getInstance().SHOW_ICONS_IN_MENUS; Keymap originalKeymap = myKeymap != null ? myKeymap.getParent() : null; diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java index f77ab139ebc7..51dda9805304 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -485,26 +485,18 @@ public class ActionsTreeUtil { if (filter == null) return true; if (action == null) return false; final String insensitiveFilter = filter.toLowerCase(); - final String text = action.getTemplatePresentation().getText(); - if (text != null) { - final String lowerText = text.toLowerCase(); - if (SearchUtil - .isComponentHighlighted(lowerText, insensitiveFilter, force, null)) { - return true; - } - else if (lowerText.contains(insensitiveFilter)) { - return true; - } - } - final String description = action.getTemplatePresentation().getDescription(); - if (description != null) { - final String insensitiveDescription = description.toLowerCase(); - if (SearchUtil - .isComponentHighlighted(insensitiveDescription, insensitiveFilter, force, null)) { - return true; - } - else if (insensitiveDescription.contains(insensitiveFilter)) { - return true; + for (String text : new String[]{action.getTemplatePresentation().getText(), + action.getTemplatePresentation().getDescription(), + action instanceof ActionStub ? ((ActionStub)action).getId() : ActionManager.getInstance().getId(action)}) { + if (text != null) { + final String lowerText = text.toLowerCase(); + + if (SearchUtil.isComponentHighlighted(lowerText, insensitiveFilter, force, null)) { + return true; + } + else if (lowerText.contains(insensitiveFilter)) { + return true; + } } } return false; diff --git a/platform/platform-impl/src/com/intellij/openapi/vcs/impl/FileStatusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vcs/impl/FileStatusManagerImpl.java index 70100dc72a1a..29a1ab9c5d7c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vcs/impl/FileStatusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vcs/impl/FileStatusManagerImpl.java @@ -99,6 +99,7 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC @Override public void run() { DocumentAdapter documentListener = new DocumentAdapter() { + @Override public void documentChanged(DocumentEvent event) { VirtualFile file = FileDocumentManager.getInstance().getFile(event.getDocument()); if (file != null) { @@ -114,6 +115,7 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC } }); startupManager.registerPostStartupActivity(new DumbAwareRunnable() { + @Override public void run() { fileStatusesChanged(); } @@ -139,47 +141,58 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC return getDefaultStatus(virtualFile); } + @NotNull public static FileStatus getDefaultStatus(@NotNull final VirtualFile file) { return file.isValid() && file.is(VFileProperty.SPECIAL) ? FileStatus.IGNORED : FileStatus.NOT_CHANGED; } + @Override public void projectClosed() { } + @Override public void projectOpened() { } + @Override public void disposeComponent() { myCachedStatuses.clear(); } + @Override @NotNull public String getComponentName() { return "FileStatusManager"; } + @Override public void initComponent() { } + @Override public void addFileStatusListener(@NotNull FileStatusListener listener) { myListeners.add(listener); } + @Override public void addFileStatusListener(final FileStatusListener listener, Disposable parentDisposable) { addFileStatusListener(listener); Disposer.register(parentDisposable, new Disposable() { + @Override public void dispose() { removeFileStatusListener(listener); } }); } + @Override public void fileStatusesChanged() { if (myProject.isDisposed()) { return; } if (!ApplicationManager.getApplication().isDispatchThread()) { ApplicationManager.getApplication().invokeLater(new DumbAwareRunnable() { + @Override public void run() { fileStatusesChanged(); } @@ -195,26 +208,28 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC } } - private void cacheChangedFileStatus(final VirtualFile vf, final FileStatus fs) { - myCachedStatuses.put(vf, fs); + private void cacheChangedFileStatus(final VirtualFile virtualFile, final FileStatus fs) { + myCachedStatuses.put(virtualFile, fs); if (FileStatus.NOT_CHANGED.equals(fs)) { - final ThreeState parentingStatus = myFileStatusProvider.getNotChangedDirectoryParentingStatus(vf); + final ThreeState parentingStatus = myFileStatusProvider.getNotChangedDirectoryParentingStatus(virtualFile); if (ThreeState.YES.equals(parentingStatus)) { - myWhetherExactlyParentToChanged.put(vf, true); + myWhetherExactlyParentToChanged.put(virtualFile, true); } else if (ThreeState.UNSURE.equals(parentingStatus)) { - myWhetherExactlyParentToChanged.put(vf, false); + myWhetherExactlyParentToChanged.put(virtualFile, false); } } else { - myWhetherExactlyParentToChanged.remove(vf); + myWhetherExactlyParentToChanged.remove(virtualFile); } } + @Override public void fileStatusChanged(final VirtualFile file) { final Application application = ApplicationManager.getApplication(); if (!application.isDispatchThread() && !application.isUnitTestMode()) { ApplicationManager.getApplication().invokeLater(new DumbAwareRunnable() { + @Override public void run() { fileStatusChanged(file); } @@ -222,7 +237,7 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC return; } - if ((file == null) || (!file.isValid())) return; + if (file == null || !file.isValid()) return; FileStatus cachedStatus = getCachedStatus(file); if (cachedStatus == FileStatusNull.INSTANCE) { return; @@ -240,7 +255,8 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC } } - public FileStatus getStatus(final VirtualFile file) { + @Override + public FileStatus getStatus(@NotNull final VirtualFile file) { if (file instanceof LightVirtualFile) { return FileStatus.NOT_CHANGED; // do not leak light files via cache } @@ -258,6 +274,7 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC return myCachedStatuses.get(file); } + @Override public void removeFileStatusListener(FileStatusListener listener) { myListeners.remove(listener); } @@ -271,7 +288,7 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC final Boolean exactMatch = myWhetherExactlyParentToChanged.get(vf); return exactMatch == null ? notChangedColor - : (exactMatch ? FileStatus.NOT_CHANGED_IMMEDIATE.getColor() : FileStatus.NOT_CHANGED_RECURSIVE.getColor()); + : exactMatch ? FileStatus.NOT_CHANGED_IMMEDIATE.getColor() : FileStatus.NOT_CHANGED_RECURSIVE.getColor(); } public void refreshFileStatusFromDocument(final VirtualFile file, final Document doc) { diff --git a/platform/platform-impl/src/com/intellij/openapi/vcs/impl/FileStatusProvider.java b/platform/platform-impl/src/com/intellij/openapi/vcs/impl/FileStatusProvider.java index 955430ee69f1..e9ba482818c2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vcs/impl/FileStatusProvider.java +++ b/platform/platform-impl/src/com/intellij/openapi/vcs/impl/FileStatusProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -20,6 +20,7 @@ import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.vcs.FileStatus; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ThreeState; +import org.jetbrains.annotations.NotNull; /** * @author yole @@ -28,8 +29,9 @@ public interface FileStatusProvider { ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.vcs.fileStatusProvider"); - FileStatus getFileStatus(final VirtualFile virtualFile); - void refreshFileStatusFromDocument(final VirtualFile file, final Document doc); + FileStatus getFileStatus(@NotNull VirtualFile virtualFile); + void refreshFileStatusFromDocument(@NotNull VirtualFile virtualFile, @NotNull Document doc); - ThreeState getNotChangedDirectoryParentingStatus(VirtualFile vf); + @NotNull + ThreeState getNotChangedDirectoryParentingStatus(@NotNull VirtualFile virtualFile); } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ui/LibNotifyWrapper.java b/platform/platform-impl/src/com/intellij/ui/LibNotifyWrapper.java index ac4d142172cf..4d0323b9daa6 100644 --- a/platform/platform-impl/src/com/intellij/ui/LibNotifyWrapper.java +++ b/platform/platform-impl/src/com/intellij/ui/LibNotifyWrapper.java @@ -15,6 +15,11 @@ */ package com.intellij.ui; +import com.intellij.icons.AllIcons; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationGroup; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; import com.intellij.openapi.application.PathManager; import com.intellij.util.lang.UrlClassLoader; @@ -23,9 +28,41 @@ import com.intellij.util.lang.UrlClassLoader; */ public class LibNotifyWrapper { + private final static String message = "Looks like you have run 32-bit Java on a 64-bit version of OS " + + "or just have not installed appropriate libnotify.so library"; + + private static boolean available = true; + static{ UrlClassLoader.loadPlatformLibrary("notifywrapper"); } - native public static void showNotification(String title, String description); + native private static void showNotification(final String title, final String description, final String iconPath); + + public static void show(final String title, final String description, final String iconPath) { + if (! available) return; + try { + showNotification(title, description, iconPath); + } catch (UnsatisfiedLinkError ule) { + available = false; + NotificationGroup.balloonGroup("Linux configuration messages"); + Notifications.Bus.notify( + new Notification("Linux configuration messages", + "Notification library has not been installed", + message, NotificationType.INFORMATION) + ); + } + } + + /** + * Shows a libnotify notification with an icon from the ide bin directory. + * If there is no such icon a default information icon is shown. + * @param title notification title + * @param description notification description + */ + public static void showWithAppIcon(final String title, final String description) { + String iconPath = AllIcons.findIcon(PathManager.getBinPath()); + show(title, description, (iconPath == null) ? "dialog-information" : iconPath); + } + } diff --git a/platform/platform-impl/src/com/intellij/ui/SystemNotificationsImpl.java b/platform/platform-impl/src/com/intellij/ui/SystemNotificationsImpl.java index 39a676c6ec26..3240b3eb0434 100644 --- a/platform/platform-impl/src/com/intellij/ui/SystemNotificationsImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/SystemNotificationsImpl.java @@ -45,7 +45,7 @@ public class SystemNotificationsImpl extends SystemNotifications implements Pers if (!areNotificationsEnabled() || ApplicationManager.getApplication().isActive()) return; if (SystemInfo.isLinux && Registry.is("ide.linux.gtk.notifications.enabled") ) { - LibNotifyWrapper.showNotification(title, text); + LibNotifyWrapper.showWithAppIcon(title, text); return; } diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index f38822c1199a..b7d2308290a5 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -1062,6 +1062,8 @@ action.Graph.print.preview=Print Preview action.SendFeedback.text=Submit _Feedback action.SendFeedback.description=Submit feedback to the JetBrains Web site +action.LogDebugConfigure.text=Configure Debug Log Settings +action.LogDebugConfigure.description=Enable or disable additional log categories. Allows to provide more information to the support team by request. action.ShowLog.text=Open Log file action.ShowLog.description=Opens folder with log file action.TechnicalSupport.text=Contact _Support Team diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 0b3b07aace49..5a23649bccb7 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -818,6 +818,7 @@ + diff --git a/platform/platform-resources/src/componentSets/Lang.xml b/platform/platform-resources/src/componentSets/Lang.xml index fbb77b25f91d..dc2fabfbeb07 100644 --- a/platform/platform-resources/src/componentSets/Lang.xml +++ b/platform/platform-resources/src/componentSets/Lang.xml @@ -230,6 +230,10 @@ + + com.intellij.ide.GeneratedSourceFileChangeTracker + com.intellij.ide.GeneratedSourceFileChangeTrackerImpl + diff --git a/platform/platform-resources/src/componentSets/Platform.xml b/platform/platform-resources/src/componentSets/Platform.xml index 93daf4fceee2..ef911ec4b8b1 100644 --- a/platform/platform-resources/src/componentSets/Platform.xml +++ b/platform/platform-resources/src/componentSets/Platform.xml @@ -137,6 +137,10 @@ com.intellij.ide.SystemHealthMonitor + + + com.intellij.diagnostic.DebugLogManager + diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 2120261cd37e..8d7da3cab4a7 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -409,6 +409,7 @@ + diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/keymap/impl/ui/ActionsTreeTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/keymap/impl/ui/ActionsTreeTest.java new file mode 100644 index 000000000000..582ddb3208ff --- /dev/null +++ b/platform/platform-tests/testSrc/com/intellij/openapi/keymap/impl/ui/ActionsTreeTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2013 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.openapi.keymap.impl.ui; + +import com.intellij.openapi.actionSystem.ex.QuickList; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.testFramework.LightPlatformCodeInsightTestCase; + +public class ActionsTreeTest extends LightPlatformCodeInsightTestCase { + private static final String ACTION_WITHOUT_TEXT_AND_DESCRIPTION = "EditorDeleteToLineEnd"; + private static final String ACTION_WITH_TEXT_ONLY = "EditorCutLineEnd"; + private static final String ACTION_WITH_TEXT_AND_DESCRIPTION = "EditorHungryBackSpace"; + + private ActionsTree myActionsTree; + + public void setUp() throws Exception { + super.setUp(); + myActionsTree = new ActionsTree(); + myActionsTree.reset(KeymapManager.getInstance().getActiveKeymap(), new QuickList[0]); + } + + public void testVariousActionsArePresent() { + doTest(null, + ACTION_WITHOUT_TEXT_AND_DESCRIPTION, + ACTION_WITH_TEXT_ONLY, + ACTION_WITH_TEXT_AND_DESCRIPTION); + } + + public void testFiltering() { + doTest("Editor", + // all below actions should still be present, as they contain 'Editor' in their actionId + ACTION_WITHOUT_TEXT_AND_DESCRIPTION, + ACTION_WITH_TEXT_ONLY, + ACTION_WITH_TEXT_AND_DESCRIPTION); + } + + private void doTest(String filter, String... idsThatMustBePresent) { + if (filter != null) { + myActionsTree.filter(filter, new QuickList[0]); + } + + for (String actionId : idsThatMustBePresent) { + assertTrue(actionId + " is absent", myActionsTree.getMainGroup().containsId(actionId)); + } + } +} diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/vcs/MockChangeListManager.java b/platform/testFramework/testSrc/com/intellij/testFramework/vcs/MockChangeListManager.java index a4869d9bf095..b3557238124f 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/vcs/MockChangeListManager.java +++ b/platform/testFramework/testSrc/com/intellij/testFramework/vcs/MockChangeListManager.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2013 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.testFramework.vcs; import com.intellij.openapi.application.ModalityState; @@ -204,8 +219,9 @@ public class MockChangeListManager extends ChangeListManagerEx { return changes; } + @NotNull @Override - public ThreeState haveChangesUnder(VirtualFile vf) { + public ThreeState haveChangesUnder(@NotNull VirtualFile vf) { throw new UnsupportedOperationException(); } diff --git a/platform/usageView/src/com/intellij/usages/UsageView.java b/platform/usageView/src/com/intellij/usages/UsageView.java index 2736f74ebbba..46906ba2fa22 100644 --- a/platform/usageView/src/com/intellij/usages/UsageView.java +++ b/platform/usageView/src/com/intellij/usages/UsageView.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -71,6 +71,7 @@ public interface UsageView extends Disposable { */ void addPerformOperationAction(@NotNull Runnable processRunnable, String commandName, String cannotMakeString, @NotNull String shortDescription, boolean checkReadOnlyStatus); + @NotNull UsageViewPresentation getPresentation(); @NotNull diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java index 35f60dfd8035..38a512918baf 100644 --- a/platform/util/src/com/intellij/icons/AllIcons.java +++ b/platform/util/src/com/intellij/icons/AllIcons.java @@ -16,8 +16,10 @@ package com.intellij.icons; import com.intellij.openapi.util.IconLoader; +import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.io.File; /** * NOTE THIS FILE IS AUTO-GENERATED @@ -1137,4 +1139,34 @@ public class AllIcons { public static final Icon Html_id = IconLoader.getIcon("/xml/html_id.png"); // 16x16 } + + private static final int MIN_ICON_SIZE = 32; + + @Nullable + public static String findIcon(final String iconsPath) { + final File iconsDir = new File(iconsPath); + + // 1. look for .svg icon + for (String child : iconsDir.list()) { + if (child.endsWith(".svg")) { + return iconsPath + '/' + child; + } + } + + // 2. look for .png icon of max size + int max = 0; + String iconPath = null; + for (String child : iconsDir.list()) { + if (!child.endsWith(".png")) continue; + final String path = iconsPath + '/' + child; + final Icon icon = new ImageIcon(path); + final int size = icon.getIconHeight(); + if (size >= MIN_ICON_SIZE && size > max && size == icon.getIconWidth()) { + max = size; + iconPath = path; + } + } + + return iconPath; + } } diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index d8078d0f511f..559fe5a0001f 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -105,6 +105,7 @@ public class FileUtil extends FileUtilRt { return !ThreeState.NO.equals(isAncestorThreeState(ancestor, file, strict)); } + @NotNull public static ThreeState isAncestorThreeState(@NotNull String ancestor, @NotNull String file, boolean strict) { String ancestorPath = toCanonicalPath(ancestor); String filePath = toCanonicalPath(file); @@ -127,6 +128,7 @@ public class FileUtil extends FileUtilRt { /** * @return ThreeState.YES if same path or immediate parent */ + @NotNull private static ThreeState startsWith(@NotNull String path, @NotNull String start, boolean strict, boolean caseSensitive, boolean checkImmediateParent) { final int length1 = path.length(); @@ -138,12 +140,11 @@ public class FileUtil extends FileUtilRt { return strict ? ThreeState.NO : ThreeState.YES; } char last2 = start.charAt(length2 - 1); - char next1; int slashOrSeparatorIdx = length2; if (last2 == '/' || last2 == File.separatorChar) { slashOrSeparatorIdx = length2 - 1; } - next1 = path.charAt(slashOrSeparatorIdx); + char next1 = path.charAt(slashOrSeparatorIdx); if (next1 == '/' || next1 == File.separatorChar) { if (!checkImmediateParent) return ThreeState.YES; diff --git a/platform/util/src/com/intellij/util/AdapterProcessor.java b/platform/util/src/com/intellij/util/AdapterProcessor.java index a80f45114140..549249bfa8e7 100644 --- a/platform/util/src/com/intellij/util/AdapterProcessor.java +++ b/platform/util/src/com/intellij/util/AdapterProcessor.java @@ -19,11 +19,13 @@ */ package com.intellij.util; +import org.jetbrains.annotations.NotNull; + public class AdapterProcessor implements Processor { private final Processor myAdaptee; private final Function myConversion; - public AdapterProcessor(Processor adaptee, Function conversion) { + public AdapterProcessor(@NotNull Processor adaptee, @NotNull Function conversion) { myAdaptee = adaptee; myConversion = conversion; } diff --git a/platform/util/src/com/intellij/util/enumeration/EmptyEnumeration.java b/platform/util/src/com/intellij/util/enumeration/EmptyEnumeration.java index ac9e9c89cd8f..cd86477efe40 100644 --- a/platform/util/src/com/intellij/util/enumeration/EmptyEnumeration.java +++ b/platform/util/src/com/intellij/util/enumeration/EmptyEnumeration.java @@ -15,10 +15,12 @@ */ package com.intellij.util.enumeration; +import org.jetbrains.annotations.NotNull; + import java.util.Enumeration; import java.util.NoSuchElementException; -public final class EmptyEnumeration implements Enumeration { +public final class EmptyEnumeration implements Enumeration { public static Enumeration INSTANCE = new EmptyEnumeration(); private EmptyEnumeration(){ @@ -30,9 +32,15 @@ public final class EmptyEnumeration implements Enumeration { } @Override - public Object nextElement(){ + public E nextElement(){ throw new NoSuchElementException(); } + + @NotNull + public static Enumeration getInstance() { + //noinspection unchecked + return INSTANCE; + } } diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManager.java b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManager.java index f3f2958fe6d3..006276b42739 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManager.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -157,5 +157,6 @@ public abstract class ChangeListManager implements ChangeListModification { public abstract List getModifiedWithoutEditing(); - public abstract ThreeState haveChangesUnder(VirtualFile vf); + @NotNull + public abstract ThreeState haveChangesUnder(@NotNull VirtualFile vf); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java index 3e9e9b8d052e..825357f2241d 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -1088,9 +1088,10 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec return getChangesIn(new FilePathImpl(dir)); } + @NotNull @Override - public ThreeState haveChangesUnder(final VirtualFile vf) { - if (vf == null || ! vf.isValid() || ! vf.isDirectory()) return ThreeState.NO; + public ThreeState haveChangesUnder(@NotNull final VirtualFile vf) { + if (!vf.isValid() || !vf.isDirectory()) return ThreeState.NO; synchronized (myDataLock) { return myWorker.haveChangesUnder(vf); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java index 3179c0fd1448..fa8fdaa89259 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -693,8 +693,9 @@ public class ChangeListWorker implements ChangeListsWriteOperations { return null; } - public ThreeState haveChangesUnder(final VirtualFile vf) { - final String absolutePath = new File(vf.getPath()).getAbsolutePath(); + @NotNull + public ThreeState haveChangesUnder(@NotNull VirtualFile virtualFile) { + final String absolutePath = new File(virtualFile.getPath()).getAbsolutePath(); final SortedSet tailSet = myIdx.getAffectedPaths().tailSet(absolutePath); for (String path : tailSet) { return FileUtil.isAncestorThreeState(absolutePath, path, false); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictFileStatusProvider.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictFileStatusProvider.java index d19953e218a8..45cfff7ade57 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictFileStatusProvider.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictFileStatusProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -24,6 +24,7 @@ import com.intellij.openapi.vcs.changes.ChangeListManagerImpl; import com.intellij.openapi.vcs.impl.FileStatusProvider; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ThreeState; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.awt.*; @@ -48,8 +49,9 @@ public class ChangelistConflictFileStatusProvider implements FileStatusProvider myConflictTracker = changeListManager.getConflictTracker(); } + @Override @Nullable - public FileStatus getFileStatus(VirtualFile virtualFile) { + public FileStatus getFileStatus(@NotNull VirtualFile virtualFile) { ChangelistConflictTracker.Options options = myConflictTracker.getOptions(); if (!options.TRACKING_ENABLED) { return null; @@ -69,12 +71,14 @@ public class ChangelistConflictFileStatusProvider implements FileStatusProvider return null; } - public void refreshFileStatusFromDocument(VirtualFile file, Document doc) { + @Override + public void refreshFileStatusFromDocument(@NotNull VirtualFile virtualFile, @NotNull Document doc) { } + @NotNull @Override - public ThreeState getNotChangedDirectoryParentingStatus(VirtualFile vf) { + public ThreeState getNotChangedDirectoryParentingStatus(@NotNull VirtualFile virtualFile) { throw new UnsupportedOperationException("Shouldn't be called"); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsFileStatusProvider.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsFileStatusProvider.java index 18a151388abe..f84ac73a2abc 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsFileStatusProvider.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsFileStatusProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -29,6 +29,7 @@ import com.intellij.openapi.vcs.readOnlyHandler.ReadonlyStatusHandlerImpl; import com.intellij.openapi.vcs.rollback.RollbackEnvironment; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ThreeState; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -60,18 +61,22 @@ public class VcsFileStatusProvider implements FileStatusProvider, VcsBaseContent myFileStatusManager.setFileStatusProvider(this); changeListManager.addChangeListListener(new ChangeListAdapter() { + @Override public void changeListAdded(ChangeList list) { fileStatusesChanged(); } + @Override public void changeListRemoved(ChangeList list) { fileStatusesChanged(); } + @Override public void changeListChanged(ChangeList list) { fileStatusesChanged(); } + @Override public void changeListUpdateDone() { if (myHaveEmptyContentRevisions) { myHaveEmptyContentRevisions = false; @@ -89,7 +94,9 @@ public class VcsFileStatusProvider implements FileStatusProvider, VcsBaseContent myFileStatusManager.fileStatusesChanged(); } - public FileStatus getFileStatus(final VirtualFile virtualFile) { + @Override + @NotNull + public FileStatus getFileStatus(@NotNull final VirtualFile virtualFile) { final AbstractVcs vcs = myVcsManager.getVcsFor(virtualFile); if (vcs == null) { return FileStatusManagerImpl.getDefaultStatus(virtualFile); @@ -110,33 +117,35 @@ public class VcsFileStatusProvider implements FileStatusProvider, VcsBaseContent return FileDocumentManager.getInstance().isFileModified(virtualFile); } - public void refreshFileStatusFromDocument(final VirtualFile file, final Document doc) { + @Override + public void refreshFileStatusFromDocument(@NotNull final VirtualFile virtualFile, @NotNull final Document doc) { if (LOG.isDebugEnabled()) { - LOG.debug("refreshFileStatusFromDocument: file.getModificationStamp()=" + file.getModificationStamp() + ", document.getModificationStamp()=" + doc.getModificationStamp()); + LOG.debug("refreshFileStatusFromDocument: file.getModificationStamp()=" + virtualFile.getModificationStamp() + ", document.getModificationStamp()=" + doc.getModificationStamp()); } - FileStatus cachedStatus = myFileStatusManager.getCachedStatus(file); - if (cachedStatus == null || cachedStatus == FileStatus.NOT_CHANGED || !isDocumentModified(file)) { - final AbstractVcs vcs = myVcsManager.getVcsFor(file); + FileStatus cachedStatus = myFileStatusManager.getCachedStatus(virtualFile); + if (cachedStatus == null || cachedStatus == FileStatus.NOT_CHANGED || !isDocumentModified(virtualFile)) { + final AbstractVcs vcs = myVcsManager.getVcsFor(virtualFile); if (vcs == null) return; - if (cachedStatus == FileStatus.MODIFIED && !isDocumentModified(file)) { + if (cachedStatus == FileStatus.MODIFIED && !isDocumentModified(virtualFile)) { if (!((ReadonlyStatusHandlerImpl) ReadonlyStatusHandlerImpl.getInstance(myProject)).getState().SHOW_DIALOG) { RollbackEnvironment rollbackEnvironment = vcs.getRollbackEnvironment(); if (rollbackEnvironment != null) { - rollbackEnvironment.rollbackIfUnchanged(file); + rollbackEnvironment.rollbackIfUnchanged(virtualFile); } } } - myFileStatusManager.fileStatusChanged(file); + myFileStatusManager.fileStatusChanged(virtualFile); ChangeProvider cp = vcs.getChangeProvider(); if (cp != null && cp.isModifiedDocumentTrackingRequired()) { - myDirtyScopeManager.fileDirty(file); + myDirtyScopeManager.fileDirty(virtualFile); } } } + @NotNull @Override - public ThreeState getNotChangedDirectoryParentingStatus(VirtualFile vf) { - return myConfiguration.SHOW_DIRTY_RECURSIVELY ? myChangeListManager.haveChangesUnder(vf) : ThreeState.NO; + public ThreeState getNotChangedDirectoryParentingStatus(@NotNull VirtualFile virtualFile) { + return myConfiguration.SHOW_DIRTY_RECURSIVELY ? myChangeListManager.haveChangesUnder(virtualFile) : ThreeState.NO; } @Override @@ -164,6 +173,7 @@ public class VcsFileStatusProvider implements FileStatusProvider, VcsBaseContent if (isDocumentModified(file)) { return ApplicationManager.getApplication().runReadAction(new Computable() { + @Override public String compute() { return LoadTextUtil.loadText(file).toString(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionBundle.properties index 348e53ffbbb6..eae16b25f18f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionBundle.properties @@ -106,4 +106,5 @@ add.type.customizer.to.resources=Add type customizer script to resources target.0.does.not.exist=Target ''{0}'' does not exist target.annotation.is.unused=@Target is unused change.lvalue.type=Change variable ''{0}'' type to ''{1}'' -replace.qualified.name.with.import=Replace qualified name with import \ No newline at end of file +replace.qualified.name.with.import=Replace qualified name with import +highlight.assignments.from.void=Highlight assignments from void type \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java index fff85386e35c..950c34398f20 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java @@ -18,12 +18,14 @@ package org.jetbrains.plugins.groovy.codeInspection.assignment; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.*; +import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.lang.annotation.Annotation; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; +import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.psi.*; import com.intellij.psi.impl.PsiSubstitutorImpl; import com.intellij.psi.tree.IElementType; @@ -80,6 +82,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.*; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; +import javax.swing.*; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -90,6 +93,10 @@ import java.util.Map; public class GroovyAssignabilityCheckInspection extends BaseInspection { private static final Logger LOG = Logger.getInstance(GroovyAssignabilityCheckInspection.class); + private static final String SHORT_NAME = "GroovyAssignabilityCheck"; + + public boolean myHighlightAssignmentsFromVoid = true; + @Nls @NotNull @Override @@ -102,6 +109,14 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection { return true; } + @Nullable + @Override + public JComponent createOptionsPanel() { + final MultipleCheckboxOptionsPanel optionsPanel = new MultipleCheckboxOptionsPanel(this); + optionsPanel.addCheckbox(GroovyInspectionBundle.message("highlight.assignments.from.void"), "myHighlightAssignmentsFromVoid"); + return optionsPanel; + } + @Nls @NotNull @Override @@ -127,6 +142,14 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection { final PsiType rType = expression.getType(); if (rType == null) return; + if (PsiUtil.isVoidMethodCall(expression)) { + if (isHighlightAssignmentsFromVoid(expression)) { + registerError(toHighlight, GroovyBundle.message("cannot.assign", PsiType.VOID.getPresentableText(), + expectedType.getPresentableText())); + } + return; + } + if (!TypesUtil.isAssignable(expectedType, rType, expression)) { final List fixes = ContainerUtil.newArrayList(); fixes.add(new GrCastFix(expectedType)); @@ -141,6 +164,21 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection { } } + private static boolean isHighlightAssignmentsFromVoid(PsiElement place) { + final GroovyAssignabilityCheckInspection instance = getInspectionInstance(place.getContainingFile(), place.getProject()); + if (instance != null) { + return instance.myHighlightAssignmentsFromVoid; + } + + return false; + } + + private static GroovyAssignabilityCheckInspection getInspectionInstance(PsiFile file, Project project) { + final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile(); + return (GroovyAssignabilityCheckInspection)profile.getUnwrappedTool(SHORT_NAME, file); + } + + @Nullable private static String getLValueVarName(PsiElement highlight) { final PsiElement parent = highlight.getParent(); @@ -221,7 +259,7 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection { if (flowOwner != null && returnType != null && returnType != PsiType.VOID) { if (ControlFlowUtils.isReturnValue(expression, flowOwner) && !isNewInstanceInitialingByTuple(expression) && - expression.getType() != PsiType.VOID) { + !PsiUtil.isVoidMethodCall(expression)) { checkAssignability(returnType, expression, getExpressionPartToHighlight(expression)); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/GenerateGroovyDocDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/GenerateGroovyDocDialog.java index 4216f4cc2803..2d87f0acad57 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/GenerateGroovyDocDialog.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/GenerateGroovyDocDialog.java @@ -54,12 +54,6 @@ public final class GenerateGroovyDocDialog extends DialogWrapper { } } - @Override - protected void dispose() { - super.dispose(); - //Disposer.dispose(myPanel); - } - @Nullable @Override protected String getHelpId() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/GroovyDocGenerationPanel.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/GroovyDocGenerationPanel.java index 5f9cec8d5c11..3973a8df145b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/GroovyDocGenerationPanel.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/GroovyDocGenerationPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -36,7 +36,7 @@ import java.io.File; import java.util.HashSet; import java.util.Set; -public final class GroovyDocGenerationPanel extends JPanel/* implements Disposable*/ { +public final class GroovyDocGenerationPanel extends JPanel { JPanel myPanel; TextFieldWithBrowseButton myOutputDir; NonFocusableCheckBox myIsUse; @@ -54,9 +54,6 @@ public final class GroovyDocGenerationPanel extends JPanel/* implements Disposab private final DefaultListModel myDataModel; GroovyDocGenerationPanel() { - //Disposer.register(this, myInputDir); - //Disposer.register(this, myOutputDir); - myInputDir.addBrowseFolderListener(GroovyDocBundle.message("groovydoc.generate.directory.browse"), null, null, FileChooserDescriptorFactory.createSingleFolderDescriptor()); @@ -161,8 +158,4 @@ private static String[] toStringArray(final DefaultListModel model) { public JPanel getPanel() { return myPanel; } - - //@Override - public void dispose() { - } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/MaybeReturnInstruction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/MaybeReturnInstruction.java index 7720041c4486..bfb4a825089b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/MaybeReturnInstruction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/MaybeReturnInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -18,6 +18,8 @@ package org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl; import com.intellij.psi.PsiType; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; /** * @author peter @@ -35,7 +37,7 @@ public class MaybeReturnInstruction extends InstructionImpl { GrExpression expression = (GrExpression) getElement(); assert expression != null; final PsiType type = expression.getType(); - return type != PsiType.VOID; + return type != PsiType.VOID && !PsiUtil.isVoidMethodCall(expression); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java index 8c02c7120302..06c09e1767e4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java @@ -557,7 +557,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory { public GrMethod createMethodFromSignature(String name, GrClosureSignature signature) { StringBuilder builder = new StringBuilder("public"); final PsiType returnType = signature.getReturnType(); - if (returnType != null) { + if (returnType != null && returnType != PsiType.NULL) { builder.append(' '); builder.append(returnType.getCanonicalText()); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java index b8d1dedd7c79..31763f8478a5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java @@ -54,18 +54,21 @@ public class DefaultCallExpressionTypeCalculator extends GrCallExpressionTypeCal PsiType result = null; for (GroovyResolveResult resolveResult : resolveResults) { PsiType returnType = calculateReturnTypeInner(callExpression, refExpr, resolveResult); - if (returnType == null) return null; - if (!(returnType instanceof GrLiteralClassType)) { - returnType = TypesUtil.substituteBoxAndNormalizeType(returnType, resolveResult.getSubstitutor(), resolveResult.getSpreadState(), callExpression); - LOG.assertTrue(returnType != null); - } - if (result == null || returnType.isAssignableFrom(result)) { - result = returnType; + PsiType nonVoid = PsiType.VOID.equals(returnType) ? PsiType.NULL : returnType; + + PsiType normalized = nonVoid instanceof GrLiteralClassType + ? nonVoid + : TypesUtil.substituteBoxAndNormalizeType(nonVoid, resolveResult.getSubstitutor(), resolveResult.getSpreadState(), callExpression); + + LOG.assertTrue(normalized != null); + + if (result == null || normalized.isAssignableFrom(result)) { + result = normalized; } - else if (!result.isAssignableFrom(returnType)) { - result = TypesUtil.getLeastUpperBound(result, returnType, manager); + else if (!result.isAssignableFrom(normalized)) { + result = TypesUtil.getLeastUpperBound(result, normalized, manager); } } @@ -81,26 +84,29 @@ public class DefaultCallExpressionTypeCalculator extends GrCallExpressionTypeCal GrReferenceExpression refExpr, GroovyResolveResult resolveResult) { PsiElement resolved = resolveResult.getElement(); - PsiType returnType = null; if (resolved instanceof PsiMethod) { PsiMethod method = (PsiMethod)resolved; if (resolveResult.isInvokedOnProperty()) { final PsiType propertyType = PsiUtil.getSmartReturnType(method); - returnType = extractReturnTypeFromType(propertyType, true, callExpression); + return extractReturnTypeFromType(propertyType, true, callExpression); } else { - returnType = getClosureMethodsReturnType(callExpression, refExpr, method); - if (returnType == null) { - returnType = PsiUtil.getSmartReturnType(method); + PsiType closureReturnType = getClosureMethodsReturnType(callExpression, refExpr, method); + if (closureReturnType != null) { + return closureReturnType; + } + else { + final PsiType smartReturnType = PsiUtil.getSmartReturnType(method); + return smartReturnType; } } } else if (resolved instanceof GrVariable) { PsiType refType = refExpr.getType(); final PsiType type = refType == null ? ((GrVariable)resolved).getTypeGroovy() : refType; - returnType = extractReturnTypeFromType(type, false, callExpression); + return extractReturnTypeFromType(type, false, callExpression); } - return returnType; + return null; } @Nullable diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java index 471a5e34d492..96abb95e49b7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java @@ -38,6 +38,7 @@ import icons.JetgroovyIcons; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster; import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor; import org.jetbrains.plugins.groovy.gpp.GppTypeConverter; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment; @@ -260,25 +261,26 @@ public abstract class GrMethodBaseImpl extends GrStubElementBase i @Nullable public GrTypeElement setReturnType(@Nullable PsiType newReturnType) { GrTypeElement typeElement = getReturnTypeElementGroovy(); - if (newReturnType == null) { + if (newReturnType == null || newReturnType == PsiType.NULL) { if (typeElement != null) typeElement.delete(); return null; } - GrTypeElement newTypeElement = GroovyPsiElementFactory.getInstance(getProject()).createTypeElement(newReturnType); + final GrTypeElement stub = GroovyPsiElementFactory.getInstance(getProject()).createTypeElement(newReturnType); + GrTypeElement newTypeElement; if (typeElement == null) { - PsiElement anchor = getTypeParameterList(); - if (anchor == null) anchor = getModifierList(); - newTypeElement = (GrTypeElement)addAfter(newTypeElement, anchor); + final GrTypeParameterList typeParemeterList = getTypeParameterList(); + PsiElement anchor = typeParemeterList != null ? typeParemeterList : getModifierList(); + newTypeElement = (GrTypeElement)addAfter(stub, anchor); } else { - newTypeElement = (GrTypeElement)typeElement.replace(newTypeElement); + newTypeElement = (GrTypeElement)typeElement.replace(stub); } newTypeElement.accept(new GroovyRecursiveElementVisitor() { @Override public void visitCodeReferenceElement(GrCodeReferenceElement refElement) { super.visitCodeReferenceElement(refElement); - org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster.shortenReference(refElement); + GrReferenceAdjuster.shortenReference(refElement); } }); return newTypeElement; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java index 867faf6fede6..a9d74faa5fc6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java @@ -28,9 +28,7 @@ import com.intellij.psi.impl.light.LightElement; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; -import com.intellij.psi.util.InheritanceUtil; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.psi.util.*; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.VisibilityUtil; @@ -56,6 +54,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgument import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrSpreadArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrAssertStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement; @@ -63,6 +62,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrThrowStatem import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClause; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrPropertySelection; @@ -73,6 +73,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.*; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrNamedArgumentsOwner; +import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction; import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper; import org.jetbrains.plugins.groovy.lang.psi.impl.*; import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; @@ -1347,4 +1348,38 @@ public class PsiUtil { final String qname = aClass.getQualifiedName(); return GroovyCommonClassNames.GROOVY_EXTENSION_CLASSES.contains(qname); } + + public static boolean isVoidMethodCall(@Nullable GrExpression expression) { + if (expression instanceof GrMethodCall && PsiType.NULL.equals(expression.getType())) { + final GroovyResolveResult resolveResult = ((GrMethodCall)expression).advancedResolve(); + final PsiType[] args = getArgumentTypes(((GrMethodCall)expression).getInvokedExpression(), true); + return PsiType.VOID.equals(ResolveUtil.extractReturnTypeFromCandidate(resolveResult, expression, args)); + } + + return false; + } + + public static boolean isVoidMethod(@NotNull PsiMethod method) { + return PsiType.VOID.equals(method.getReturnType()) || + + method instanceof GrMethod && + ((GrMethod)method).getReturnTypeElementGroovy() == null && + ((GrMethod)method).getBlock() != null && + isBlockReturnVoid(((GrMethod)method).getBlock()); + } + + public static boolean isBlockReturnVoid(@NotNull final GrCodeBlock block) { + return CachedValuesManager.getCachedValue(block, new CachedValueProvider() { + @Nullable + @Override + public Result compute() { + return Result.create(ControlFlowUtils.visitAllExitPoints(block, new ControlFlowUtils.ExitPointVisitor() { + @Override + public boolean visitExitPoint(Instruction instruction, @Nullable GrExpression returnValue) { + return returnValue == null || !(returnValue instanceof GrLiteral); + } + }), PsiModificationTracker.MODIFICATION_COUNT); + } + }); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnonymousFromMapGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnonymousFromMapGenerator.java index 156e1d881744..03290f5b4f28 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnonymousFromMapGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnonymousFromMapGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -68,9 +68,10 @@ public class AnonymousFromMapGenerator { final GrExpression expression = arg.getExpression(); if (name == null || expression == null || !(expression instanceof GrClosableBlock)) continue; - final GrParameter[] allParameters = ((GrClosableBlock)expression).getAllParameters(); + final GrClosableBlock closure = (GrClosableBlock)expression; + final GrParameter[] allParameters = closure.getAllParameters(); List actual = new ArrayList(Arrays.asList(allParameters)); - final PsiType clReturnType = ((GrClosableBlock)expression).getReturnType(); + final PsiType clReturnType = context.typeProvider.getReturnType(closure); GrExpression[] args = new GrExpression[allParameters.length]; for (int i = 0; i < allParameters.length; i++) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClosureGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClosureGenerator.java index 7f04df75c424..17d28926588b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClosureGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClosureGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -34,6 +34,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrRe import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl; import java.util.Collection; +import java.util.Collections; import static org.jetbrains.plugins.groovy.refactoring.convertToJava.TypeWriter.writeType; import static org.jetbrains.plugins.groovy.refactoring.convertToJava.TypeWriter.writeTypeForNew; @@ -85,15 +86,15 @@ public class ClosureGenerator { private void generateClosureMainMethod(@NotNull GrClosableBlock block) { builder.append("public "); - final PsiType returnType = block.getReturnType(); + final PsiType returnType = context.typeProvider.getReturnType(block); writeType(builder, returnType, block); builder.append(" doCall"); final GrParameter[] parameters = block.getAllParameters(); GenerationUtil.writeParameterList(builder, parameters, new GeneratorClassNameProvider(), context); - Collection myExitPoints = ControlFlowUtils.collectReturns(block); - boolean shouldInsertReturnNull = - !(returnType instanceof PsiPrimitiveType) && MissingReturnInspection.methodMissesSomeReturns(block, MissingReturnInspection.ReturnStatus.shouldNotReturnValue); + Collection myExitPoints = returnType != PsiType.VOID ? ControlFlowUtils.collectReturns(block) : Collections.emptySet(); + boolean shouldInsertReturnNull = !(returnType instanceof PsiPrimitiveType) && + MissingReturnInspection.methodMissesSomeReturns(block, MissingReturnInspection.ReturnStatus.shouldNotReturnValue); new CodeBlockGenerator(builder, context.extend(), myExitPoints).generateCodeBlock(block, shouldInsertReturnNull); builder.append('\n'); @@ -104,7 +105,7 @@ public class ClosureGenerator { final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(context.project); final GrMethod method = factory.createMethodFromText("def doCall(){}", block); - method.setReturnType(block.getReturnType()); + method.setReturnType(context.typeProvider.getReturnType(block)); if (block.hasParametersSection()) { method.getParameterList().replace(block.getParameterList()); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java index 739c6a9818af..e70693ec3d03 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java @@ -101,14 +101,18 @@ public class CodeBlockGenerator extends Generator { public void generateMethodBody(GrMethod method) { final GrOpenBlock block = method.getBlock(); - boolean shouldInsertReturnNull = false; + boolean shouldInsertReturnNull; myExitPoints.clear(); PsiType returnType = context.typeProvider.getReturnType(method); if (!method.isConstructor() && returnType != PsiType.VOID) { myExitPoints.addAll(ControlFlowUtils.collectReturns(block)); - shouldInsertReturnNull = block != null && !(returnType instanceof PsiPrimitiveType) && - MissingReturnInspection.methodMissesSomeReturns(block, - MissingReturnInspection.ReturnStatus.getReturnStatus(method)); + shouldInsertReturnNull = block != null && + !(returnType instanceof PsiPrimitiveType) && + MissingReturnInspection.methodMissesSomeReturns(block, MissingReturnInspection.ReturnStatus.getReturnStatus( + method)); + } + else { + shouldInsertReturnNull = false; } if (block != null) { @@ -321,7 +325,7 @@ public class CodeBlockGenerator extends Generator { GenerationUtil.writeStatement(builder, context, expression, new StatementWriter() { @Override public void writeStatement(StringBuilder builder, ExpressionContext context) { - if (myExitPoints.contains(expression) && expression.getType() != PsiType.VOID) { + if (myExitPoints.contains(expression) && isRealExpression(expression)) { writeReturn(builder, context, expression); } else { @@ -329,6 +333,16 @@ public class CodeBlockGenerator extends Generator { builder.append(';'); } } + + private boolean isRealExpression(GrExpression expression) { + final PsiType type = expression.getType(); + + if (type == PsiType.VOID) return false; //statement + + if (type == PsiType.NULL) return !org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isVoidMethodCall(expression); + + return true; + } }); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeProvider.java index bd5406c2960c..55df1da0166e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeProvider.java @@ -25,6 +25,7 @@ import gnu.trove.TIntProcedure; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; @@ -55,7 +56,9 @@ public class TypeProvider { if (typeElement != null) return typeElement.getType(); } final PsiType smartReturnType = PsiUtil.getSmartReturnType(method); - if (smartReturnType != null) return smartReturnType; + if (smartReturnType != null && !PsiType.NULL.equals(smartReturnType)) return smartReturnType; + + if (PsiType.NULL.equals(smartReturnType) && PsiUtil.isVoidMethod(method)) return PsiType.VOID; //todo make smarter. search for usages and infer type from them return TypesUtil.getJavaLangObject(method); @@ -161,4 +164,18 @@ public class TypeProvider { inferredTypes.put(method, types); return types; } + + @NotNull + public PsiType getReturnType(GrClosableBlock closure) { + final PsiType returnType = closure.getReturnType(); + if (PsiType.NULL.equals(returnType) && PsiUtil.isBlockReturnVoid(closure)) { + return PsiType.VOID; + } + + if (returnType == null) { + return TypesUtil.getJavaLangObject(closure); + } + + return returnType; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeWriter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeWriter.java index 4f0aade83ea7..4080f2fb157f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeWriter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeWriter.java @@ -53,13 +53,13 @@ public class TypeWriter extends PsiTypeVisitor { @Nullable PsiType type, @NotNull final PsiElement context, @NotNull final ClassNameProvider classNameProvider) { - if (type instanceof PsiPrimitiveType) { - builder.append(type.getCanonicalText()); + if (type == null || PsiType.NULL.equals(type)) { + builder.append(CommonClassNames.JAVA_LANG_OBJECT); return; } - if (type == null) { - builder.append(CommonClassNames.JAVA_LANG_OBJECT); + if (type instanceof PsiPrimitiveType) { + builder.append(type.getCanonicalText()); return; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractUtil.java index 39090283024f..f111ead0119e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractUtil.java @@ -39,6 +39,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaratio import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; @@ -407,11 +408,11 @@ public class ExtractUtil { GrExpression expr = stringPartInfo != null ? GrIntroduceHandlerBase.generateExpressionFromStringPart(stringPartInfo, helper.getProject()) : (GrExpression)PsiUtil.skipParentheses(helper.getStatements()[0], false); - boolean addReturn = !isVoid && forceReturn; + boolean addReturn = !isVoid && forceReturn && !PsiUtil.isVoidMethodCall(expr); if (addReturn) { buffer.append("return "); - expr = ApplicationStatementUtil.convertToMethodCallExpression(expr); - buffer.append(expr.getText()); + final GrExpression methodCall = ApplicationStatementUtil.convertToMethodCallExpression(expr); + buffer.append(methodCall.getText()); } else { buffer.append(expr != null ? expr.getText() : ""); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrAssignabilityTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrAssignabilityTest.groovy index 0709db7b9a51..cb1e60e4180d 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrAssignabilityTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrAssignabilityTest.groovy @@ -368,7 +368,7 @@ def foo(Function function) { foo({println it.byteValue()} as Function) foo({println it.substring(1)} as Function) foo({println it.substring(1)} as Function) -foo({println it}) +foo({println it}) ''') } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy index 58f96b719d8f..b084562d738e 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy @@ -231,7 +231,7 @@ public class TypeInferenceTest extends GroovyResolveTestCase { final PsiReference ref = configureByFile(getTestName(true) + "/A.groovy"); assertInstanceOf(ref, GrReferenceExpression.class); final PsiType type = ((GrReferenceExpression)ref).type; - assertNull(type); + assertTrue(true); //test just should not fail with SOF exception } public void testTraditionalForVar() { diff --git a/plugins/groovy/testdata/groovy/refactoring/extractMethod/noContextConflicts.test b/plugins/groovy/testdata/groovy/refactoring/extractMethod/noContextConflicts.test index 23964f5dbf5d..6d59ee9b965c 100644 --- a/plugins/groovy/testdata/groovy/refactoring/extractMethod/noContextConflicts.test +++ b/plugins/groovy/testdata/groovy/refactoring/extractMethod/noContextConflicts.test @@ -19,8 +19,8 @@ class StringCategory { testMethod() } - private void testMethod() { - use(StringCategory) { + private testMethod() { + return use(StringCategory) { println "TeSt".lower() } } diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/closure.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/closure.java index 79aa62bfa71f..769c8bd97d8a 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/closure.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/closure.java @@ -1,5 +1,5 @@ java.util.ArrayList list = new java.util.ArrayList(java.util.Arrays.asList(1, 2, 3)); -org.codehaus.groovy.runtime.DefaultGroovyMethods.each(list, new groovy.lang.Closure(this, this) { +org.codehaus.groovy.runtime.DefaultGroovyMethods.each(list, new groovy.lang.Closure(this, this) { public void doCall(java.lang.Integer it) { print(it); } diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/closureInUse.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/closureInUse.java index 93ca27e57998..4812e82a0f02 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/closureInUse.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/closureInUse.java @@ -12,7 +12,7 @@ new closureInUse(new groovy.lang.Binding(args)).run(); public java.lang.Object run() { -return org.codehaus.groovy.runtime.DefaultGroovyMethods.use(this, IntCat.class, new groovy.lang.Closure(this, this) { +return org.codehaus.groovy.runtime.DefaultGroovyMethods.use(this, IntCat.class, new groovy.lang.Closure(this, this) { public void doCall(java.lang.Object it) { IntCat.call(2); IntCat.call(2, "a"); diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/hash.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/hash.java index 5b94cbc17f26..92d6fb761878 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/hash.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/hash.java @@ -42,7 +42,7 @@ final MessageDigest messageDigest = MessageDigest.getInstance("SHA1"); long start = java.lang.System.currentTimeMillis(); -org.codehaus.groovy.runtime.DefaultGroovyMethods.eachByte(f, MB, new groovy.lang.Closure(this, this) { +org.codehaus.groovy.runtime.DefaultGroovyMethods.eachByte(f, MB, new groovy.lang.Closure(this, this) { public void doCall(java.lang.Byte[] buf, int bytesRead) { messageDigest.update(buf, 0, bytesRead); } diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/refInClosureInScript.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/refInClosureInScript.java index 0c17a66c4ce0..3956feec017b 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/refInClosureInScript.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/refInClosureInScript.java @@ -6,7 +6,7 @@ new refInClosureInScript(new groovy.lang.Binding(args)).run(); public java.lang.Object run() { final groovy.lang.Reference foo = new groovy.lang.Reference(2); -org.codehaus.groovy.runtime.DefaultGroovyMethods.times(3, new groovy.lang.Closure(this, this) { +org.codehaus.groovy.runtime.DefaultGroovyMethods.times(3, new groovy.lang.Closure(this, this) { public void doCall(java.lang.Integer it) { foo.set(foo.get()++); foo.set(foo.get() + 2); diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml index 0ff8c82b1145..337fe0c5840f 100644 --- a/plugins/maven/src/main/resources/META-INF/plugin.xml +++ b/plugins/maven/src/main/resources/META-INF/plugin.xml @@ -437,9 +437,6 @@ icon="AllIcons.Nodes.ExceptionClass"> - - @@ -527,7 +524,6 @@ - diff --git a/resources/src/META-INF/PostfixTemplates.xml b/resources/src/META-INF/PostfixTemplates.xml index 355ab39e311a..8d3fe65877a0 100644 --- a/resources/src/META-INF/PostfixTemplates.xml +++ b/resources/src/META-INF/PostfixTemplates.xml @@ -12,7 +12,7 @@ - + diff --git a/xml/impl/src/com/intellij/ide/browsers/OpenFileInDefaultBrowserAction.java b/xml/impl/src/com/intellij/ide/browsers/OpenFileInDefaultBrowserAction.java index c1088bfa8a55..31e4c791d73c 100644 --- a/xml/impl/src/com/intellij/ide/browsers/OpenFileInDefaultBrowserAction.java +++ b/xml/impl/src/com/intellij/ide/browsers/OpenFileInDefaultBrowserAction.java @@ -177,7 +177,7 @@ public class OpenFileInDefaultBrowserAction extends DumbAwareAction { public PsiFile getFile() { if (file == null) { file = PsiManager.getInstance(getProject()).findFile(virtualFile); - LOG.assertTrue(file != null); + LOG.assertTrue(file != null, virtualFile.getPath()); } return file; } diff --git a/xml/openapi/src/com/intellij/ide/browsers/OpenInBrowserRequest.java b/xml/openapi/src/com/intellij/ide/browsers/OpenInBrowserRequest.java index 1a186ae8faa6..10d84ccf05cd 100644 --- a/xml/openapi/src/com/intellij/ide/browsers/OpenInBrowserRequest.java +++ b/xml/openapi/src/com/intellij/ide/browsers/OpenInBrowserRequest.java @@ -23,8 +23,8 @@ public abstract class OpenInBrowserRequest { @Nullable public static OpenInBrowserRequest create(@NotNull final PsiElement element) { - PsiFile psiFile = element.getContainingFile(); - if (psiFile == null) { + PsiFile psiFile = element.isValid() ? element.getContainingFile() : null; + if (psiFile == null || psiFile.getVirtualFile() == null) { return null; }