Merge branch 'master' of git.labs.intellij.net:idea/community
authorDmitry Jemerov <yole@jetbrains.com>
Fri, 12 Nov 2010 09:22:57 +0000 (12:22 +0300)
committerDmitry Jemerov <yole@jetbrains.com>
Fri, 12 Nov 2010 09:22:57 +0000 (12:22 +0300)
138 files changed:
java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactLoadingErrorDescription.java [new file with mode: 0644]
java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java
java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactModelBase.java
java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifact.java [new file with mode: 0644]
java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifactType.java [new file with mode: 0644]
java/compiler/impl/src/com/intellij/packaging/impl/artifacts/UnknownPackagingElementTypeException.java [new file with mode: 0644]
java/compiler/impl/src/com/intellij/packaging/impl/elements/ManifestFileUtil.java
java/compiler/impl/src/com/intellij/packaging/impl/elements/PackagingElementFactoryImpl.java
java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactModel.java
java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsImpl.java
java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java
java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/EditClassFiltersDialog.java
java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java
java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java
java/debugger/impl/src/com/intellij/debugger/ui/impl/UpdatableDebuggerView.java
java/execution/impl/src/com/intellij/execution/ui/ClassBrowser.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurable.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurableBase.java [new file with mode: 0644]
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/InvalidArtifactComponent.form [new file with mode: 0644]
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/InvalidArtifactConfigurable.java [new file with mode: 0644]
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java
java/java-impl/java-impl.iml
java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaAwareCompletionData.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaGlobalMemberNameCompletionContributor.java
java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
java/java-impl/src/com/intellij/ide/util/TreeClassChooserFactoryImpl.java
java/java-impl/src/com/intellij/ide/util/TreeJavaClassChooserDialog.java [new file with mode: 0644]
java/java-impl/src/com/intellij/ide/util/scopeChooser/ClassHierarchyScopeDescriptor.java
java/java-impl/src/com/intellij/lang/java/parser/DeclarationParser.java
java/java-impl/src/com/intellij/lang/java/parser/ExpressionParser.java
java/java-impl/src/com/intellij/lang/java/parser/FileParser.java
java/java-impl/src/com/intellij/lang/java/parser/ReferenceParser.java
java/java-impl/src/com/intellij/psi/impl/compiled/ClsClassImpl.java
java/java-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java
java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java
java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java
java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java
java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java
java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java
java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderDialog.java
java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java
java/java-impl/src/com/intellij/refactoring/ui/ClassNameReferenceEditor.java
java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueDialog.java
java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java
java/java-impl/src/com/intellij/util/xml/ui/PsiClassControl.java
java/java-impl/src/com/intellij/util/xml/ui/PsiClassTableCellEditor.java
java/java-tests/testData/codeInsight/completion/normal/FinalInForLoop.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/completion/normal/SpaceAfterReturn.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/completion/normal/SpaceAfterReturn_after.java [new file with mode: 0644]
java/java-tests/testData/psi/parser-partial/expressions/New15.txt [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
java/java-tests/testSrc/com/intellij/lang/java/parser/partial/ExpressionParserTest.java
java/java-tests/testSrc/com/intellij/lang/java/parser/partial/ReferenceParserTest.java
java/openapi/src/com/intellij/ide/util/ClassFilter.java [new file with mode: 0644]
java/openapi/src/com/intellij/ide/util/TreeClassChooser.java
java/openapi/src/com/intellij/ide/util/TreeClassChooserFactory.java
java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditor.java
java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditorAddDialog.java
java/openapi/src/com/intellij/util/xml/actions/CreateClassMappingAction.java
platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java
platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java
platform/lang-impl/src/com/intellij/codeInsight/completion/WordCompletionContributor.java
platform/lang-impl/src/com/intellij/codeInsight/documentation/actions/ShowJavaDocInfoAction.java
platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java
platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java
platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java
platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectTreeBuilder.java
platform/lang-impl/src/com/intellij/ide/util/AbstractTreeClassChooserDialog.java [moved from java/java-impl/src/com/intellij/ide/util/TreeClassChooserDialog.java with 57% similarity]
platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java
platform/lang-impl/src/com/intellij/psi/impl/cache/impl/IndexCacheManagerImpl.java
platform/lang-impl/src/com/intellij/psi/impl/source/text/ASTDiffBuilder.java
platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java
platform/platform-api/src/com/intellij/ide/plugins/PluginManager.java
platform/platform-impl/src/com/intellij/ide/util/TreeChooser.java [new file with mode: 0644]
platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/IterationState.java
platform/platform-resources-en/src/messages/IdeBundle.properties
platform/util/src/com/intellij/openapi/util/JDOMUtil.java
platform/util/src/com/intellij/openapi/util/io/FileUtil.java
plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties
plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java
plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/SynchronizationUtil.java
plugins/InspectionGadgets/src/com/siyeh/ig/threading/ArithmeticOnVolatileFieldInspection.java [deleted file]
plugins/InspectionGadgets/src/com/siyeh/ig/threading/NonAtomicOperationOnVolatileFieldInspection.java [new file with mode: 0644]
plugins/InspectionGadgets/src/com/siyeh/ig/ui/TreeClassChooserAction.java
plugins/InspectionGadgets/src/com/siyeh/ig/ui/UiUtils.java
plugins/InspectionGadgets/src/inspectionDescriptions/ArithmeticOnVolatileField.html [deleted file]
plugins/InspectionGadgets/src/inspectionDescriptions/NonAtomicOperationOnVolatileField.html [new file with mode: 0644]
plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/AdvancedSettingsUI.java
plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.java
plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java
plugins/android/resources/messages/AndroidBundle.properties
plugins/android/src/org/jetbrains/android/compiler/AndroidAptCompiler.java
plugins/android/src/org/jetbrains/android/compiler/AndroidPackagingCompiler.java
plugins/android/src/org/jetbrains/android/compiler/AndroidResourcesPackagingCompiler.java
plugins/android/src/org/jetbrains/android/compiler/ResourcesValidityState.java
plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java
plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.form
plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java
plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java
plugins/android/src/org/jetbrains/android/run/AndroidClassBrowser.java
plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationBase.java
plugins/android/src/org/jetbrains/android/run/AndroidRunningState.java
plugins/android/src/org/jetbrains/android/run/ApplicationRunParameters.java
plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java
plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java
plugins/github/src/org/jetbrains/plugins/github/ui/GitHubSettingsConfigurable.java
plugins/github/src/org/jetbrains/plugins/github/ui/GithubCloneProjectPane.form
plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginDialog.java
plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.form
plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.java
plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form [new file with mode: 0644]
plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java [new file with mode: 0644]
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/javaToGrovyRename/RenameJavaFileToGroovyFileAction.java
plugins/java-i18n/src/com/intellij/codeInspection/i18n/I18nInspection.java
plugins/junit/src/com/intellij/execution/junit/TestClassFilter.java
plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java
plugins/maven/src/main/resources/ProjectBundle.properties
plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java
plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.java
plugins/testng/src/com/theoryinpractice/testng/configuration/browser/TestClassBrowser.java
plugins/testng/src/com/theoryinpractice/testng/model/TestClassFilter.java
plugins/testng/src/com/theoryinpractice/testng/model/TestListenerFilter.java
plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItemDialog.java
plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/properties/ClassToBindProperty.java
plugins/ui-designer/src/com/intellij/uiDesigner/wizard/BeanStep.java
resources-en/src/messages/EvaluationFeedbackRequest.html
resources/src/META-INF/IdeaPlugin.xml

index fd5d00d45ee7a151752dfb4ba15988640c30b16f..6e6bd91022791ebd218871c853c2121adacfcd49 100644 (file)
@@ -115,7 +115,7 @@ public class CompileDriver {
 
   private static final boolean GENERATE_CLASSPATH_INDEX = "true".equals(System.getProperty("generate.classpath.index"));
   private static final String PROP_PERFORM_INITIAL_REFRESH = "compiler.perform.outputs.refresh.on.start";
-  private boolean myInitialRefreshPerformed = false;
+  private static final Key<Boolean> REFRESH_DONE_KEY = Key.create("_compiler.initial.refresh.done_");
 
   private static final FileProcessingCompilerAdapterFactory FILE_PROCESSING_COMPILER_ADAPTER_FACTORY = new FileProcessingCompilerAdapterFactory() {
     public FileProcessingCompilerAdapter create(CompileContext context, FileProcessingCompiler compiler) {
@@ -663,8 +663,8 @@ public class CompileDriver {
       }
 
       boolean needRecalcOutputDirs = false;
-      if (Registry.is(PROP_PERFORM_INITIAL_REFRESH) || !myInitialRefreshPerformed) {
-        myInitialRefreshPerformed = true;
+      if (Registry.is(PROP_PERFORM_INITIAL_REFRESH) || !Boolean.valueOf(REFRESH_DONE_KEY.get(myProject, Boolean.FALSE))) {
+        REFRESH_DONE_KEY.set(myProject, Boolean.TRUE);
         final long refreshStart = System.currentTimeMillis();
 
         //need this to make sure the VFS is built
index f4abe40f4b9d0aaeac5da295b40a9efd4dfc8e02..5c7be0535dcad39bf4305b7025a478e65c3e81fd 100644 (file)
@@ -37,10 +37,7 @@ import com.intellij.openapi.project.ProjectManager;
 import com.intellij.openapi.project.ProjectManagerAdapter;
 import com.intellij.openapi.roots.*;
 import com.intellij.openapi.startup.StartupManager;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.Trinity;
+import com.intellij.openapi.util.*;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.vfs.*;
 import com.intellij.openapi.vfs.newvfs.FileAttribute;
@@ -389,7 +386,7 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
   }
 
   public void updateOutputRootsLayout(Project project) {
-    final TIntObjectHashMap<Pair<Integer, Integer>> map = buildOutputRootsLayout(project);
+    final TIntObjectHashMap<Pair<Integer, Integer>> map = buildOutputRootsLayout(new ProjectRef(project));
     synchronized (myProjectOutputRoots) {
       myProjectOutputRoots.put(getProjectId(project), map);
     }
@@ -467,9 +464,9 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
     }
   }
 
-  private TIntObjectHashMap<Pair<Integer, Integer>> buildOutputRootsLayout(Project project) {
+  private TIntObjectHashMap<Pair<Integer, Integer>> buildOutputRootsLayout(ProjectRef projRef) {
     final TIntObjectHashMap<Pair<Integer, Integer>> map = new TIntObjectHashMap<Pair<Integer, Integer>>();
-    for (Module module : ModuleManager.getInstance(project).getModules()) {
+    for (Module module : ModuleManager.getInstance(projRef.get()).getModules()) {
       final CompilerModuleExtension manager = CompilerModuleExtension.getInstance(module);
       if (manager != null) {
         final VirtualFile output = manager.getCompilerOutputPath();
@@ -905,17 +902,18 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
   }
 
   // made public for tests
-  public void scanSourceContent(final Project project, final Collection<VirtualFile> roots, final int totalRootCount, final boolean isNewRoots) {
+  public void scanSourceContent(final ProjectRef projRef, final Collection<VirtualFile> roots, final int totalRootCount, final boolean isNewRoots) {
     if (roots.size() == 0) {
       return;
     }
-    final int projectId = getProjectId(project);
+    final int projectId = getProjectId(projRef.get());
 
-    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
+    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(projRef.get()).getFileIndex();
     final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
     int processed = 0;
     for (VirtualFile srcRoot : roots) {
       if (indicator != null) {
+        projRef.get();
         indicator.setText2(srcRoot.getPresentableUrl());
         indicator.setFraction(++processed / (double)totalRootCount);
       }
@@ -930,6 +928,9 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
                 }
               }
             }
+            else {
+              projRef.get();
+            }
             return true;
           }
         });
@@ -944,6 +945,7 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
             final int fileId = getFileId(file);
             if (fileId > 0 /*file is valid*/) {
               if (file.isDirectory()) {
+                projRef.get();
                 for (VirtualFile child : file.getChildren()) {
                   processFile(child);
                 }
@@ -981,8 +983,8 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
     }
   }
 
-  private void markOldOutputRoots(final Project project, final TIntObjectHashMap<Pair<Integer, Integer>> currentLayout) {
-    final int projectId = getProjectId(project);
+  private void markOldOutputRoots(final ProjectRef projRef, final TIntObjectHashMap<Pair<Integer, Integer>> currentLayout) {
+    final int projectId = getProjectId(projRef.get());
 
     final TIntHashSet rootsToMark = new TIntHashSet();
     synchronized (myProjectOutputRoots) {
@@ -1043,16 +1045,14 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
       public void run() {
         new Task.Backgroundable(project, CompilerBundle.message("compiler.initial.scanning.progress.text"), false) {
           public void run(@NotNull final ProgressIndicator indicator) {
+            final ProjectRef projRef = new ProjectRef(project);
             try {
-              if (project.isDisposed()) {
-                return;
-              }
               final IntermediateOutputCompiler[] compilers =
-                  CompilerManager.getInstance(project).getCompilers(IntermediateOutputCompiler.class);
+                  CompilerManager.getInstance(projRef.get()).getCompilers(IntermediateOutputCompiler.class);
 
               final Set<VirtualFile> intermediateRoots = new HashSet<VirtualFile>();
               if (compilers.length > 0) {
-                final Module[] modules = ModuleManager.getInstance(project).getModules();
+                final Module[] modules = ModuleManager.getInstance(projRef.get()).getModules();
                 for (IntermediateOutputCompiler compiler : compilers) {
                   for (Module module : modules) {
                     if (module.isDisposed()) {
@@ -1070,9 +1070,9 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
                 }
               }
 
-              final List<VirtualFile> projectRoots = Arrays.asList(ProjectRootManager.getInstance(project).getContentSourceRoots());
+              final List<VirtualFile> projectRoots = Arrays.asList(ProjectRootManager.getInstance(projRef.get()).getContentSourceRoots());
               final int totalRootsCount = projectRoots.size() + intermediateRoots.size();
-              scanSourceContent(project, projectRoots, totalRootsCount, true);
+              scanSourceContent(projRef, projectRoots, totalRootsCount, true);
 
               if (!intermediateRoots.isEmpty()) {
                 final FileProcessor processor = new FileProcessor() {
@@ -1087,13 +1087,16 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
                 };
                 int processed = projectRoots.size();
                 for (VirtualFile root : intermediateRoots) {
+                  projRef.get();
                   indicator.setText2(root.getPresentableUrl());
                   indicator.setFraction(++processed / (double)totalRootsCount);
                   processRecursively(root, false, processor);
                 }
               }
-
-              markOldOutputRoots(project, buildOutputRootsLayout(project));
+              
+              markOldOutputRoots(projRef, buildOutputRootsLayout(projRef));
+            }
+            catch (ProjectRef.ProjectClosedException swallowed) {
             }
             finally {
               synchronized (myInitializationLock) {
@@ -1108,7 +1111,6 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
     });
   }
   
-
   private class MyProjectManagerListener extends ProjectManagerAdapter {
 
     final Map<Project, MessageBusConnection> myConnections = new HashMap<Project, MessageBusConnection>();
@@ -1116,39 +1118,54 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
     public void projectOpened(final Project project) {
       final MessageBusConnection conn = project.getMessageBus().connect();
       myConnections.put(project, conn);
+      final ProjectRef projRef = new ProjectRef(project);
       conn.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
         private VirtualFile[] myRootsBefore;
 
         public void beforeRootsChange(final ModuleRootEvent event) {
-          myRootsBefore = ProjectRootManager.getInstance(project).getContentSourceRoots();
+          try {
+            myRootsBefore = ProjectRootManager.getInstance(projRef.get()).getContentSourceRoots();
+          }
+          catch (ProjectRef.ProjectClosedException e) {
+            myRootsBefore = null;
+          }
         }
 
         public void rootsChanged(final ModuleRootEvent event) {
-          final VirtualFile[] rootsAfter = ProjectRootManager.getInstance(project).getContentSourceRoots();
-
-          {
-            final Set<VirtualFile> newRoots = new HashSet<VirtualFile>();
-            ContainerUtil.addAll(newRoots, rootsAfter);
-            if (myRootsBefore != null) {
-              newRoots.removeAll(Arrays.asList(myRootsBefore));
-            }
-            scanSourceContent(project, newRoots, newRoots.size(), true);
-          }
-
-          {
-            final Set<VirtualFile> oldRoots = new HashSet<VirtualFile>();
-            if (myRootsBefore != null) {
-              ContainerUtil.addAll(oldRoots, myRootsBefore);
+          try {
+            try {
+              final VirtualFile[] rootsAfter = ProjectRootManager.getInstance(projRef.get()).getContentSourceRoots();
+  
+              {
+                final Set<VirtualFile> newRoots = new HashSet<VirtualFile>();
+                ContainerUtil.addAll(newRoots, rootsAfter);
+                if (myRootsBefore != null) {
+                  newRoots.removeAll(Arrays.asList(myRootsBefore));
+                }
+                scanSourceContent(projRef, newRoots, newRoots.size(), true);
+              }
+  
+              {
+                final Set<VirtualFile> oldRoots = new HashSet<VirtualFile>();
+                if (myRootsBefore != null) {
+                  ContainerUtil.addAll(oldRoots, myRootsBefore);
+                }
+                if (!oldRoots.isEmpty()) {
+                  oldRoots.removeAll(Arrays.asList(rootsAfter));
+                }
+                scanSourceContent(projRef, oldRoots, oldRoots.size(), false);
+              }
             }
-            if (!oldRoots.isEmpty()) {
-              oldRoots.removeAll(Arrays.asList(rootsAfter));
+            finally {
+              myRootsBefore = null;
             }
-            scanSourceContent(project, oldRoots, oldRoots.size(), false);
-          }
 
-          myRootsBefore = null;
 
-          markOldOutputRoots(project, buildOutputRootsLayout(project));
+            markOldOutputRoots(projRef, buildOutputRootsLayout(projRef));
+          }
+          catch (ProjectRef.ProjectClosedException e) {
+            LOG.info(e);
+          }
         }
       });
 
@@ -1465,4 +1482,24 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
     }
   }
 
+  public static final class ProjectRef extends Ref<Project> {
+    static class ProjectClosedException extends RuntimeException {
+    }
+
+    public ProjectRef() {
+    }
+
+    public ProjectRef(Project project) {
+      super(project);
+    }
+
+    public Project get() {
+      final Project project = super.get();
+      if (project != null && project.isDisposed()) {
+        throw new ProjectClosedException();
+      }
+      return project;
+    }
+  }
+  
 }
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactLoadingErrorDescription.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactLoadingErrorDescription.java
new file mode 100644 (file)
index 0000000..5ca3007
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.artifacts;
+
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.module.ConfigurationErrorDescription;
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.artifacts.ModifiableArtifactModel;
+
+/**
+ * @author nik
+ */
+public class ArtifactLoadingErrorDescription extends ConfigurationErrorDescription {
+  private final Project myProject;
+  private final InvalidArtifact myArtifact;
+
+  public ArtifactLoadingErrorDescription(Project project, InvalidArtifact artifact) {
+    super(artifact.getName(), "artifact", artifact.getErrorMessage());
+    myProject = project;
+    myArtifact = artifact;
+  }
+
+  @Override
+  public void removeInvalidElement() {
+    final ModifiableArtifactModel model = ArtifactManager.getInstance(myProject).createModifiableModel();
+    model.removeArtifact(myArtifact);
+    new WriteAction() {
+      protected void run(final Result result) {
+        model.commit();
+      }
+    }.execute();
+  }
+
+  @Override
+  public String getRemoveConfirmationMessage() {
+    return "Would you like to remove artifact '" + myArtifact.getName() + "?";
+  }
+
+  @Override
+  public boolean isValid() {
+    return ArtifactManager.getInstance(myProject).getAllArtifactsIncludingInvalid().contains(myArtifact);
+  }
+}
index 6b6d04c3eed6928da859a386cc2103c86517be33..d02cbcf99906b93b0b459560dc046a506a5ebc12 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.Result;
 import com.intellij.openapi.application.WriteAction;
 import com.intellij.openapi.components.*;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.ProjectLoadingErrorsNotifier;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
 import com.intellij.openapi.util.ModificationTracker;
@@ -97,26 +98,37 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo
     return myModel.getArtifactsByType(type);
   }
 
+  @Override
+  public List<? extends Artifact> getAllArtifactsIncludingInvalid() {
+    return myModel.getAllArtifactsIncludingInvalid();
+  }
+
   public ArtifactManagerState getState() {
     final ArtifactManagerState state = new ArtifactManagerState();
-    for (Artifact artifact : getArtifacts()) {
-      final ArtifactState artifactState = new ArtifactState();
-      artifactState.setBuildOnMake(artifact.isBuildOnMake());
-      artifactState.setName(artifact.getName());
-      artifactState.setOutputPath(artifact.getOutputPath());
-      artifactState.setRootElement(serializePackagingElement(artifact.getRootElement()));
-      artifactState.setArtifactType(artifact.getArtifactType().getId());
-      for (ArtifactPropertiesProvider provider : artifact.getPropertiesProviders()) {
-        final ArtifactPropertiesState propertiesState = serializeProperties(provider, artifact.getProperties(provider));
-        if (propertiesState != null) {
-          artifactState.getPropertiesList().add(propertiesState);
-        }
+    for (Artifact artifact : getAllArtifactsIncludingInvalid()) {
+      final ArtifactState artifactState;
+      if (artifact instanceof InvalidArtifact) {
+        artifactState = ((InvalidArtifact)artifact).getState();
       }
-      Collections.sort(artifactState.getPropertiesList(), new Comparator<ArtifactPropertiesState>() {
-        public int compare(ArtifactPropertiesState o1, ArtifactPropertiesState o2) {
-          return o1.getId().compareTo(o2.getId());
+      else {
+        artifactState = new ArtifactState();
+        artifactState.setBuildOnMake(artifact.isBuildOnMake());
+        artifactState.setName(artifact.getName());
+        artifactState.setOutputPath(artifact.getOutputPath());
+        artifactState.setRootElement(serializePackagingElement(artifact.getRootElement()));
+        artifactState.setArtifactType(artifact.getArtifactType().getId());
+        for (ArtifactPropertiesProvider provider : artifact.getPropertiesProviders()) {
+          final ArtifactPropertiesState propertiesState = serializeProperties(provider, artifact.getProperties(provider));
+          if (propertiesState != null) {
+            artifactState.getPropertiesList().add(propertiesState);
+          }
         }
-      });
+        Collections.sort(artifactState.getPropertiesList(), new Comparator<ArtifactPropertiesState>() {
+          public int compare(ArtifactPropertiesState o1, ArtifactPropertiesState o2) {
+            return o1.getId().compareTo(o2.getId());
+          }
+        });
+      }
       state.getArtifacts().add(artifactState);
     }
     return state;
@@ -148,9 +160,13 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo
     return element;
   }
 
-  private <T> PackagingElement<T> deserializeElement(Element element) {
+  private <T> PackagingElement<T> deserializeElement(Element element) throws UnknownPackagingElementTypeException {
     final String id = element.getAttributeValue(TYPE_ID_ATTRIBUTE);
     PackagingElementType<?> type = PackagingElementFactory.getInstance().findElementType(id);
+    if (type == null) {
+      throw new UnknownPackagingElementTypeException(id);
+    }
+
     PackagingElement<T> packagingElement = (PackagingElement<T>)type.createEmpty(myProject);
     T state = packagingElement.getState();
     if (state != null) {
@@ -168,31 +184,7 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo
   public void loadState(ArtifactManagerState managerState) {
     final List<ArtifactImpl> artifacts = new ArrayList<ArtifactImpl>();
     for (ArtifactState state : managerState.getArtifacts()) {
-      final Element element = state.getRootElement();
-      ArtifactType type = ArtifactType.findById(state.getArtifactType());
-      if (type == null) {
-        LOG.info("Unknown artifact type: " + state.getArtifactType());
-        continue;
-      }
-
-      final String artifactName = state.getName();
-      final CompositePackagingElement<?> rootElement;
-      if (element != null) {
-        rootElement = (CompositePackagingElement<?>)deserializeElement(element);
-      }
-      else {
-        rootElement = type.createRootElement(artifactName);
-      }
-
-      final ArtifactImpl artifact = new ArtifactImpl(artifactName, type, state.isBuildOnMake(), rootElement, state.getOutputPath());
-      final List<ArtifactPropertiesState> propertiesList = state.getPropertiesList();
-      for (ArtifactPropertiesState propertiesState : propertiesList) {
-        final ArtifactPropertiesProvider provider = ArtifactPropertiesProvider.findById(propertiesState.getId());
-        if (provider != null) {
-          deserializeProperties(artifact.getProperties(provider), propertiesState);
-        }
-      }
-      artifacts.add(artifact);
+      artifacts.add(loadArtifact(state));
     }
 
     if (myLoaded) {
@@ -205,6 +197,47 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo
     }
   }
 
+  private ArtifactImpl loadArtifact(ArtifactState state) {
+    ArtifactType type = ArtifactType.findById(state.getArtifactType());
+    if (type == null) {
+      return createInvalidArtifact(state, "Unknown artifact type: " + state.getArtifactType());
+    }
+
+    final Element element = state.getRootElement();
+    final String artifactName = state.getName();
+    final CompositePackagingElement<?> rootElement;
+    if (element != null) {
+      try {
+        rootElement = (CompositePackagingElement<?>)deserializeElement(element);
+      }
+      catch (UnknownPackagingElementTypeException e) {
+        return createInvalidArtifact(state, "Unknown element: " + e.getTypeId());
+      }
+    }
+    else {
+      rootElement = type.createRootElement(artifactName);
+    }
+
+    final ArtifactImpl artifact = new ArtifactImpl(artifactName, type, state.isBuildOnMake(), rootElement, state.getOutputPath());
+    final List<ArtifactPropertiesState> propertiesList = state.getPropertiesList();
+    for (ArtifactPropertiesState propertiesState : propertiesList) {
+      final ArtifactPropertiesProvider provider = ArtifactPropertiesProvider.findById(propertiesState.getId());
+      if (provider != null) {
+        deserializeProperties(artifact.getProperties(provider), propertiesState);
+      }
+      else {
+        return createInvalidArtifact(state, "Unknown artifact properties: " + propertiesState.getId());
+      }
+    }
+    return artifact;
+  }
+
+  private InvalidArtifact createInvalidArtifact(ArtifactState state, String errorMessage) {
+    final InvalidArtifact artifact = new InvalidArtifact(state, errorMessage);
+    ProjectLoadingErrorsNotifier.getInstance(myProject).registerError(new ArtifactLoadingErrorDescription(myProject, artifact));
+    return artifact;
+  }
+
   private static <S> void deserializeProperties(ArtifactProperties<S> artifactProperties, ArtifactPropertiesState propertiesState) {
     final Element options = propertiesState.getOptions();
     if (artifactProperties == null || options == null) {
index ee67d33edb5ecad3d1173d34d92999fd67a27d5f..9dbfa2a493fa7b76ee872e635f6b68d0403dd738 100644 (file)
  */
 package com.intellij.packaging.impl.artifacts;
 
+import com.intellij.openapi.util.Condition;
 import com.intellij.packaging.artifacts.Artifact;
 import com.intellij.packaging.artifacts.ArtifactModel;
 import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.*;
@@ -28,18 +30,29 @@ import java.util.*;
 public abstract class ArtifactModelBase implements ArtifactModel {
   private Map<String, Artifact> myArtifactsMap;
   private Artifact[] myArtifactsArray;
+  public static final Condition<Artifact> VALID_ARTIFACT_CONDITION = new Condition<Artifact>() {
+    @Override
+    public boolean value(Artifact artifact) {
+      return !(artifact instanceof InvalidArtifact);
+    }
+  };
 
   protected abstract List<? extends Artifact> getArtifactsList();
 
   @NotNull
   public Artifact[] getArtifacts() {
     if (myArtifactsArray == null) {
-      final List<? extends Artifact> artifacts = getArtifactsList();
-      myArtifactsArray = artifacts.toArray(new Artifact[artifacts.size()]);
+      final List<? extends Artifact> validArtifacts = ContainerUtil.findAll(getArtifactsList(), VALID_ARTIFACT_CONDITION);
+      myArtifactsArray = validArtifacts.toArray(new Artifact[validArtifacts.size()]);
     }
     return myArtifactsArray;
   }
 
+  @Override
+  public List<? extends Artifact> getAllArtifactsIncludingInvalid() {
+    return Collections.unmodifiableList(getArtifactsList());
+  }
+
   public Artifact findArtifact(@NotNull String name) {
     if (myArtifactsMap == null) {
       myArtifactsMap = new HashMap<String, Artifact>();
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifact.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifact.java
new file mode 100644 (file)
index 0000000..6f25a28
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.artifacts;
+
+import com.intellij.packaging.elements.PackagingElementFactory;
+
+/**
+ * @author nik
+ */
+public class InvalidArtifact extends ArtifactImpl {
+  private ArtifactState myState;
+  private final String myErrorMessage;
+
+  public InvalidArtifact(ArtifactState state, String errorMessage) {
+    super(state.getName(), InvalidArtifactType.getInstance(), false, PackagingElementFactory.getInstance().createArtifactRootElement(), "");
+    myState = state;
+    myErrorMessage = errorMessage;
+  }
+
+  public String getErrorMessage() {
+    return myErrorMessage;
+  }
+
+  public ArtifactState getState() {
+    return myState;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifactType.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifactType.java
new file mode 100644 (file)
index 0000000..ef483f9
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.artifacts;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.util.IconLoader;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElementFactory;
+import com.intellij.packaging.elements.PackagingElementOutputKind;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * @author nik
+ */
+public class InvalidArtifactType extends ArtifactType {
+  public static final Icon ICON = IconLoader.getIcon("/fileTypes/unknown.png");
+
+  public static InvalidArtifactType getInstance() {
+    return ServiceManager.getService(InvalidArtifactType.class);
+  }
+
+  public InvalidArtifactType() {
+    super("invalid", "Invalid");
+  }
+
+  @NotNull
+  @Override
+  public Icon getIcon() {
+    return ICON;
+  }
+
+  @Override
+  public String getDefaultPathFor(@NotNull PackagingElementOutputKind kind) {
+    return "";
+  }
+
+  @NotNull
+  @Override
+  public CompositePackagingElement<?> createRootElement(@NotNull String artifactName) {
+    return PackagingElementFactory.getInstance().createArtifactRootElement();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/UnknownPackagingElementTypeException.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/UnknownPackagingElementTypeException.java
new file mode 100644 (file)
index 0000000..9856fec
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.artifacts;
+
+/**
+ * @author nik
+ */
+class UnknownPackagingElementTypeException extends Exception {
+  private final String myTypeId;
+
+  public UnknownPackagingElementTypeException(String typeId) {
+    myTypeId = typeId;
+  }
+
+  public String getTypeId() {
+    return myTypeId;
+  }
+}
index 392d58aa7e8dbdf6b61e711e7f6fec8e3c7b67ab..4700cab2d0c9acb9ee1569c4630bfb027af08591 100644 (file)
@@ -16,6 +16,7 @@
 package com.intellij.packaging.impl.elements;
 
 import com.intellij.CommonBundle;
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
 import com.intellij.openapi.application.ApplicationManager;
@@ -332,7 +333,7 @@ public class ManifestFileUtil {
     final TreeClassChooser chooser =
         chooserFactory.createWithInnerClassesScopeChooser("Select Main Class", searchScope, new MainClassFilter(), aClass);
     chooser.showDialog();
-    return chooser.getSelectedClass();
+    return chooser.getSelected();
   }
 
   public static void setupMainClassField(final Project project, final TextFieldWithBrowseButton field) {
@@ -346,7 +347,7 @@ public class ManifestFileUtil {
     });
   }
 
-  private static class MainClassFilter implements TreeClassChooser.ClassFilter {
+  private static class MainClassFilter implements ClassFilter {
     public boolean isAccepted(PsiClass aClass) {
       return PsiMethodUtil.MAIN_CLASS.value(aClass) && PsiMethodUtil.hasMainMethod(aClass);
     }
index 7ec062a7101a6350d424cb304367b0179b0dc2c4..1fadf9c7b11b97f770b00b0420f0f0feb870bede 100644 (file)
@@ -108,7 +108,7 @@ public class PackagingElementFactoryImpl extends PackagingElementFactory {
     if (id.equals(ARTIFACT_ROOT_ELEMENT_TYPE.getId())) {
       return ARTIFACT_ROOT_ELEMENT_TYPE;
     }
-    throw new AssertionError(id + " not registered");
+    return null;
   }
 
   @NotNull
index 1a11ecbb4c67c0fa5e420cc752999a8888b81754..91f3ae71c6ef805050d728c4f98e3546ca46a645 100644 (file)
@@ -19,6 +19,7 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Collection;
+import java.util.List;
 
 /**
  * @author nik
@@ -37,4 +38,6 @@ public interface ArtifactModel {
   Artifact getOriginalArtifact(@NotNull Artifact artifact);
 
   Collection<? extends Artifact> getArtifactsByType(@NotNull ArtifactType type);
+
+  List<? extends Artifact> getAllArtifactsIncludingInvalid();
 }
index cedea6fe98f00d7233e78be5d98afead12e2a7a6..2a3feb95cfe3ac347f2fdb1ab09c3a8ed177ac0e 100644 (file)
@@ -114,7 +114,7 @@ public class DebuggerUtilsImpl extends DebuggerUtilsEx{
   public PsiClass chooseClassDialog(String title, Project project) {
     TreeClassChooser dialog = TreeClassChooserFactory.getInstance(project).createAllProjectScopeChooser(title);
     dialog.showDialog();
-    return dialog.getSelectedClass();
+    return dialog.getSelected();
   }
 
   public CompletionEditor createEditor(Project project, PsiElement context, String recentsId) {
index 783016dd95988555191958cf30df1528e4eb940b..f325da10fcde02076c3ef827fd7a7dcf62fa6716 100644 (file)
@@ -75,7 +75,7 @@ abstract class AddFieldBreakpointDialog extends DialogWrapper {
           }
         }
         chooser.showDialog();
-        PsiClass selectedClass = chooser.getSelectedClass();
+        PsiClass selectedClass = chooser.getSelected();
         if (selectedClass != null) {
           myClassChooser.setText(selectedClass.getQualifiedName());
         }
index 1be01b72654d637dee4f914bba758d79d6ed4b78..48527a7e4c766229b6a1e3ce6779dbb815a8a972 100644 (file)
@@ -30,7 +30,7 @@ import com.intellij.debugger.settings.DebuggerSettings;
 import com.intellij.debugger.ui.CompletionEditor;
 import com.intellij.debugger.ui.DebuggerExpressionComboBox;
 import com.intellij.debugger.ui.DebuggerStatementEditor;
-import com.intellij.ide.util.TreeClassChooser;
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.ComboBox;
 import com.intellij.openapi.ui.DialogWrapper;
@@ -40,7 +40,6 @@ import com.intellij.psi.PsiClass;
 import com.intellij.psi.PsiElement;
 import com.intellij.ui.FieldPanel;
 import com.intellij.ui.MultiLineTooltipUI;
-import com.intellij.ui.classFilter.ClassFilter;
 import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
@@ -63,8 +62,8 @@ public abstract class BreakpointPropertiesPanel {
   private final FieldPanel myInstanceFiltersField;
 
   private final FieldPanel myClassFiltersField;
-  private ClassFilter[] myClassFilters;
-  private ClassFilter[] myClassExclusionFilters;
+  private com.intellij.ui.classFilter.ClassFilter[] myClassFilters;
+  private com.intellij.ui.classFilter.ClassFilter[] myClassExclusionFilters;
   private InstanceFilter[] myInstanceFilters;
 
   private JCheckBox myLogExpressionCheckBox;
@@ -221,7 +220,7 @@ public abstract class BreakpointPropertiesPanel {
       public void actionPerformed(ActionEvent e) {
         reloadClassFilters();
 
-        TreeClassChooser.ClassFilter classFilter;
+        ClassFilter classFilter;
         classFilter = createClassConditionFilter();
 
         EditClassFiltersDialog _dialog = new EditClassFiltersDialog(myProject, classFilter);
@@ -298,10 +297,10 @@ public abstract class BreakpointPropertiesPanel {
     mySuspendNoneRadio.setFont(DebuggerSettings.SUSPEND_NONE.equals(defPolicy)? boldFont : font);
   }
 
-  protected TreeClassChooser.ClassFilter createClassConditionFilter() {
-    TreeClassChooser.ClassFilter classFilter;
+  protected ClassFilter createClassConditionFilter() {
+    ClassFilter classFilter;
     if(myBreakpointPsiClass != null) {
-      classFilter = new TreeClassChooser.ClassFilter() {
+      classFilter = new ClassFilter() {
         public boolean isAccepted(PsiClass aClass) {
           return myBreakpointPsiClass == aClass || aClass.isInheritor(myBreakpointPsiClass, true);
         }
@@ -476,14 +475,14 @@ public abstract class BreakpointPropertiesPanel {
   private void updateClassFilterEditor(boolean updateText) {
     List<String> filters = new ArrayList<String>();
     for (int i = 0; i < myClassFilters.length; i++) {
-      ClassFilter classFilter = myClassFilters[i];
+      com.intellij.ui.classFilter.ClassFilter classFilter = myClassFilters[i];
       if(classFilter.isEnabled()) {
         filters.add(classFilter.getPattern());
       }
     }
     List<String> excludeFilters = new ArrayList<String>();
     for (int i = 0; i < myClassExclusionFilters.length; i++) {
-      ClassFilter classFilter = myClassExclusionFilters[i];
+      com.intellij.ui.classFilter.ClassFilter classFilter = myClassExclusionFilters[i];
       if(classFilter.isEnabled()) {
         excludeFilters.add("-" + classFilter.getPattern());
       }
@@ -506,8 +505,8 @@ public abstract class BreakpointPropertiesPanel {
   private void reloadClassFilters() {
     String filtersText = myClassFiltersField.getText();
 
-    ArrayList<ClassFilter> classFilters     = new ArrayList<ClassFilter>();
-    ArrayList<ClassFilter> exclusionFilters = new ArrayList<ClassFilter>();
+    ArrayList<com.intellij.ui.classFilter.ClassFilter> classFilters     = new ArrayList<com.intellij.ui.classFilter.ClassFilter>();
+    ArrayList<com.intellij.ui.classFilter.ClassFilter> exclusionFilters = new ArrayList<com.intellij.ui.classFilter.ClassFilter>();
     int startFilter = -1;
     for(int i = 0; i <= filtersText.length(); i++) {
       if(i < filtersText.length() && !Character.isWhitespace(filtersText.charAt(i))){
@@ -515,24 +514,24 @@ public abstract class BreakpointPropertiesPanel {
       } else {
         if(startFilter >=0) {
           if(filtersText.charAt(startFilter) == '-'){
-            exclusionFilters.add(new ClassFilter(filtersText.substring(startFilter + 1, i)));
+            exclusionFilters.add(new com.intellij.ui.classFilter.ClassFilter(filtersText.substring(startFilter + 1, i)));
           } else {
-            classFilters.add(new ClassFilter(filtersText.substring(startFilter, i)));
+            classFilters.add(new com.intellij.ui.classFilter.ClassFilter(filtersText.substring(startFilter, i)));
           }
           startFilter = -1;
         }
       }
     }
     for (int i = 0; i < myClassFilters.length; i++) {
-      ClassFilter classFilter = myClassFilters[i];
+      com.intellij.ui.classFilter.ClassFilter classFilter = myClassFilters[i];
       if(!classFilter.isEnabled()) classFilters.add(classFilter);
     }
     for (int i = 0; i < myClassExclusionFilters.length; i++) {
-      ClassFilter classFilter = myClassExclusionFilters[i];
+      com.intellij.ui.classFilter.ClassFilter classFilter = myClassExclusionFilters[i];
       if(!classFilter.isEnabled()) exclusionFilters.add(classFilter);
     }
-    myClassFilters          = classFilters    .toArray(new ClassFilter[classFilters    .size()]);
-    myClassExclusionFilters = exclusionFilters.toArray(new ClassFilter[exclusionFilters.size()]);
+    myClassFilters          = classFilters    .toArray(new com.intellij.ui.classFilter.ClassFilter[classFilters    .size()]);
+    myClassExclusionFilters = exclusionFilters.toArray(new com.intellij.ui.classFilter.ClassFilter[exclusionFilters.size()]);
   }
 
   public void setEnabled(boolean enabled) {
index 28516ee4e07793b466a05b8954e73bff18db1a31..eaf7e27b8ce855cd2a94a42dad6bc910083a2321 100644 (file)
  */
 package com.intellij.debugger.ui.breakpoints;
 
-import com.intellij.ui.classFilter.ClassFilter;
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.ui.classFilter.ClassFilterEditor;
 import com.intellij.debugger.DebuggerBundle;
-import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.ui.IdeBorderFactory;
@@ -35,13 +34,13 @@ public class EditClassFiltersDialog extends DialogWrapper {
   private ClassFilterEditor myClassFilterEditor;
   private ClassFilterEditor myClassExclusionFilterEditor;
   private Project myProject;
-  private TreeClassChooser.ClassFilter myChooserFilter;
+  private ClassFilter myChooserFilter;
 
   public EditClassFiltersDialog(Project project) {
     this(project, null);
   }
 
-  public EditClassFiltersDialog(Project project, TreeClassChooser.ClassFilter filter) {
+  public EditClassFiltersDialog(Project project, ClassFilter filter) {
     super(project, true);
     myChooserFilter = filter;
     myProject = project;
@@ -75,7 +74,7 @@ public class EditClassFiltersDialog extends DialogWrapper {
     super.dispose();
   }
 
-  public void setFilters(ClassFilter[] filters, ClassFilter[] inverseFilters) {
+  public void setFilters(com.intellij.ui.classFilter.ClassFilter[] filters, com.intellij.ui.classFilter.ClassFilter[] inverseFilters) {
     myClassFilterEditor.setFilters(filters);
     myClassExclusionFilterEditor.setFilters(inverseFilters);
   }
@@ -84,11 +83,11 @@ public class EditClassFiltersDialog extends DialogWrapper {
     return "#com.intellij.debugger.ui.breakpoints.EditClassFiltersDialog";
   }
 
-  public ClassFilter[] getFilters() {
+  public com.intellij.ui.classFilter.ClassFilter[] getFilters() {
     return myClassFilterEditor.getFilters();
   }
 
-  public ClassFilter[] getExclusionFilters() {
+  public com.intellij.ui.classFilter.ClassFilter[] getExclusionFilters() {
     return myClassExclusionFilterEditor.getFilters();
   }
 }
\ No newline at end of file
index e0dfbbaca47dcf96015a21272f3ac993734153ee..6a457a270bf59b4e6c175cb4a38e565051ea0f4d 100644 (file)
@@ -114,7 +114,7 @@ public class ExceptionBreakpointFactory extends BreakpointFactory{
           DebuggerBundle.message("add.exception.breakpoint.classchooser.title"), GlobalSearchScope.allScope(myProject),
           throwableClass, true, true, null);
       chooser.showDialog();
-      PsiClass selectedClass = chooser.getSelectedClass();
+      PsiClass selectedClass = chooser.getSelected();
       String qName = selectedClass == null ? null : JVMNameUtil.getNonAnonymousClassName(selectedClass);
 
       if (qName != null && qName.length() > 0) {
index 52b7ce99433bba1b684119987031f89b6285a51c..9de67e05caa9723410493086a5cc5f435bfd2fd7 100644 (file)
@@ -21,7 +21,7 @@
 package com.intellij.debugger.ui.breakpoints;
 
 import com.intellij.debugger.DebuggerBundle;
-import com.intellij.ide.util.TreeClassChooser;
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.openapi.project.Project;
 
 import javax.swing.*;
@@ -38,7 +38,7 @@ public class ExceptionBreakpointPropertiesPanel extends BreakpointPropertiesPane
     super(project, ExceptionBreakpoint.CATEGORY);
   }
 
-  protected TreeClassChooser.ClassFilter createClassConditionFilter() {
+  protected ClassFilter createClassConditionFilter() {
     return null;
   }
 
index 9863785dea78b102db169c982144bd101b987083..c6b912883391b91feb907e3a32b985d9aac8ce95 100644 (file)
@@ -23,6 +23,7 @@ import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.ActionManager;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.ShortcutSet;
+import com.intellij.openapi.application.ModalityState;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.util.Alarm;
@@ -91,7 +92,7 @@ public abstract class UpdatableDebuggerView extends JPanel implements DebuggerVi
             // ignored
           }
         }
-      }, 100);
+      }, 100, ModalityState.NON_MODAL);
     }
     else {
       myRefreshNeeded = true;
index ea65d0316b3243f98d034b6f95b03357545f7dce..485a482268cb3a07bb449ef569206a40d0d05a31 100644 (file)
@@ -19,6 +19,7 @@ import com.intellij.execution.ExecutionBundle;
 import com.intellij.execution.JavaExecutionUtil;
 import com.intellij.execution.configuration.BrowseModuleValueActionListener;
 import com.intellij.execution.configurations.ConfigurationUtil;
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
 import com.intellij.openapi.module.Module;
@@ -41,7 +42,7 @@ public abstract class ClassBrowser extends BrowseModuleValueActionListener {
 
   @Nullable
   protected String showDialog() {
-    final TreeClassChooser.ClassFilterWithScope classFilter;
+    final ClassFilter.ClassFilterWithScope classFilter;
     try {
       classFilter = getFilter();
     }
@@ -53,17 +54,17 @@ public abstract class ClassBrowser extends BrowseModuleValueActionListener {
     final TreeClassChooser dialog = createClassChooser(classFilter);
     configureDialog(dialog);
     dialog.showDialog();
-    final PsiClass psiClass = dialog.getSelectedClass();
+    final PsiClass psiClass = dialog.getSelected();
     if (psiClass == null) return null;
     onClassChoosen(psiClass);
     return JavaExecutionUtil.getRuntimeQualifiedName(psiClass);
   }
 
-  protected TreeClassChooser createClassChooser(TreeClassChooser.ClassFilterWithScope classFilter) {
+  protected TreeClassChooser createClassChooser(ClassFilter.ClassFilterWithScope classFilter) {
     return TreeClassChooserFactory.getInstance(getProject()).createWithInnerClassesScopeChooser(myTitle, classFilter.getScope(), classFilter, null);
   }
 
-  protected abstract TreeClassChooser.ClassFilterWithScope getFilter() throws NoFilterException;
+  protected abstract ClassFilter.ClassFilterWithScope getFilter() throws NoFilterException;
 
   protected void onClassChoosen(final PsiClass psiClass) { }
 
@@ -73,20 +74,20 @@ public abstract class ClassBrowser extends BrowseModuleValueActionListener {
     if (psiClass == null) return;
     final PsiDirectory directory = psiClass.getContainingFile().getContainingDirectory();
     if (directory != null) dialog.selectDirectory(directory);
-    dialog.selectClass(psiClass);
+    dialog.select(psiClass);
   }
 
   protected abstract PsiClass findClass(String className);
 
   public static ClassBrowser createApplicationClassBrowser(final Project project,
                                                            final ConfigurationModuleSelector moduleSelector) {
-    final TreeClassChooser.ClassFilter applicationClass = new TreeClassChooser.ClassFilter() {
+    final ClassFilter applicationClass = new ClassFilter() {
       public boolean isAccepted(final PsiClass aClass) {
         return ConfigurationUtil.MAIN_CLASS.value(aClass) && PsiMethodUtil.findMainMethod(aClass) != null;
       }
     };
     return new MainClassBrowser(project, moduleSelector, ExecutionBundle.message("choose.main.class.dialog.title")){
-      protected TreeClassChooser.ClassFilter createFilter(final Module module) {
+      protected ClassFilter createFilter(final Module module) {
         return applicationClass;
       }
     };
@@ -98,7 +99,7 @@ public abstract class ClassBrowser extends BrowseModuleValueActionListener {
     return new MainClassBrowser(project, moduleSelector, title) {
 
       @Override
-      protected TreeClassChooser createClassChooser(TreeClassChooser.ClassFilterWithScope classFilter) {
+      protected TreeClassChooser createClassChooser(ClassFilter.ClassFilterWithScope classFilter) {
         final Module module = moduleSelector.getModule();
         final GlobalSearchScope scope =
             module == null ? GlobalSearchScope.allScope(myProject) : GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module);
@@ -124,13 +125,13 @@ public abstract class ClassBrowser extends BrowseModuleValueActionListener {
       return myModuleSelector.findClass(className);
     }
 
-    protected TreeClassChooser.ClassFilterWithScope getFilter() throws NoFilterException {
+    protected ClassFilter.ClassFilterWithScope getFilter() throws NoFilterException {
       final Module module = myModuleSelector.getModule();
       final GlobalSearchScope scope;
       if (module == null) scope = GlobalSearchScope.allScope(myProject);
       else scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module);
-      final TreeClassChooser.ClassFilter filter = createFilter(module);
-      return new TreeClassChooser.ClassFilterWithScope() {
+      final ClassFilter filter = createFilter(module);
+      return new ClassFilter.ClassFilterWithScope() {
         public GlobalSearchScope getScope() {
           return scope;
         }
@@ -141,7 +142,7 @@ public abstract class ClassBrowser extends BrowseModuleValueActionListener {
       };
     }
 
-    protected TreeClassChooser.ClassFilter createFilter(final Module module) { return null; }
+    protected ClassFilter createFilter(final Module module) { return null; }
   }
 
   public static class NoFilterException extends Exception {
index a1925aa881bb6d4e072cb67aa077384cc08e34d2..fbf3989eebcac7ed85f4cd80ebd4e3d0cb47b1dd 100644 (file)
 package com.intellij.openapi.roots.ui.configuration.artifacts;
 
 import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.project.ProjectBundle;
-import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectStructureElementConfigurable;
-import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement;
 import com.intellij.openapi.ui.ComboBox;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.packaging.artifacts.Artifact;
 import com.intellij.packaging.artifacts.ArtifactType;
-import org.jetbrains.annotations.Nls;
 
 import javax.swing.*;
 import java.awt.*;
@@ -33,19 +29,13 @@ import java.awt.event.ActionListener;
 /**
  * @author nik
  */
-public class ArtifactConfigurable extends ProjectStructureElementConfigurable<Artifact> {
-  private final Artifact myOriginalArtifact;
-  private final ArtifactsStructureConfigurableContext myArtifactsStructureContext;
+public class ArtifactConfigurable extends ArtifactConfigurableBase {
   private final ArtifactEditorImpl myEditor;
   private boolean myIsInUpdateName;
-  private final ProjectStructureElement myProjectStructureElement;
 
   public ArtifactConfigurable(Artifact originalArtifact, ArtifactsStructureConfigurableContextImpl artifactsStructureContext, final Runnable updateTree) {
-    super(true, updateTree);
-    myOriginalArtifact = originalArtifact;
-    myArtifactsStructureContext = artifactsStructureContext;
+    super(originalArtifact, artifactsStructureContext, updateTree, true);
     myEditor = artifactsStructureContext.getOrCreateEditor(originalArtifact);
-    myProjectStructureElement = myArtifactsStructureContext.getOrCreateArtifactElement(myOriginalArtifact);
   }
 
   public void setDisplayName(String name) {
@@ -56,11 +46,6 @@ public class ArtifactConfigurable extends ProjectStructureElementConfigurable<Ar
     }
   }
 
-  @Override
-  public ProjectStructureElement getProjectStructureElement() {
-    return myProjectStructureElement;
-  }
-
   @Override
   public void updateName() {
     myIsInUpdateName = true;
@@ -72,35 +57,10 @@ public class ArtifactConfigurable extends ProjectStructureElementConfigurable<Ar
     }
   }
 
-  private Artifact getArtifact() {
-    return myArtifactsStructureContext.getArtifactModel().getArtifactByOriginal(myOriginalArtifact);
-  }
-
-  public Artifact getEditableObject() {
-    return getArtifact();
-  }
-
-  public String getBannerSlogan() {
-    return ProjectBundle.message("banner.slogan.artifact.0", getDisplayName());
-  }
-
   public JComponent createOptionsPanel() {
     return myEditor.createMainComponent();
   }
 
-  @Nls
-  public String getDisplayName() {
-    return getArtifact().getName();
-  }
-
-  public Icon getIcon() {
-    return getArtifact().getArtifactType().getIcon();
-  }
-
-  public String getHelpTopic() {
-    return myEditor.getHelpTopic();
-  }
-
   @Override
   protected JComponent createTopRightComponent() {
     final ComboBox artifactTypeBox = new ComboBox();
@@ -137,7 +97,7 @@ public class ArtifactConfigurable extends ProjectStructureElementConfigurable<Ar
   public void reset() {
   }
 
-  public void disposeUIResources() {
+  public String getHelpTopic() {
+    return myEditor.getHelpTopic();
   }
-
 }
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurableBase.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurableBase.java
new file mode 100644 (file)
index 0000000..42a3ba7
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000-2010 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.roots.ui.configuration.artifacts;
+
+import com.intellij.openapi.project.ProjectBundle;
+import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectStructureElementConfigurable;
+import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement;
+import com.intellij.packaging.artifacts.Artifact;
+import org.jetbrains.annotations.Nls;
+
+import javax.swing.*;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactConfigurableBase extends ProjectStructureElementConfigurable<Artifact> {
+  protected final Artifact myOriginalArtifact;
+  protected final ArtifactsStructureConfigurableContext myArtifactsStructureContext;
+  protected final ProjectStructureElement myProjectStructureElement;
+
+  public ArtifactConfigurableBase(Artifact originalArtifact,
+                                  ArtifactsStructureConfigurableContextImpl artifactsStructureContext,
+                                  Runnable updateTree,
+                                  final boolean nameEditable) {
+    super(nameEditable, updateTree);
+    myOriginalArtifact = originalArtifact;
+    myArtifactsStructureContext = artifactsStructureContext;
+    myProjectStructureElement = myArtifactsStructureContext.getOrCreateArtifactElement(myOriginalArtifact);
+  }
+
+  @Override
+  public ProjectStructureElement getProjectStructureElement() {
+    return myProjectStructureElement;
+  }
+
+  protected Artifact getArtifact() {
+    return myArtifactsStructureContext.getArtifactModel().getArtifactByOriginal(myOriginalArtifact);
+  }
+
+  public Artifact getEditableObject() {
+    return getArtifact();
+  }
+
+  public String getBannerSlogan() {
+    return ProjectBundle.message("banner.slogan.artifact.0", getDisplayName());
+  }
+
+  @Nls
+  public String getDisplayName() {
+    return getArtifact().getName();
+  }
+
+  public Icon getIcon() {
+    return getArtifact().getArtifactType().getIcon();
+  }
+
+  public void disposeUIResources() {
+  }
+}
index 59a93707edc18d382e259078c405d4fc5cae2be1..7a4ad7c84be62f419333bf68fb69f1393d166c4e 100644 (file)
@@ -35,8 +35,10 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.*;
 import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement;
 import com.intellij.openapi.ui.MasterDetailsState;
 import com.intellij.openapi.ui.MasterDetailsStateService;
+import com.intellij.openapi.ui.NamedConfigurable;
 import com.intellij.packaging.artifacts.*;
 import com.intellij.packaging.impl.artifacts.ArtifactUtil;
+import com.intellij.packaging.impl.artifacts.InvalidArtifact;
 import com.intellij.packaging.impl.artifacts.PackagingElementPath;
 import com.intellij.packaging.impl.artifacts.PackagingElementProcessor;
 import com.intellij.packaging.impl.elements.LibraryElementType;
@@ -177,7 +179,7 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable {
   protected void loadTree() {
     myTree.setRootVisible(false);
     myTree.setShowsRootHandles(false);
-    for (Artifact artifact : myPackagingEditorContext.getArtifactModel().getArtifacts()) {
+    for (Artifact artifact : myPackagingEditorContext.getArtifactModel().getAllArtifactsIncludingInvalid()) {
       addArtifactNode(artifact);
     }
   }
@@ -186,14 +188,21 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable {
   @Override
   protected Collection<? extends ProjectStructureElement> getProjectStructureElements() {
     final List<ProjectStructureElement> elements = new ArrayList<ProjectStructureElement>();
-    for (Artifact artifact : myPackagingEditorContext.getArtifactModel().getArtifacts()) {
+    for (Artifact artifact : myPackagingEditorContext.getArtifactModel().getAllArtifactsIncludingInvalid()) {
       elements.add(myPackagingEditorContext.getOrCreateArtifactElement(artifact));
     }
     return elements;
   }
 
   private MyNode addArtifactNode(final Artifact artifact) {
-    final MyNode node = new MyNode(new ArtifactConfigurable(artifact, myPackagingEditorContext, TREE_UPDATER));
+    final NamedConfigurable<Artifact> configurable;
+    if (artifact instanceof InvalidArtifact) {
+      configurable = new InvalidArtifactConfigurable((InvalidArtifact)artifact, myPackagingEditorContext, TREE_UPDATER);
+    }
+    else {
+      configurable = new ArtifactConfigurable(artifact, myPackagingEditorContext, TREE_UPDATER);
+    }
+    final MyNode node = new MyNode(configurable);
     addNode(node, myRoot);
     return node;
   }
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/InvalidArtifactComponent.form b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/InvalidArtifactComponent.form
new file mode 100644 (file)
index 0000000..d291652
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.openapi.roots.ui.configuration.artifacts.InvalidArtifactConfigurable.InvalidArtifactComponent">
+  <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="20" y="20" width="500" height="400"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <vspacer id="b67c4">
+        <constraints>
+          <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </vspacer>
+      <component id="2bf31" class="javax.swing.JLabel">
+        <constraints>
+          <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="Cannot load artifact"/>
+        </properties>
+      </component>
+      <component id="b6c83" class="javax.swing.JLabel" binding="myIconLabel">
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value=""/>
+        </properties>
+      </component>
+      <component id="f350" class="com.intellij.openapi.ui.ex.MultiLineLabel" binding="myDescriptionLabel">
+        <constraints>
+          <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+      </component>
+    </children>
+  </grid>
+</form>
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/InvalidArtifactConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/InvalidArtifactConfigurable.java
new file mode 100644 (file)
index 0000000..2f4cd52
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2000-2010 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.roots.ui.configuration.artifacts;
+
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.ui.ex.MultiLineLabel;
+import com.intellij.openapi.util.IconLoader;
+import com.intellij.packaging.impl.artifacts.InvalidArtifact;
+
+import javax.swing.*;
+
+/**
+ * @author nik
+ */
+public class InvalidArtifactConfigurable extends ArtifactConfigurableBase {
+  private String myErrorMessage;
+
+  public InvalidArtifactConfigurable(InvalidArtifact originalArtifact,
+                                     ArtifactsStructureConfigurableContextImpl artifactsStructureContext,
+                                     Runnable updateTree) {
+    super(originalArtifact, artifactsStructureContext, updateTree, false);
+    myErrorMessage = originalArtifact.getErrorMessage();
+  }
+
+  @Override
+  public void setDisplayName(String name) {
+  }
+
+  @Override
+  public JComponent createOptionsPanel() {
+    return new InvalidArtifactComponent(myErrorMessage).myMainPanel;
+  }
+
+  @Override
+  public String getHelpTopic() {
+    return null;
+  }
+
+  @Override
+  public boolean isModified() {
+    return false;
+  }
+
+  @Override
+  public void apply() throws ConfigurationException {
+  }
+
+  @Override
+  public void reset() {
+  }
+
+  private static class InvalidArtifactComponent {
+    private JPanel myMainPanel;
+    private MultiLineLabel myDescriptionLabel;
+    private JLabel myIconLabel;
+
+    private InvalidArtifactComponent(String errorMessage) {
+      myIconLabel.setIcon(IconLoader.getIcon("/runConfigurations/configurationWarning.png"));
+      myDescriptionLabel.setText(errorMessage);
+    }
+  }
+}
index 1f7b946148da5d86f940e0a28de7a0bb02f7eb29..da0fa64cc01f8904ef7beea2ba35583ee1a616e0 100644 (file)
@@ -158,7 +158,7 @@ public class LibraryRootsComponent implements Disposable, LibraryEditorComponent
 
     myRemoveButton.addActionListener(new RemoveAction());
     final LibraryTableAttachHandler[] handlers = LibraryTableAttachHandler.EP_NAME.getExtensions();
-    if (handlers.length == 0 || myProject == null || myDescriptor != null) {
+    if (handlers.length == 0 || myProject == null || getLibraryEditor().getType() != null) {
       myAttachMoreButton.setVisible(false);
     }
     else {
index 72169b16647d6ca4f3f4e3c631655877a346673f..d9a746ec05646552639e9ea5163229d5724c91c1 100644 (file)
@@ -27,6 +27,7 @@
     <orderEntry type="module" module-name="icons" />
     <orderEntry type="library" name="jcip" level="project" />
     <orderEntry type="library" name="Groovy" level="project" />
+    <orderEntry type="library" name="Guava" level="project" />
   </component>
   <component name="copyright">
     <Base>
index e5592528a78fb82a9aeefd9d117bace40bad3f89..cf8e5c9ccea2d749aeef210e1dc736816f18f250 100644 (file)
@@ -275,7 +275,14 @@ public class ExpectedTypesProvider {
     }
 
     @Override public void visitAnnotationArrayInitializer(PsiArrayInitializerMemberValue initializer) {
-      final PsiType type = getAnnotationMethodType((PsiNameValuePair)initializer.getParent());
+      final PsiElement parent = initializer.getParent();
+      final PsiType type;
+      if (parent instanceof PsiNameValuePair) {
+        type = getAnnotationMethodType((PsiNameValuePair)parent);
+      }
+      else {
+        type = ((PsiAnnotationMethod)parent).getReturnType();
+      }
       if (type instanceof PsiArrayType) {
         myResult = new ExpectedTypeInfo[]{createInfoImpl(((PsiArrayType)type).getComponentType(), ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, TailType.UNKNOWN)};
       }
index 0def3c85f6bac740353854e066f316da1ca2771f..ae8c9070c875e501df39f8864b3ae2da334fcbbc 100644 (file)
@@ -19,7 +19,6 @@ import com.intellij.codeInsight.TailType;
 import com.intellij.codeInsight.lookup.LookupElement;
 import com.intellij.codeInsight.lookup.LookupItem;
 import com.intellij.codeInsight.lookup.LookupItemUtil;
-import com.intellij.codeInsight.lookup.TailTypeDecorator;
 import com.intellij.psi.*;
 import com.intellij.psi.filters.ContextGetter;
 import com.intellij.util.IncorrectOperationException;
@@ -72,7 +71,7 @@ public class JavaAwareCompletionData extends CompletionData{
     return TailType.NONE;
   }
 
-  protected void addLookupItem(Set<LookupElement> set, TailType tailType, @NotNull Object completion, final PsiFile file, final CompletionVariant variant) {
+  protected void addLookupItem(Set<LookupElement> set, final TailType tailType, @NotNull Object completion, final PsiFile file, final CompletionVariant variant) {
     if (completion instanceof LookupElement && !(completion instanceof LookupItem)) {
       set.add((LookupElement)completion);
       return;
@@ -88,8 +87,11 @@ public class JavaAwareCompletionData extends CompletionData{
     ret.setInsertHandler(new InsertHandler<LookupElement>() {
       @Override
       public void handleInsert(InsertionContext context, LookupElement item) {
-        final TailType type = analyzeItem(item.getObject(), context.getFile().findElementAt(context.getStartOffset()));
-        new DefaultInsertHandler().handleInsert(context, item);
+        TailType type = analyzeItem(item.getObject(), context.getFile().findElementAt(context.getStartOffset()));
+        if (type == TailType.NONE) {
+          type = tailType;
+        }
+        //new DefaultInsertHandler().handleInsert(context, item);
         if (type != TailType.NONE) {
           context.setAddCompletionChar(false);
           type.processTail(context.getEditor(), context.getTailOffset());
@@ -102,11 +104,7 @@ public class JavaAwareCompletionData extends CompletionData{
       ret.setAttribute(key, itemProperties.get(key));
     }
 
-    if ((insertHandler == null || ret.getInsertHandler() != null) && tailType != TailType.NONE) {
-      set.add(TailTypeDecorator.withTail(ret, tailType));
-    } else {
-      set.add(ret);
-    }
+    set.add(ret);
   }
 
   protected void addKeywords(final Set<LookupElement> set, final PsiElement position, final PrefixMatcher matcher, final PsiFile file,
index 01a93aab9dca877052f96dd76342efde31ae5bcd..1750e8e5ae58d026c620d22f75f7a43b0c3666d9 100644 (file)
@@ -119,6 +119,10 @@ public class JavaCompletionContributor extends CompletionContributor {
       return null;
     }
 
+    if (JavaCompletionData.START_FOR.accepts(position)) {
+      return ElementClassFilter.VARIABLE;
+    }
+
     if (psiElement().afterLeaf(psiElement().withText("(").withParent(PsiTryStatement.class)).accepts(position)) {
       return new OrFilter(new ThisOrAnyInnerFilter(new AssignableFromFilter(CommonClassNames.JAVA_LANG_THROWABLE)), ElementClassFilter.PACKAGE_FILTER);
     }
index d1a8955f8fc4be827c7064f4f11e9389aaee87a0..f7643dbd846b33e5cab246367ccecc755750fd03 100644 (file)
@@ -137,6 +137,8 @@ public class JavaCompletionData extends JavaAwareCompletionData{
   final static ElementFilter CLASS_BODY = new OrFilter(
     new AfterElementFilter(new TextFilter("{")),
     new ScopeFilter(new ClassFilter(JspClassLevelDeclarationStatement.class)));
+  public static final ElementPattern<PsiElement> START_FOR =
+    psiElement().afterLeaf(psiElement().withText("(").afterLeaf("for")).withParents(PsiJavaCodeReferenceElement.class, PsiExpressionStatement.class, PsiForStatement.class);
 
   public JavaCompletionData(){
     declareCompletionSpaces();
@@ -538,7 +540,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
     variant.addCompletion(PsiKeyword.IF, TailTypes.IF_LPARENTH);
     variant.addCompletion(PsiKeyword.TRY, TailType.createSimpleTailType('{'));
     variant.addCompletion(PsiKeyword.THROW, TailType.SPACE);
-    variant.addCompletion(PsiKeyword.RETURN, TailType.SPACE);
+    variant.addCompletion(PsiKeyword.RETURN, TailType.NONE);
     variant.addCompletion(PsiKeyword.NEW, TailType.SPACE);
     variant.addCompletion(PsiKeyword.ASSERT, TailType.SPACE);
     variant.addCompletion(PsiKeyword.SYNCHRONIZED, TailTypes.SYNCHRONIZED_LPARENTH);
@@ -592,11 +594,12 @@ public class JavaCompletionData extends JavaAwareCompletionData{
       result.addElement(createKeyword(position, PsiKeyword.FALSE));
     }
 
-    if (psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiExpressionStatement.class, PsiForStatement.class).accepts(position)) {
+    if (START_FOR.accepts(position)) {
       for (String primitiveType : PRIMITIVE_TYPES) {
         if (!PsiKeyword.VOID.equals(primitiveType)) {
           result.addElement(TailTypeDecorator.withTail(createKeyword(position, primitiveType), TailType.SPACE));
         }
+        result.addElement(TailTypeDecorator.withTail(createKeyword(position, PsiKeyword.FINAL), TailType.SPACE));
       }
     }
 
index 57d5496f2d556349b238fa5cfbc0e9f3d05773a6..831ee149ab27806f1b9abf11e03163942d5cdc8c 100644 (file)
@@ -3,6 +3,7 @@ package com.intellij.codeInsight.completion;
 import com.intellij.codeInsight.lookup.LookupElement;
 import com.intellij.codeInsight.lookup.VariableLookupItem;
 import com.intellij.psi.*;
+import com.intellij.psi.impl.source.PostprocessReformattingAspect;
 import com.intellij.psi.util.PsiTreeUtil;
 import org.jetbrains.annotations.NotNull;
 
@@ -53,6 +54,7 @@ public class JavaGlobalMemberNameCompletionContributor extends CompletionContrib
             final PsiReferenceExpression ref = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiReferenceExpression.class, false);
             if (ref != null) {
               ref.bindToElementViaStaticImport(containingClass);
+              PostprocessReformattingAspect.getInstance(ref.getProject()).doPostponedFormatting();
             }
             super.handleInsert(context);
           }
index 29c0f8f3c5055d897606dc67e239f4293527e41f..f399888ce64e48aa3e53863c69de0f542ff4a88a 100644 (file)
@@ -1731,21 +1731,20 @@ public class HighlightUtil {
       rTypeParams = psiClass == null ? PsiTypeParameter.EMPTY_ARRAY : psiClass.getTypeParameters();
     }
 
-
     int typeParamColumns = Math.max(lTypeParams.length, rTypeParams.length);
-    @Language("HTML") @NonNls String requredRow = "";
+    @Language("HTML") @NonNls String requiredRow = "";
     @Language("HTML") @NonNls String foundRow = "";
     for (int i = 0; i < typeParamColumns; i++) {
       PsiTypeParameter lTypeParameter = i >= lTypeParams.length ? null : lTypeParams[i];
       PsiTypeParameter rTypeParameter = i >= rTypeParams.length ? null : rTypeParams[i];
-      PsiType lSubstedType = lTypeParameter == null ? null : lTypeSubstitutor.substitute(lTypeParameter);
-      PsiType rSubstedType = rTypeParameter == null ? null : rTypeSubstitutor.substitute(rTypeParameter);
-      boolean matches = Comparing.equal(lSubstedType, rSubstedType);
+      PsiType lSubstitutedType = lTypeParameter == null ? null : lTypeSubstitutor.substitute(lTypeParameter);
+      PsiType rSubstitutedType = rTypeParameter == null ? null : rTypeSubstitutor.substitute(rTypeParameter);
+      boolean matches = Comparing.equal(lSubstitutedType, rSubstitutedType);
       @NonNls String openBrace = i == 0 ? "&lt;" : "";
       @NonNls String closeBrace = i == typeParamColumns - 1 ? "&gt;" : ",";
-      requredRow += "<td>" + (lTypeParams.length == 0 ? "" : openBrace) + redIfNotMatch(lSubstedType, matches) +
-                    (i < lTypeParams.length ? closeBrace : "") + "</td>";
-      foundRow += "<td>" + (rTypeParams.length == 0 ? "" : openBrace) + redIfNotMatch(rSubstedType, matches) +
+      requiredRow += "<td>" + (lTypeParams.length == 0 ? "" : openBrace) + redIfNotMatch(lSubstitutedType, matches) +
+                     (i < lTypeParams.length ? closeBrace : "") + "</td>";
+      foundRow += "<td>" + (rTypeParams.length == 0 ? "" : openBrace) + redIfNotMatch(rSubstitutedType, matches) +
                   (i < rTypeParams.length ? closeBrace : "") + "</td>";
     }
     PsiType lRawType = lType1 instanceof PsiClassType ? ((PsiClassType)lType1).rawType() : lType1;
@@ -1753,7 +1752,7 @@ public class HighlightUtil {
     boolean assignable = lRawType == null || rRawType == null || TypeConversionUtil.isAssignable(lRawType, rRawType);
 
     String toolTip = JavaErrorMessages.message("incompatible.types.html.tooltip",
-                                               redIfNotMatch(lRawType, assignable), requredRow,
+                                               redIfNotMatch(lRawType, assignable), requiredRow,
                                                redIfNotMatch(rRawType, assignable), foundRow);
 
     String description = JavaErrorMessages.message("incompatible.types", formatType(lType1), formatType(rType1));
index d9552ac1377d535f29436992c48a85ff6e879b85..1105bf497ef028588ff485ba29ab084ab2f7d8ca 100644 (file)
@@ -38,32 +38,32 @@ public class TreeClassChooserFactoryImpl extends TreeClassChooserFactory {
   @NotNull
   public TreeClassChooser createWithInnerClassesScopeChooser(String title,
                                                              GlobalSearchScope scope,
-                                                             final TreeClassChooser.ClassFilter classFilter,
+                                                             final ClassFilter classFilter,
                                                              PsiClass initialClass) {
-    return TreeClassChooserDialog.withInnerClasses(title, myProject, scope, classFilter, initialClass);
+    return TreeJavaClassChooserDialog.withInnerClasses(title, myProject, scope, classFilter, initialClass);
   }
 
   @NotNull
   public TreeClassChooser createNoInnerClassesScopeChooser(String title,
                                                            GlobalSearchScope scope,
-                                                           TreeClassChooser.ClassFilter classFilter,
+                                                           ClassFilter classFilter,
                                                            PsiClass initialClass) {
-    return new TreeClassChooserDialog(title, myProject, scope, classFilter, initialClass);
+    return new TreeJavaClassChooserDialog(title, myProject, scope, classFilter, initialClass);
   }
 
   @NotNull
   public TreeClassChooser createProjectScopeChooser(String title, PsiClass initialClass) {
-    return new TreeClassChooserDialog(title, myProject, initialClass);
+    return new TreeJavaClassChooserDialog(title, myProject, initialClass);
   }
 
   @NotNull
   public TreeClassChooser createProjectScopeChooser(String title) {
-    return new TreeClassChooserDialog(title, myProject);
+    return new TreeJavaClassChooserDialog(title, myProject);
   }
 
   @NotNull
   public TreeClassChooser createAllProjectScopeChooser(String title) {
-    return new TreeClassChooserDialog(title, myProject, GlobalSearchScope.allScope(myProject), null, null);
+    return new TreeJavaClassChooserDialog(title, myProject, GlobalSearchScope.allScope(myProject), null, null);
   }
 
   @NotNull
@@ -73,8 +73,8 @@ public class TreeClassChooserFactoryImpl extends TreeClassChooserFactory {
                                                         boolean acceptsSelf,
                                                         boolean acceptInner,
                                                         Condition<? super PsiClass> additionalCondition) {
-    TreeClassChooser.ClassFilter classFilter = new TreeClassChooserDialog.InheritanceClassFilterImpl(base, acceptsSelf, acceptInner, additionalCondition);
-    return new TreeClassChooserDialog(title, myProject, scope, classFilter, base, null, null);
+    ClassFilter classFilter = new TreeJavaClassChooserDialog.InheritanceJavaClassFilterImpl(base, acceptsSelf, acceptInner, additionalCondition);
+    return new TreeJavaClassChooserDialog(title, myProject, scope, classFilter, base, null, false);
   }
 
   @NotNull
@@ -84,8 +84,8 @@ public class TreeClassChooserFactoryImpl extends TreeClassChooserFactory {
 
   @NotNull
   public TreeClassChooser createInheritanceClassChooser(String title, GlobalSearchScope scope, PsiClass base, PsiClass initialClass,
-                                                        TreeClassChooser.ClassFilter classFilter) {
-    return new TreeClassChooserDialog(title, myProject, scope, classFilter, base, initialClass, null);
+                                                        ClassFilter classFilter) {
+    return new TreeJavaClassChooserDialog(title, myProject, scope, classFilter, base, initialClass, false);
   }
 
   @NotNull
diff --git a/java/java-impl/src/com/intellij/ide/util/TreeJavaClassChooserDialog.java b/java/java-impl/src/com/intellij/ide/util/TreeJavaClassChooserDialog.java
new file mode 100644 (file)
index 0000000..0b89a17
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2000-2010 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.util;
+
+import com.google.common.collect.Lists;
+import com.intellij.ide.projectView.impl.nodes.ClassTreeNode;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Conditions;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiJavaFile;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.psi.search.searches.ClassInheritorsSearch;
+import com.intellij.util.Query;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import java.util.List;
+
+/**
+ * @author traff
+ */
+public class TreeJavaClassChooserDialog extends AbstractTreeClassChooserDialog<PsiClass> implements TreeClassChooser {
+  public TreeJavaClassChooserDialog(String title, Project project) {
+    super(title, project);
+  }
+
+  public TreeJavaClassChooserDialog(String title, Project project, @Nullable PsiClass initialClass) {
+    super(title, project, initialClass);
+  }
+
+  public TreeJavaClassChooserDialog(String title,
+                                    Project project,
+                                    GlobalSearchScope scope,
+                                    final ClassFilter classFilter, @Nullable PsiClass initialClass) {
+    super(title, project, scope, createFilter(classFilter), initialClass);
+  }
+
+
+  @Override
+  @Nullable
+  protected PsiClass getSelectedFromTreeUserObject(DefaultMutableTreeNode node) {
+    Object userObject = node.getUserObject();
+    if (!(userObject instanceof ClassTreeNode)) return null;
+    ClassTreeNode descriptor = (ClassTreeNode)userObject;
+    return descriptor.getPsiClass();
+  }
+
+  public TreeJavaClassChooserDialog(String title,
+                                    Project project,
+                                    GlobalSearchScope scope,
+                                    final ClassFilter classFilter,
+                                    PsiClass baseClass,
+                                    @Nullable PsiClass initialClass, boolean isShowMembers) {
+    super(title, project, scope, createFilter(classFilter), baseClass, initialClass, isShowMembers);
+  }
+
+  public static TreeJavaClassChooserDialog withInnerClasses(String title,
+                                                            Project project,
+                                                            GlobalSearchScope scope,
+                                                            final ClassFilter classFilter,
+                                                            @Nullable PsiClass initialClass) {
+    return new TreeJavaClassChooserDialog(title, project, scope, classFilter, null, initialClass, true);
+  }
+
+  @Nullable
+  private static Filter<PsiClass> createFilter(@Nullable final ClassFilter classFilter) {
+    if (classFilter == null) {
+      return null;
+    }
+    else {
+      return new Filter<PsiClass>() {
+        @Override
+        public boolean isAccepted(PsiClass element) {
+          return classFilter.isAccepted(element);
+        }
+      };
+    }
+  }
+
+  @NotNull
+  protected List<PsiClass> getClassesByName(final String name,
+                                            final boolean checkBoxState,
+                                            final String pattern,
+                                            final GlobalSearchScope searchScope) {
+    final PsiShortNamesCache cache = JavaPsiFacade.getInstance(getProject()).getShortNamesCache();
+    PsiClass[] classes =
+      cache.getClassesByName(name, checkBoxState ? searchScope : GlobalSearchScope.projectScope(getProject()).intersectWith(searchScope));
+    return Lists.newArrayList(classes);
+  }
+
+  @NotNull
+  @Override
+  protected BaseClassInheritorsProvider<PsiClass> getInheritorsProvider() {
+    return new JavaInheritorsProvider(getProject(), getBaseClass(), getScope());
+  }
+
+  private static class JavaInheritorsProvider extends BaseClassInheritorsProvider<PsiClass> {
+    private final Project myProject;
+
+    public JavaInheritorsProvider(Project project, PsiClass baseClass, GlobalSearchScope scope) {
+      super(baseClass, scope);
+      myProject = project;
+    }
+
+    @NotNull
+    @Override
+    protected Query<PsiClass> searchForInheritors(PsiClass baseClass, GlobalSearchScope searchScope, boolean checkDeep) {
+      return ClassInheritorsSearch.search(baseClass, searchScope, checkDeep);
+    }
+
+    @Override
+    protected boolean isInheritor(PsiClass clazz, PsiClass baseClass, boolean checkDeep) {
+      return clazz.isInheritor(baseClass, checkDeep);
+    }
+
+    @Override
+    protected String[] getNames() {
+      return JavaPsiFacade.getInstance(myProject).getShortNamesCache().getAllClassNames();
+    }
+  }
+
+  public static class InheritanceJavaClassFilterImpl implements ClassFilter {
+    private final PsiClass myBase;
+    private final boolean myAcceptsSelf;
+    private final boolean myAcceptsInner;
+    private final Condition<? super PsiClass> myAdditionalCondition;
+
+    public InheritanceJavaClassFilterImpl(PsiClass base,
+                                          boolean acceptsSelf,
+                                          boolean acceptInner,
+                                          Condition<? super PsiClass> additionalCondition) {
+      myAcceptsSelf = acceptsSelf;
+      myAcceptsInner = acceptInner;
+      if (additionalCondition == null) {
+        additionalCondition = Conditions.alwaysTrue();
+      }
+      myAdditionalCondition = additionalCondition;
+      myBase = base;
+    }
+
+    public boolean isAccepted(PsiClass aClass) {
+      if (!myAcceptsInner && !(aClass.getParent() instanceof PsiJavaFile)) return false;
+      if (!myAdditionalCondition.value(aClass)) return false;
+      // we've already checked for inheritance
+      return myAcceptsSelf || !aClass.getManager().areElementsEquivalent(aClass, myBase);
+    }
+  }
+}
index 0f9f6eb9a5206cfcea62d79a9cc8c8eae6daf847..4fe8df3feefafc4b8c1e0cfa38e57e05ef81120d 100644 (file)
@@ -55,7 +55,7 @@ public class ClassHierarchyScopeDescriptor extends ScopeDescriptor {
 
       chooser.showDialog();
 
-      PsiClass aClass = chooser.getSelectedClass();
+      PsiClass aClass = chooser.getSelected();
       if (aClass == null) return null;
 
       List<PsiElement> classesToSearch = new LinkedList<PsiElement>();
index f99d8355c3093fbb0c8ac238d395f67ae14a6197..d1d91be0ee2115052d3a69186ddc307bb63f8505 100644 (file)
@@ -205,7 +205,7 @@ public class DeclarationParser {
       }
 
       // adding a reference, not simple tokens allows "Browse ..." to work well
-      final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, true, false, false);
+      final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, true, false, false, false);
       if (ref == null) {
         builder.advanceLexer();
       }
@@ -518,7 +518,7 @@ public class DeclarationParser {
       }
 
       // adding a reference, not simple tokens allows "Browse .." to work well
-      final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, true, false, false);
+      final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, true, false, false, false);
       if (ref == null && builder.getTokenType() != null) {
         builder.advanceLexer();
       }
@@ -689,7 +689,7 @@ public class DeclarationParser {
     final PsiBuilder.Marker anno = builder.mark();
     builder.advanceLexer();
 
-    final PsiBuilder.Marker classRef = ReferenceParser.parseJavaCodeReference(builder, true, false, false, false);
+    final PsiBuilder.Marker classRef = ReferenceParser.parseJavaCodeReference(builder, true, false, false, false, false);
     if (classRef == null) {
       error(builder, JavaErrorMessages.message("expected.class.reference"));
     }
index c04f0e6989624bf08a9b4b2dffc43fb9bedcaa18..d48486858153b0cc16817a884d4d747143df87f6 100644 (file)
@@ -357,7 +357,7 @@ public class ExpressionParser {
           final PsiBuilder.Marker copy = startMarker.precede();
           startMarker.rollbackTo();
 
-          final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, false, true, false, false);
+          final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, false, true, false, false, false);
           if (ref == null || builder.getTokenType() != JavaTokenType.DOT) {
             copy.rollbackTo();
             return parsePrimary(builder, BreakPoint.P2, -1);
@@ -661,7 +661,7 @@ public class ExpressionParser {
 
     final IElementType tokenType = builder.getTokenType();
     if (tokenType == JavaTokenType.IDENTIFIER || parseAnnotations) {
-      refOrType = ReferenceParser.parseJavaCodeReference(builder, true, true, parseAnnotations, parseDiamonds);
+      refOrType = ReferenceParser.parseJavaCodeReference(builder, true, true, parseAnnotations, true, parseDiamonds);
       if (refOrType == null) {
         error(builder, JavaErrorMessages.message("expected.identifier"));
         newExpr.done(JavaElementType.NEW_EXPRESSION);
index 06ff60adde5c6bd157305631c5dfa244a898d375..d41de50bc5815b0d279004982bcd858c241da477 100644 (file)
@@ -115,7 +115,7 @@ public class FileParser {
       }
     }
 
-    final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, false, false, false);
+    final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, false, false, false, false);
     if (ref == null) {
       statement.rollbackTo();
       return null;
index fb87ee3275ef315522a98dfa07f21ce36be25974..00eb4604df3f690125862d6197148bdf818cc1d3 100644 (file)
@@ -79,7 +79,7 @@ public class ReferenceParser {
       typeInfo.isPrimitive = true;
     }
     else if (tokenType == JavaTokenType.IDENTIFIER) {
-      parseJavaCodeReference(builder, eatLastDot, true, annotationsSupported, false, false, diamonds, typeInfo);
+      parseJavaCodeReference(builder, eatLastDot, true, annotationsSupported, false, false, false, diamonds, typeInfo);
     }
     else if (wildcard && tokenType == JavaTokenType.QUEST) {
       type.drop();
@@ -149,22 +149,21 @@ public class ReferenceParser {
   }
 
   @Nullable
-  public static PsiBuilder.Marker parseJavaCodeReference(final PsiBuilder builder, final boolean eatLastDot,
-                                                         final boolean parameterList, final boolean annotations, final boolean diamonds) {
-    return parseJavaCodeReference(builder, eatLastDot, parameterList, annotations, false, false, diamonds, new TypeInfo());
+  public static PsiBuilder.Marker parseJavaCodeReference(final PsiBuilder builder, final boolean eatLastDot, final boolean parameterList,
+                                                         final boolean annotations, final boolean isNew, final boolean diamonds) {
+    return parseJavaCodeReference(builder, eatLastDot, parameterList, annotations, false, false, isNew, diamonds, new TypeInfo());
   }
 
   public static boolean parseImportCodeReference(final PsiBuilder builder, final boolean isStatic) {
     final TypeInfo typeInfo = new TypeInfo();
-    parseJavaCodeReference(builder, true, false, false, true, isStatic, false, typeInfo);
+    parseJavaCodeReference(builder, true, false, false, true, isStatic, false, false, typeInfo);
     return !typeInfo.hasErrors;
   }
 
   @Nullable
-  private static PsiBuilder.Marker parseJavaCodeReference(final PsiBuilder builder, final boolean eatLastDot,
-                                                          final boolean parameterList, final boolean annotations,
-                                                          final boolean isImport, final boolean isStaticImport,
-                                                          final boolean diamonds, final TypeInfo typeInfo) {
+  private static PsiBuilder.Marker parseJavaCodeReference(final PsiBuilder builder, final boolean eatLastDot, final boolean parameterList,
+                                                          final boolean annotations, final boolean isImport, final boolean isStaticImport,
+                                                          final boolean isNew, final boolean diamonds, final TypeInfo typeInfo) {
     PsiBuilder.Marker refElement = builder.mark();
 
     if (annotations) {
@@ -193,6 +192,10 @@ public class ReferenceParser {
     while (builder.getTokenType() == JavaTokenType.DOT) {
       refElement.done(JavaElementType.JAVA_CODE_REFERENCE);
 
+      if (isNew && typeInfo.isParameterized) {
+        return refElement;
+      }
+
       final PsiBuilder.Marker dotPos = builder.mark();
       builder.advanceLexer();
 
@@ -330,7 +333,7 @@ public class ReferenceParser {
 
     if (expect(builder, start)) {
       while (true) {
-        final PsiBuilder.Marker classReference = parseJavaCodeReference(builder, true, true, true, false);
+        final PsiBuilder.Marker classReference = parseJavaCodeReference(builder, true, true, true, false, false);
         if (classReference == null) {
           error(builder, JavaErrorMessages.message("expected.identifier"));
         }
index 9616168e2ef37b1505f0fc4dfd96db42be72303c..c4615730b454085b0fde183c7856ac30fd92d61f 100644 (file)
@@ -38,6 +38,7 @@ import com.intellij.psi.search.SearchScope;
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.util.Collection;
@@ -466,10 +467,13 @@ public class ClsClassImpl extends ClsRepositoryPsiElement<PsiClassStub<?>> imple
     return InheritanceImplUtil.isInheritor(this, baseClass, checkDeep);
   }
 
+  @Nullable
   public PsiClass getSourceMirrorClass() {
     PsiElement parent = getParent();
     final String name = getName();
     if (parent instanceof PsiFile) {
+      if (!(parent instanceof PsiClassOwner)) return null;
+
       PsiClassOwner fileNavigationElement = (PsiClassOwner)parent.getNavigationElement();
       for (PsiClass aClass : fileNavigationElement.getClasses()) {
         if (name.equals(aClass.getName())) return aClass;
index d8d36729a3ebad88edce785faecc4c91bbbcb274..0af5952b0e1ab30f22bcf3cc6935df83303f7ce7 100644 (file)
@@ -236,7 +236,7 @@ public interface JavaElementType {
         return JavaParserUtil.parseFragment(chameleon,
                                             new JavaParserUtil.ParserWrapper() {
                                               public void parse(final PsiBuilder builder) {
-                                                ReferenceParser.parseJavaCodeReference(builder, false, true, false, false);
+                                                ReferenceParser.parseJavaCodeReference(builder, false, true, false, false, false);
                                               }
                                             });
       }
index cbfa0d58a4e9f3e2975bd96ce5c0c89d14b42a54..0648fb6f87ffb378db8c755a07aa9d095b8e1574 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.refactoring.introduceField;
 
 import com.intellij.codeInsight.AnnotationUtil;
 import com.intellij.codeInsight.completion.JavaCompletionUtil;
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.ide.util.PropertiesComponent;
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
@@ -432,7 +433,7 @@ class IntroduceConstantDialog extends DialogWrapper {
 
   private class ChooseClassAction implements ActionListener {
     public void actionPerformed(ActionEvent e) {
-      TreeClassChooser chooser = TreeClassChooserFactory.getInstance(myProject).createWithInnerClassesScopeChooser(RefactoringBundle.message("choose.destination.class"), GlobalSearchScope.projectScope(myProject), new TreeClassChooser.ClassFilter() {
+      TreeClassChooser chooser = TreeClassChooserFactory.getInstance(myProject).createWithInnerClassesScopeChooser(RefactoringBundle.message("choose.destination.class"), GlobalSearchScope.projectScope(myProject), new ClassFilter() {
         public boolean isAccepted(PsiClass aClass) {
           return aClass.getParent() instanceof PsiJavaFile || aClass.hasModifierProperty(PsiModifier.STATIC);
         }
@@ -441,7 +442,7 @@ class IntroduceConstantDialog extends DialogWrapper {
         chooser.selectDirectory(myTargetClass.getContainingFile().getContainingDirectory());
       }
       chooser.showDialog();
-      PsiClass aClass = chooser.getSelectedClass();
+      PsiClass aClass = chooser.getSelected();
       if (aClass != null) {
         myTfTargetClassName.setText(aClass.getQualifiedName());
       }
index 8704779e2662559802f435fb457f24cd7359b865..ede4be1340d308d136d04e25c0f9d9942aebf7c2 100644 (file)
@@ -468,6 +468,10 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
         final TypeExpression expression = new TypeExpression(project, typeSelectorManager.getTypesForAll());
         final RangeMarker exprMarker = editor.getDocument().createRangeMarker(expr.getTextRange());
         final SuggestedNameInfo suggestedName = getSuggestedName(settings.getSelectedType(), expr);
+        final List<RangeMarker> occurrenceMarkers = new ArrayList<RangeMarker>();
+        for (PsiExpression occurrence : occurrences) {
+          occurrenceMarkers.add(editor.getDocument().createRangeMarker(occurrence.getTextRange()));
+        }
         final Runnable runnable =
           introduce(project, expr, editor, anchorStatement, tempContainer, occurrences, anchorStatementIfAll, settings, variable);
         CommandProcessor.getInstance().executeCommand(
@@ -481,6 +485,8 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
                   editor.getCaretModel().moveToOffset(elementToRename.getTextOffset());
                   final PsiDeclarationStatement declarationStatement = PsiTreeUtil.getParentOfType(elementToRename, PsiDeclarationStatement.class);
                   editor.putUserData(ReassignVariableUtil.DECLARATION_KEY, declarationStatement);
+                  editor.putUserData(ReassignVariableUtil.OCCURRENCES_KEY,
+                                     occurrenceMarkers.toArray(new RangeMarker[occurrenceMarkers.size()]));
                   final VariableInplaceRenamer renamer = new VariableInplaceRenamer(elementToRename, editor){
                     @Override
                     protected void addAdditionalVariables(TemplateBuilderImpl builder) {
@@ -505,6 +511,10 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
                           editor.getCaretModel().moveToOffset(startOffset);
                         }
                         editor.putUserData(ReassignVariableUtil.DECLARATION_KEY, null);
+                        for (RangeMarker occurrenceMarker : occurrenceMarkers) {
+                          occurrenceMarker.dispose();
+                        }
+                        editor.putUserData(ReassignVariableUtil.OCCURRENCES_KEY, null);
                         typeSelectorManager.typeSelected(ReassignVariableUtil.getVariableType(declarationStatement));
                         exprMarker.dispose();
                       }
index 18741296d3d99c5b24a25e209e41f88d41d3eb52..4417ef29a1fd443a5c8542918889405728815d51 100644 (file)
@@ -27,6 +27,7 @@ import com.intellij.openapi.actionSystem.Shortcut;
 import com.intellij.openapi.application.Result;
 import com.intellij.openapi.command.WriteCommandAction;
 import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.RangeMarker;
 import com.intellij.openapi.editor.VisualPosition;
 import com.intellij.openapi.keymap.Keymap;
 import com.intellij.openapi.keymap.KeymapManager;
@@ -36,6 +37,7 @@ import com.intellij.openapi.util.Key;
 import com.intellij.psi.*;
 import com.intellij.psi.scope.processor.VariablesProcessor;
 import com.intellij.psi.scope.util.PsiScopesUtil;
+import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.TypeConversionUtil;
 import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer;
 import com.intellij.refactoring.ui.TypeSelectorManager;
@@ -53,6 +55,10 @@ import java.awt.*;
  */
 public class ReassignVariableUtil {
   static final Key<PsiDeclarationStatement> DECLARATION_KEY = Key.create("var.type");
+  static final Key<RangeMarker[]> OCCURRENCES_KEY = Key.create("occurrences");
+
+  private ReassignVariableUtil() {
+  }
 
   static boolean reassign(final Editor editor) {
     final PsiDeclarationStatement declaration = editor.getUserData(DECLARATION_KEY);
@@ -130,15 +136,29 @@ public class ReassignVariableUtil {
     return proc;
   }
 
-  static void replaceWithAssignment(final PsiDeclarationStatement declaration, final PsiVariable variable, Editor editor) {
+  static void replaceWithAssignment(final PsiDeclarationStatement declaration, final PsiVariable variable, final Editor editor) {
     final PsiVariable var = (PsiVariable)declaration.getDeclaredElements()[0];
     final PsiExpression initializer = var.getInitializer();
     new WriteCommandAction(declaration.getProject()) {
       @Override
       protected void run(Result result) throws Throwable {
+        final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(variable.getProject());
+        final String chosenVariableName = variable.getName();
         //would generate red code for final variables
-        declaration.replace(JavaPsiFacade.getElementFactory(variable.getProject())
-                              .createStatementFromText(variable.getName() + " = " + initializer.getText() + ";", declaration));
+        PsiElement newDeclaration = elementFactory.createStatementFromText(chosenVariableName + " = " + initializer.getText() + ";",
+                                                                           declaration);
+        newDeclaration = declaration.replace(newDeclaration);
+        final PsiFile containingFile = newDeclaration.getContainingFile();
+        final RangeMarker[] occurrenceMarkers = editor.getUserData(OCCURRENCES_KEY);
+        if (occurrenceMarkers != null) {
+          for (RangeMarker marker : occurrenceMarkers) {
+            final PsiElement refVariableElement = containingFile.findElementAt(marker.getStartOffset());
+            final PsiExpression expression = PsiTreeUtil.getParentOfType(refVariableElement, PsiReferenceExpression.class);
+            if (expression != null) {
+              expression.replace(elementFactory.createExpressionFromText(chosenVariableName, newDeclaration));
+            }
+          }
+        }
       }
     }.execute();
     finishTemplate(editor);
index eaaa49a2cf86d2fda016ee53cc8800fe325a2cc2..924db50dc42b2d46672eb17d51eb805f57d3b999 100644 (file)
@@ -15,7 +15,7 @@
  */
 package com.intellij.refactoring.introduceparameterobject;
 
-import com.intellij.ide.util.TreeClassChooserDialog;
+import com.intellij.ide.util.TreeJavaClassChooserDialog;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.help.HelpManager;
 import com.intellij.openapi.options.ConfigurationException;
@@ -288,15 +288,15 @@ public class IntroduceParameterObjectDialog extends RefactoringDialog {
       public void actionPerformed(ActionEvent e) {
         final Project project = sourceMethod.getProject();
         final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
-        final TreeClassChooserDialog chooser =
-          new TreeClassChooserDialog(RefactorJBundle.message("select.wrapper.class"), project, scope, null, null);
+        final TreeJavaClassChooserDialog chooser =
+          new TreeJavaClassChooserDialog(RefactorJBundle.message("select.wrapper.class"), project, scope, null, null);
         final String classText = existingClassField.getText();
         final PsiClass currentClass = JavaPsiFacade.getInstance(project).findClass(classText, GlobalSearchScope.allScope(project));
         if (currentClass != null) {
-          chooser.selectClass(currentClass);
+          chooser.select(currentClass);
         }
         chooser.show();
-        final PsiClass selectedClass = chooser.getSelectedClass();
+        final PsiClass selectedClass = chooser.getSelected();
         if (selectedClass != null) {
           final String className = selectedClass.getQualifiedName();
           existingClassField.setText(className);
index 3377fc24f5b2b573ad9cfd1107dfe29443f424a7..8ba26c80da2a814f2ce611f37b208bc81256dff9 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.intellij.refactoring.move.moveMembers;
 
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.ide.util.PackageUtil;
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
@@ -379,7 +380,7 @@ public class MoveMembersDialog extends RefactoringDialog implements MoveMembersO
   private class ChooseClassAction implements ActionListener {
     public void actionPerformed(ActionEvent e) {
       TreeClassChooser chooser = TreeClassChooserFactory.getInstance(myProject).createWithInnerClassesScopeChooser(
-        RefactoringBundle.message("choose.destination.class"), GlobalSearchScope.projectScope(myProject), new TreeClassChooser.ClassFilter() {
+        RefactoringBundle.message("choose.destination.class"), GlobalSearchScope.projectScope(myProject), new ClassFilter() {
         public boolean isAccepted(PsiClass aClass) {
           return aClass.getParent() instanceof PsiFile || aClass.hasModifierProperty(PsiModifier.STATIC);
         }
@@ -395,7 +396,7 @@ public class MoveMembersDialog extends RefactoringDialog implements MoveMembersO
       }
 
       chooser.showDialog();
-      PsiClass aClass = chooser.getSelectedClass();
+      PsiClass aClass = chooser.getSelected();
       if (aClass != null) {
         myTfTargetClassName.setText(aClass.getQualifiedName());
         myMemberInfoModel.updateTargetClass();
index 7c0e18a9e65fdf6f862a514c769d289274eb17a1..8603fe0a3ee61cf604eda4d5fad49c26581e8003 100644 (file)
@@ -230,10 +230,10 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
         final String classText = myExistentClassTF.getText();
         final PsiClass currentClass = JavaPsiFacade.getInstance(myProject).findClass(classText, GlobalSearchScope.allScope(myProject));
         if (currentClass != null) {
-          chooser.selectClass(currentClass);
+          chooser.select(currentClass);
         }
         chooser.showDialog();
-        final PsiClass selectedClass = chooser.getSelectedClass();
+        final PsiClass selectedClass = chooser.getSelected();
         if (selectedClass != null) {
           myExistentClassTF.setText(selectedClass.getQualifiedName());
         }
index 0c8773c5ea3e6b33468b22c0f596f3b095be9fe1..16f35ea4d6519fb0e16542e8c858a2d5c809035e 100644 (file)
@@ -170,7 +170,7 @@ public class ReplaceConstructorWithFactoryDialog extends RefactoringDialog {
         RefactoringBundle.message("choose.destination.class"));
       chooser.selectDirectory(myContainingClass.getContainingFile().getContainingDirectory());
       chooser.showDialog();
-      PsiClass aClass = chooser.getSelectedClass();
+      PsiClass aClass = chooser.getSelected();
       if (aClass != null) {
         myTfTargetClassName.setText(aClass.getQualifiedName());
       }
index 4d4b32d48f7952c8c14f900fd13fe0683625fb48..43a58670cbdc5f9d620c6d7768d67403e73cf553 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.intellij.refactoring.ui;
 
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
 import com.intellij.openapi.editor.Document;
@@ -72,7 +73,7 @@ public class ClassNameReferenceEditor extends ReferenceEditorWithBrowseButton {
     public void actionPerformed(ActionEvent e) {
       TreeClassChooser chooser = TreeClassChooserFactory.getInstance(myProject).createWithInnerClassesScopeChooser(myChooserTitle,
                                                                                                                    GlobalSearchScope.projectScope(myProject),
-                                                                                                                   new TreeClassChooser.ClassFilter() {
+                                                                                                                   new ClassFilter() {
         public boolean isAccepted(PsiClass aClass) {
           return aClass.getParent() instanceof PsiJavaFile || aClass.hasModifierProperty(PsiModifier.STATIC);
         }
@@ -81,7 +82,7 @@ public class ClassNameReferenceEditor extends ReferenceEditorWithBrowseButton {
         chooser.selectDirectory(mySelectedClass.getContainingFile().getContainingDirectory());
       }
       chooser.showDialog();
-      mySelectedClass = chooser.getSelectedClass();
+      mySelectedClass = chooser.getSelected();
       if (mySelectedClass != null) {
         setText(mySelectedClass.getQualifiedName());
       }
index fab67d6024975b310656d7d3cb8f0aff72528ab1..7b1b77b51b6ce7f988249d84fcafc1a79f683396 100644 (file)
@@ -267,10 +267,10 @@ class WrapReturnValueDialog extends RefactoringDialog {
         final String classText = existingClassField.getText();
         final PsiClass currentClass = JavaPsiFacade.getInstance(myProject).findClass(classText, GlobalSearchScope.allScope(myProject));
         if (currentClass != null) {
-          chooser.selectClass(currentClass);
+          chooser.select(currentClass);
         }
         chooser.showDialog();
-        final PsiClass selectedClass = chooser.getSelectedClass();
+        final PsiClass selectedClass = chooser.getSelected();
         if (selectedClass != null) {
           existingClassField.setText(selectedClass.getQualifiedName());
         }
index ca3abf3010f9c4818f7d289a141673ff3c2fff51..10b46187a741f992aed836be6b08755bd9894de0 100644 (file)
@@ -495,7 +495,7 @@ public class CreateTestDialog extends DialogWrapper {
       TreeClassChooser dialog =
         f.createAllProjectScopeChooser(CodeInsightBundle.message("intention.create.test.dialog.choose.super.class"));
       dialog.showDialog();
-      PsiClass aClass = dialog.getSelectedClass();
+      PsiClass aClass = dialog.getSelected();
       if (aClass != null) {
         mySuperClassField.setText(aClass.getQualifiedName());
       }
index 8601e74478a5de91dcca485b2dd7ae2c58b7f2db..ac38c459932a4e7ae223ddb84b0dc7fa0b8210c6 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.intellij.util.xml.ui;
 
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
 import com.intellij.openapi.editor.Document;
@@ -78,11 +79,11 @@ public class PsiClassControl extends EditorTextFieldControl<PsiClassPanel> {
         final DomElement domElement = control.getDomElement();
         ExtendClass extend = domElement.getAnnotation(ExtendClass.class);
         PsiClass baseClass = null;
-        TreeClassChooser.ClassFilter filter = null;
+        ClassFilter filter = null;
         if (extend != null) {
           baseClass = JavaPsiFacade.getInstance(control.getProject()).findClass(extend.value(), resolveScope);
           if (extend.instantiatable()) {
-            filter = TreeClassChooser.INSTANTIATABLE;
+            filter = ClassFilter.INSTANTIABLE;
           }
         }
 
@@ -96,7 +97,7 @@ public class PsiClassControl extends EditorTextFieldControl<PsiClassPanel> {
         TreeClassChooser chooser = TreeClassChooserFactory.getInstance(control.getProject())
           .createInheritanceClassChooser(UIBundle.message("choose.class"), resolveScope, baseClass, initialClass, filter);
         chooser.showDialog();
-        final PsiClass psiClass = chooser.getSelectedClass();
+        final PsiClass psiClass = chooser.getSelected();
         if (psiClass != null) {
           control.setValue(psiClass.getQualifiedName());
         }
index 2fce5d20c4335d458097589bde3c88e5981f9e3a..3e3d860e334872bd41727829d16b40272abede2d 100644 (file)
@@ -78,7 +78,7 @@ public class PsiClassTableCellEditor extends AbstractTableCellEditor {
         TreeClassChooser chooser = TreeClassChooserFactory.getInstance(myProject)
           .createInheritanceClassChooser(UIBundle.message("choose.class"), mySearchScope, null, true, true, Conditions.alwaysTrue());
         chooser.showDialog();
-        final PsiClass psiClass = chooser.getSelectedClass();
+        final PsiClass psiClass = chooser.getSelected();
         if (psiClass != null) {
           myEditor.setText(psiClass.getQualifiedName());
         }
diff --git a/java/java-tests/testData/codeInsight/completion/normal/FinalInForLoop.java b/java/java-tests/testData/codeInsight/completion/normal/FinalInForLoop.java
new file mode 100644 (file)
index 0000000..14705a9
--- /dev/null
@@ -0,0 +1,7 @@
+public class Foooo {
+
+    {
+        for (fin<caret>x)
+    }
+
+}
diff --git a/java/java-tests/testData/codeInsight/completion/normal/SpaceAfterReturn.java b/java/java-tests/testData/codeInsight/completion/normal/SpaceAfterReturn.java
new file mode 100644 (file)
index 0000000..de9477c
--- /dev/null
@@ -0,0 +1,8 @@
+public abstract class Zzza {
+
+    int foo() {
+        ret<caret>x
+    }
+
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/normal/SpaceAfterReturn_after.java b/java/java-tests/testData/codeInsight/completion/normal/SpaceAfterReturn_after.java
new file mode 100644 (file)
index 0000000..3b12fd4
--- /dev/null
@@ -0,0 +1,8 @@
+public abstract class Zzza {
+
+    int foo() {
+        return <caret>x
+    }
+
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-partial/expressions/New15.txt b/java/java-tests/testData/psi/parser-partial/expressions/New15.txt
new file mode 100644 (file)
index 0000000..80407ed
--- /dev/null
@@ -0,0 +1,24 @@
+PsiJavaFile:New15.java
+  PsiMethodCallExpression:new C<?>.B()
+    PsiReferenceExpression:new C<?>.B
+      PsiNewExpression:new C<?>
+        PsiKeyword:new('new')
+        PsiReferenceParameterList
+          <empty list>
+        PsiWhiteSpace(' ')
+        PsiJavaCodeReferenceElement:C<?>
+          PsiIdentifier:C('C')
+          PsiReferenceParameterList
+            PsiJavaToken:LT('<')
+            PsiTypeElement:?
+              PsiJavaToken:QUEST('?')
+            PsiJavaToken:GT('>')
+        PsiErrorElement:'(' or '[' expected
+          <empty list>
+      PsiJavaToken:DOT('.')
+      PsiReferenceParameterList
+        <empty list>
+      PsiIdentifier:B('B')
+    PsiExpressionList
+      PsiJavaToken:LPARENTH('(')
+      PsiJavaToken:RPARENTH(')')
\ No newline at end of file
index 661ec57195c4b026f25ad97e08b29dd93f8c65ab..2dd319a56d864c6f624d3f9a83e120c2d0bb3f54 100644 (file)
@@ -613,6 +613,12 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
     configureByFile(getTestName(false) + ".java")
   }
 
+  public void testFinalInForLoop() throws Throwable {
+    configure()
+    checkResultByFile(getTestName(false) + ".java")
+    assertOrderedEquals myFixture.lookupElementStrings, 'final'
+  }
+
   public void testPrimitiveTypesInForLoop() throws Throwable { doPrimitiveTypeTest() }
   public void testPrimitiveTypesInForLoop2() throws Throwable { doPrimitiveTypeTest() }
   public void testPrimitiveTypesInForLoop3() throws Throwable { doPrimitiveTypeTest() }
@@ -684,6 +690,12 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
 
   public void testSecondAnonymousClassParameter() throws Throwable { doTest(); }
 
+  public void testSpaceAfterReturn() throws Throwable {
+    configure()
+    type '\n'
+    checkResultByFile(getTestName(false) + "_after.java")
+  }
+
   public void testCastInstanceofedQualifier() throws Throwable { doTest(); }
   public void testCastComplexInstanceofedQualifier() throws Throwable { doTest(); }
 
index 6b294d9083fc67b728ec71e7e31874dcfcccd3f3..0e730aeed991f82bdac565717ddffc03d887567e 100644 (file)
@@ -72,6 +72,7 @@ public class ExpressionParserTest extends JavaParsingTestCase {
   public void testNew12() { doParserTest("new int[1][2]"); }
   public void testNew13() { doParserTest("new int[1][][2]"); }
   public void testNew14() { doParserTest("Q.new A()"); }
+  public void testNew15() { doParserTest("new C<?>.B()"); }
 
   public void testExprList0() { doParserTest("f(1,2)"); }
   public void testExprList1() { doParserTest("f("); }
index 805970e0b8bda39b96f64e4814bfe43e2366fe09..4a5662fcaedb1f3260c75f18b10cf11dd98961af 100644 (file)
@@ -56,7 +56,7 @@ public class ReferenceParserTest extends JavaParsingTestCase {
     doParserTest(text, new TestParser() {
       @Override
       public void parse(final PsiBuilder builder) {
-        ReferenceParser.parseJavaCodeReference(builder, incomplete, false, false, false);
+        ReferenceParser.parseJavaCodeReference(builder, incomplete, false, false, false, false);
       }
     });
   }
diff --git a/java/openapi/src/com/intellij/ide/util/ClassFilter.java b/java/openapi/src/com/intellij/ide/util/ClassFilter.java
new file mode 100644 (file)
index 0000000..8b1fc2e
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2010 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.util;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiUtil;
+
+/**
+* @author traff
+*/
+public interface ClassFilter {
+  ClassFilter INSTANTIABLE = new ClassFilter() {
+    public boolean isAccepted(PsiClass aClass) {
+      return PsiUtil.isInstantiatable(aClass);
+    }
+  };
+
+  boolean isAccepted(PsiClass aClass);
+  ClassFilter ALL = new ClassFilter() {
+    public boolean isAccepted(PsiClass aClass) {
+      return true;
+    }
+  };
+
+  interface ClassFilterWithScope extends ClassFilter {
+    GlobalSearchScope getScope();
+  }
+}
index 3605bd4f3bed0944764be8642afaa6da1b2d44ad..9a9536cbbe811f6d87a37934a9c4630fda7bc2dd 100644 (file)
@@ -17,43 +17,19 @@ package com.intellij.ide.util;
 
 import com.intellij.psi.PsiClass;
 import com.intellij.psi.PsiDirectory;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.search.GlobalSearchScope;
 
 /**
  * User: anna
  * Date: Jan 24, 2005
  */
-public interface TreeClassChooser{
-  ClassFilter INSTANTIATABLE = new ClassFilter() {
-    public boolean isAccepted(PsiClass aClass) {
-      return PsiUtil.isInstantiatable(aClass);
-    }
-  };
+public interface TreeClassChooser extends TreeChooser<PsiClass> {
+  PsiClass getSelected();
 
-  PsiClass getSelectedClass();
-
-  void selectClass(final PsiClass aClass);
+  void select(final PsiClass aClass);
 
   void selectDirectory(final PsiDirectory directory);
 
   void showDialog();
 
   void showPopup();
-
-  interface ClassFilter {
-    boolean isAccepted(PsiClass aClass);
-    ClassFilter ALL = new ClassFilter() {
-      public boolean isAccepted(PsiClass aClass) {
-        return true;
-      }
-    };
-  }
-
-  interface ClassFilterWithScope extends ClassFilter {
-    GlobalSearchScope getScope();
-  }
-
-  interface InheritanceClassFilter extends ClassFilter{
-  }
 }
index 6e0afd853e070a682f4c173723e9cf8020da31f4..2a8d4cd65ded9c295500debd1a784b2cfe9a3303 100644 (file)
@@ -39,14 +39,14 @@ public abstract class TreeClassChooserFactory {
   @NotNull
   public abstract TreeClassChooser createWithInnerClassesScopeChooser(String title,
                                                                       GlobalSearchScope scope,
-                                                                      final TreeClassChooser.ClassFilter classFilter,
+                                                                      final ClassFilter classFilter,
                                                                       @Nullable PsiClass initialClass);
 
 
   @NotNull
   public abstract TreeClassChooser createNoInnerClassesScopeChooser(String title,
                                                                     GlobalSearchScope scope,
-                                                                    TreeClassChooser.ClassFilter classFilter,
+                                                                    ClassFilter classFilter,
                                                                     @Nullable PsiClass initialClass);
 
 
@@ -81,7 +81,7 @@ public abstract class TreeClassChooserFactory {
                                                                  GlobalSearchScope scope,
                                                                  PsiClass base,
                                                                  PsiClass initialClass,
-                                                                 TreeClassChooser.ClassFilter classFilter);
+                                                                 ClassFilter classFilter);
 
 
   @NotNull
index b475e65c66c488fc25bcb37386f84b40be6ac1f6..f0e13a1ca808261595e11172ea8ccddfd2012cc3 100644 (file)
@@ -20,8 +20,8 @@
  */
 package com.intellij.ui.classFilter;
 
-import com.intellij.ide.util.TreeClassChooser;
-import com.intellij.ide.util.TreeClassChooserFactory;
+import com.intellij.ide.util.*;
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.PsiClass;
 import com.intellij.psi.search.GlobalSearchScope;
@@ -55,13 +55,13 @@ public class ClassFilterEditor extends JPanel {
   protected JButton myAddPatternButton;
   private JButton myRemoveButton;
   protected Project myProject;
-  private TreeClassChooser.ClassFilter myChooserFilter;
+  private ClassFilter myChooserFilter;
 
   public ClassFilterEditor(Project project) {
     this (project, null);
   }
 
-  public ClassFilterEditor(Project project, TreeClassChooser.ClassFilter classFilter) {
+  public ClassFilterEditor(Project project, com.intellij.ide.util.ClassFilter classFilter) {
     super(new GridBagLayout());
     myAddClassButton = new JButton(getAddButtonText());
     myAddPatternButton = new JButton(getAddPatternButtonText());
@@ -144,11 +144,11 @@ public class ClassFilterEditor extends JPanel {
     return UIBundle.message("button.add.pattern");
   }
 
-  public void setFilters(ClassFilter[] filters) {
+  public void setFilters(com.intellij.ui.classFilter.ClassFilter[] filters) {
     myTableModel.setFilters(filters);
   }
 
-  public ClassFilter[] getFilters() {
+  public com.intellij.ui.classFilter.ClassFilter[] getFilters() {
     return myTableModel.getFilters();
   }
 
@@ -170,11 +170,11 @@ public class ClassFilterEditor extends JPanel {
   }
 
   protected final class FilterTableModel extends AbstractTableModel implements ItemRemovable{
-    private final List<ClassFilter> myFilters = new LinkedList<ClassFilter>();
+    private final List<com.intellij.ui.classFilter.ClassFilter> myFilters = new LinkedList<com.intellij.ui.classFilter.ClassFilter>();
     public static final int CHECK_MARK = 0;
     public static final int FILTER = 1;
 
-    public final void setFilters(ClassFilter[] filters) {
+    public final void setFilters(com.intellij.ui.classFilter.ClassFilter[] filters) {
       myFilters.clear();
       if (filters != null) {
         ContainerUtil.addAll(myFilters, filters);
@@ -182,26 +182,26 @@ public class ClassFilterEditor extends JPanel {
       fireTableDataChanged();
     }
 
-    public ClassFilter[] getFilters() {
-      for (Iterator<ClassFilter> it = myFilters.iterator(); it.hasNext();) {
-        ClassFilter filter = it.next();
+    public com.intellij.ui.classFilter.ClassFilter[] getFilters() {
+      for (Iterator<com.intellij.ui.classFilter.ClassFilter> it = myFilters.iterator(); it.hasNext();) {
+        com.intellij.ui.classFilter.ClassFilter filter = it.next();
         String pattern = filter.getPattern();
         if (pattern == null || "".equals(pattern)) {
           it.remove();
         }
       }
-      return myFilters.toArray(new ClassFilter[myFilters.size()]);
+      return myFilters.toArray(new com.intellij.ui.classFilter.ClassFilter[myFilters.size()]);
     }
 
-    public ClassFilter getFilterAt(int index) {
+    public com.intellij.ui.classFilter.ClassFilter getFilterAt(int index) {
       return myFilters.get(index);
     }
 
-    public int getFilterIndex(ClassFilter filter) {
+    public int getFilterIndex(com.intellij.ui.classFilter.ClassFilter filter) {
       return myFilters.indexOf(filter);
     }
 
-    public void addRow(ClassFilter filter) {
+    public void addRow(com.intellij.ui.classFilter.ClassFilter filter) {
       myFilters.add(filter);
       int row = myFilters.size() - 1;
       fireTableRowsInserted(row, row);
@@ -216,7 +216,7 @@ public class ClassFilterEditor extends JPanel {
     }
 
     public Object getValueAt(int rowIndex, int columnIndex) {
-      ClassFilter filter = myFilters.get(rowIndex);
+      com.intellij.ui.classFilter.ClassFilter filter = myFilters.get(rowIndex);
       if (columnIndex == FILTER) {
         return filter;
       }
@@ -227,7 +227,7 @@ public class ClassFilterEditor extends JPanel {
     }
 
     public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
-      ClassFilter filter = myFilters.get(rowIndex);
+      com.intellij.ui.classFilter.ClassFilter filter = myFilters.get(rowIndex);
       if (columnIndex == FILTER) {
         filter.setPattern(aValue != null? aValue.toString() : "");
       }
@@ -265,7 +265,7 @@ public class ClassFilterEditor extends JPanel {
         ((JLabel)component).setBorder(noFocusBorder);
       }
       UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, color);
-      ClassFilter filter = (ClassFilter)table.getValueAt(row, FilterTableModel.FILTER);
+      com.intellij.ui.classFilter.ClassFilter filter = (com.intellij.ui.classFilter.ClassFilter)table.getValueAt(row, FilterTableModel.FILTER);
       component.setEnabled(ClassFilterEditor.this.isEnabled() && filter.isEnabled());
       return component;
     }
@@ -287,8 +287,8 @@ public class ClassFilterEditor extends JPanel {
   }
 
   @NotNull
-  protected ClassFilter createFilter(String pattern){
-    return new ClassFilter(pattern);
+  protected com.intellij.ui.classFilter.ClassFilter createFilter(String pattern){
+    return new com.intellij.ui.classFilter.ClassFilter(pattern);
   }
 
   protected void addPatternFilter() {
@@ -297,7 +297,7 @@ public class ClassFilterEditor extends JPanel {
     if (dialog.isOK()) {
       String pattern = dialog.getPattern();
       if (pattern != null) {
-        ClassFilter filter = createFilter(pattern);
+        com.intellij.ui.classFilter.ClassFilter filter = createFilter(pattern);
         myTableModel.addRow(filter);
         int row = myTableModel.getRowCount() - 1;
         myTable.getSelectionModel().setSelectionInterval(row, row);
@@ -312,9 +312,9 @@ public class ClassFilterEditor extends JPanel {
     TreeClassChooser chooser = TreeClassChooserFactory.getInstance(myProject).createNoInnerClassesScopeChooser(
       UIBundle.message("class.filter.editor.choose.class.title"), GlobalSearchScope.allScope(myProject), myChooserFilter, null);
     chooser.showDialog();
-    PsiClass selectedClass = chooser.getSelectedClass();
+    PsiClass selectedClass = chooser.getSelected();
     if (selectedClass != null) {
-      ClassFilter filter = createFilter(getJvmClassName(selectedClass));
+      com.intellij.ui.classFilter.ClassFilter filter = createFilter(getJvmClassName(selectedClass));
       myTableModel.addRow(filter);
       int row = myTableModel.getRowCount() - 1;
       myTable.getSelectionModel().setSelectionInterval(row, row);
@@ -338,7 +338,7 @@ public class ClassFilterEditor extends JPanel {
   }
 
   public void addPattern(String pattern) {
-    ClassFilter filter = createFilter(pattern);
+    com.intellij.ui.classFilter.ClassFilter filter = createFilter(pattern);
     myTableModel.addRow(filter);
   }
 
index 8b10403aef959d192bea4fac156663050cd84428..79695e91aa1cceaa318bf772b87a74b586e622ca 100644 (file)
@@ -81,7 +81,7 @@ class ClassFilterEditorAddDialog extends DialogWrapper {
           }
         }
         chooser.showDialog();
-        PsiClass selectedClass = chooser.getSelectedClass();
+        PsiClass selectedClass = chooser.getSelected();
         if (selectedClass != null) {
           myClassName.setText(selectedClass.getQualifiedName());
         }
index ff861f5513849272b99d0be8adbe7632e494ac49..faed33a571bcd983d26c00b9952f86586fbadde1 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.intellij.util.xml.actions;
 
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
 import com.intellij.openapi.application.ApplicationManager;
@@ -54,14 +55,14 @@ public abstract class CreateClassMappingAction<T extends DomElement> extends Cre
     if (!ApplicationManager.getApplication().isUnitTestMode()) {
       PsiClass baseClass = getBaseClass(context, project, myBaseClass);
       TreeClassChooser chooser = TreeClassChooserFactory.getInstance(project)
-        .createInheritanceClassChooser(getChooserTitle(), GlobalSearchScope.allScope(project), baseClass, null, new TreeClassChooser.ClassFilter() {
+        .createInheritanceClassChooser(getChooserTitle(), GlobalSearchScope.allScope(project), baseClass, null, new ClassFilter() {
           @Override
           public boolean isAccepted(PsiClass aClass) {
             return !aClass.isInterface() && !aClass.hasModifierProperty(PsiModifier.ABSTRACT);
           }
         });
       chooser.showDialog();
-      selectedClass = chooser.getSelectedClass();
+      selectedClass = chooser.getSelected();
     }
     else {
       selectedClass = getBaseClass(context, project, myBaseClass == null ? "java.lang.Object" : myBaseClass);
index 0d651e3cb9a4b22ba8ce7befbfb2f048f787e0bb..84b44292f99f9230cb85ab8d2a6bc042c02e3875 100644 (file)
@@ -15,6 +15,8 @@
  */
 package com.intellij.codeInsight.completion;
 
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -26,5 +28,8 @@ public abstract class CompletionConfidence {
   @Nullable
   public abstract Boolean shouldFocusLookup(@NotNull CompletionParameters parameters);
 
-
+  @Nullable
+  public Boolean shouldSkipAutopopup(@Nullable PsiElement contextElement, @NotNull PsiFile psiFile, int offset) {
+    return null;
+  }
 }
index dd7e941c62531e48e6883484e54974deefc218a0..7d3dd6825fc047e3e6102547bb05a286ef9fa4df 100644 (file)
@@ -193,6 +193,23 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
     };
     if (autopopup) {
       CommandProcessor.getInstance().runUndoTransparentAction(initCmd);
+
+      int offset = editor.getCaretModel().getOffset();
+
+      PsiElement elementAt = InjectedLanguageUtil.findInjectedElementNoCommit(psiFile, offset);
+      if (elementAt == null) {
+        elementAt = psiFile.findElementAt(offset);
+        if (elementAt == null && offset > 0) {
+          elementAt = psiFile.findElementAt(offset - 1);
+        }
+      }
+
+      Language language = elementAt != null ? PsiUtilBase.findLanguageFromElement(elementAt):psiFile.getLanguage();
+
+      for (CompletionConfidence confidence : CompletionConfidenceEP.forLanguage(language)) {
+        final Boolean result = confidence.shouldSkipAutopopup(elementAt, psiFile, offset); // TODO: Peter Lazy API
+        if (result == Boolean.TRUE) return;
+      }
     } else {
       CommandProcessor.getInstance().executeCommand(project, initCmd, null, null);
     }
index 878f97c9e7f3023b222b131a45817ace3fddeb7f..e842a0efbe29792af2b78716792012783d9bdc02 100644 (file)
@@ -622,6 +622,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
       final String newPrefix = text.subSequence(pair.first, caretOffset).toString();
       if (pair.second.accepts(newPrefix)) {
         scheduleRestart();
+        myRestartingPrefixConditions.clear();
         return;
       }
     }
@@ -635,6 +636,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     final int offset = myEditor.getCaretModel().getOffset();
     final long stamp = myEditor.getDocument().getModificationStamp();
     final Project project = getProject();
+    final boolean wasDumb = DumbService.getInstance(project).isDumb();
     ApplicationManager.getApplication().invokeLater(new Runnable() {
       @Override
       public void run() {
@@ -646,6 +648,10 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
           return;
         }
 
+        if (!wasDumb && DumbService.getInstance(project).isDumb()) {
+          return;
+        }
+
         if (myEditor.getCaretModel().getOffset() != offset || myEditor.getDocument().getModificationStamp() != stamp) {
           return;
         }
index 7a545f68a9a74772710f1c1dd1be80913c9cce45..fc38b698fa13d00a7d71244ce20f1a0ac8958e46 100644 (file)
@@ -21,7 +21,6 @@ import com.intellij.codeInsight.lookup.LookupElement;
 import com.intellij.codeInsight.lookup.LookupElementPresentation;
 import com.intellij.navigation.ChooseByNameContributor;
 import com.intellij.openapi.actionSystem.IdeActions;
-import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.fileTypes.FileNameMatcher;
 import com.intellij.openapi.fileTypes.FileType;
@@ -32,7 +31,6 @@ import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.ProjectFileIndex;
 import com.intellij.openapi.roots.ProjectRootManager;
-import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.StringUtil;
@@ -88,12 +86,7 @@ public class FilePathCompletionContributor extends CompletionContributor {
         final PsiElement e = parameters.getPosition();
         final Project project = e.getProject();
 
-        final PsiReference psiReference = ApplicationManager.getApplication().runReadAction(new Computable<PsiReference>() {
-          public PsiReference compute() {
-            //noinspection ConstantConditions
-            return parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset());
-          }
-        });
+        final PsiReference psiReference = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset());
 
         final Pair<FileReference, Boolean> fileReferencePair = getReference(psiReference);
         if (fileReferencePair != null) {
@@ -102,11 +95,17 @@ public class FilePathCompletionContributor extends CompletionContributor {
 
           final FileReferenceSet set = first.getFileReferenceSet();
           String prefix = set.getPathString().substring(0, parameters.getOffset() - set.getElement().getTextRange().getStartOffset() - set.getStartInElement());
+          final String textBeforePosition = e.getContainingFile().getText().substring(0, parameters.getOffset());
+          if (!textBeforePosition.endsWith(prefix)) {
+            final int len = textBeforePosition.length();
+            final String fragment = len > 100 ? textBeforePosition.substring(len - 100) : textBeforePosition;
+            throw new AssertionError("prefix should be some actual file string just before caret: " + prefix + "\n text=" + fragment + ";\npathString=" + set.getPathString() + ";\nelementText=" + e.getParent().getText());
+          }
           
-          final List<String>[] pathPrefixParts = new List[] {null};
+          List<String> pathPrefixParts = null;
           int lastSlashIndex;
           if ((lastSlashIndex = prefix.lastIndexOf('/')) != -1) {
-            pathPrefixParts[0] = StringUtil.split(prefix.substring(0, lastSlashIndex), "/");
+            pathPrefixParts = StringUtil.split(prefix.substring(0, lastSlashIndex), "/");
             prefix = prefix.substring(lastSlashIndex + 1);
           }
 
@@ -133,28 +132,20 @@ public class FilePathCompletionContributor extends CompletionContributor {
               for (final String name : resultNames) {
                 ProgressManager.checkCanceled();
 
-                final PsiFile[] files = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile[]>() {
-                  public PsiFile[] compute() {
-                    return FilenameIndex.getFilesByName(project, name, scope);
-                  }
-                });
+                final PsiFile[] files = FilenameIndex.getFilesByName(project, name, scope);
 
                 if (files.length > 0) {
                   for (final PsiFile file : files) {
                     ProgressManager.checkCanceled();
 
-                    ApplicationManager.getApplication().runReadAction(new Runnable() {
-                      public void run() {
-                        final VirtualFile virtualFile = file.getVirtualFile();
-                        if (virtualFile != null && virtualFile.isValid() && virtualFile != contextFile) {
-                          if (contextHelper.isMine(project, virtualFile)) {
-                            if (pathPrefixParts[0] == null || fileMatchesPathPrefix(contextHelper.getPsiFileSystemItem(project, virtualFile), pathPrefixParts[0])) {
-                              __result.addElement(new FilePathLookupItem(file, contextHelper));
-                            }
-                          }
+                    final VirtualFile virtualFile = file.getVirtualFile();
+                    if (virtualFile != null && virtualFile.isValid() && virtualFile != contextFile) {
+                      if (contextHelper.isMine(project, virtualFile)) {
+                        if (pathPrefixParts == null || fileMatchesPathPrefix(contextHelper.getPsiFileSystemItem(project, virtualFile), pathPrefixParts)) {
+                          __result.addElement(new FilePathLookupItem(file, contextHelper));
                         }
                       }
-                    });
+                    }
                   }
                 }
               }
@@ -220,11 +211,7 @@ public class FilePathCompletionContributor extends CompletionContributor {
     final ChooseByNameContributor[] nameContributors = ChooseByNameContributor.FILE_EP_NAME.getExtensions();
     for (final ChooseByNameContributor contributor : nameContributors) {
       try {
-        names.addAll(ApplicationManager.getApplication().runReadAction(new Computable<Collection<? extends String>>() {
-          public Collection<? extends String> compute() {
-            return Arrays.asList(contributor.getNames(project, false));
-          }
-        }));
+        names.addAll(Arrays.asList(contributor.getNames(project, false)));
       }
       catch (ProcessCanceledException ex) {
         // index corruption detected, ignore
index 3a7324a1cba6a1d527f1f8fff8ef0905c0876555..63fff98a87e4244b8efae9fee00ae76e596f1d4d 100644 (file)
@@ -113,8 +113,7 @@ public class WordCompletionContributor extends CompletionContributor implements
       return true;
     }
 
-    final CompletionProcess completion = CompletionService.getCompletionService().getCurrentCompletion();
-    if (completion == null || !completion.isAutopopupCompletion()) {
+    if (parameters.getInvocationCount() > 0) {
       return true;
     }
 
index fec51dee66710d7a9192a19ca7da9a1c3ec00af8..dfa056a02260170037082af3e047ec7d9f53f418 100644 (file)
@@ -93,9 +93,14 @@ public class ShowJavaDocInfoAction extends BaseCodeInsightAction implements Hint
         }
 
         if (element == null && file != null) {
-          final PsiReference ref = file.findReferenceAt(editor.getCaretModel().getOffset());
-          if (ref instanceof PsiPolyVariantReference) {
-            element = ref.getElement();
+          try {
+            final PsiReference ref = file.findReferenceAt(editor.getCaretModel().getOffset());
+            if (ref instanceof PsiPolyVariantReference) {
+              element = ref.getElement();
+            }
+          }
+          catch (IndexNotReadyException e) {
+            element = null;
           }
         }
       }
index 3be94618a300e45183ffc99d0895806d9be27e0b..a84084c873225b0786d9206e46b6b2748f174222 100644 (file)
@@ -34,6 +34,7 @@ import com.intellij.openapi.fileEditor.FileEditorManagerAdapter;
 import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
 import com.intellij.openapi.fileEditor.FileEditorManagerListener;
 import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.project.DumbService;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Key;
 import com.intellij.psi.PsiFile;
@@ -98,6 +99,7 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
         if (project.isDisposed() || !file.isValid()) return;
         if (editor.isDisposed() || isMainEditor && FileEditorManager.getInstance(project).getSelectedTextEditor() != editor) return;
         if (ApplicationManager.getApplication().isWriteAccessAllowed()) return; //it will fail anyway
+        if (DumbService.getInstance(project).isDumb()) return;
 
         new CodeCompletionHandlerBase(CompletionType.BASIC, false, true).invoke(project, editor);
 
index 02fafa6acb7310b9656f5a08a0f9af8ec3fe8a86..b5f0794f5e72aedea52c916d5cbc02fb10bf2440 100644 (file)
@@ -115,6 +115,10 @@ public class EnterHandler extends BaseEnterHandler {
 
     for(EnterHandlerDelegate delegate: Extensions.getExtensions(EnterHandlerDelegate.EP_NAME)) {
       EnterHandlerDelegate.Result result = delegate.preprocessEnter(file, editor, caretOffsetRef, caretAdvanceRef, dataContext, myOriginalHandler);
+      if (caretOffsetRef.get() > document.getTextLength()) {
+        throw new AssertionError("Wrong caret offset change by " + delegate);
+      }
+
       if (result == EnterHandlerDelegate.Result.Stop) return;
       if (result != EnterHandlerDelegate.Result.Continue) {
         text = document.getCharsSequence();
index 87c324f654fdfa5e85abb3b525e9cd9ac2f8e17a..9d79a0668894dd9caa6bb211aa518fd58810958f 100644 (file)
@@ -213,7 +213,6 @@ public class FacetManagerImpl extends FacetManager implements ModuleComponent, P
 
   private void addInvalidFacet(final FacetState state, ModifiableFacetModel model, final Facet underlyingFacet, final String errorMessage) {
     final InvalidFacetManager invalidFacetManager = InvalidFacetManager.getInstance(myModule.getProject());
-    final String typeId = StringUtil.notNullize(state.getFacetType());
     final InvalidFacetType type = InvalidFacetType.getInstance();
     final InvalidFacetConfiguration configuration = new InvalidFacetConfiguration(state, errorMessage);
     final InvalidFacet facet = createFacet(type, StringUtil.notNullize(state.getName()), configuration, underlyingFacet);
index ed522a8e333342e6991d02616ef14b50ab769849..1cc127ca2cab32400c5327ee1a7106ebbbce0c97 100644 (file)
@@ -57,7 +57,6 @@ public class ProjectTreeBuilder extends BaseProjectTreeBuilder {
   private final MyFileStatusListener myFileStatusListener;
 
   private final CopyPasteUtil.DefaultCopyPasteListener myCopyPasteListener;
-  //private final PropertiesFileListener myPropertiesFileListener;
   private final WolfTheProblemSolver.ProblemListener myProblemListener;
 
   public ProjectTreeBuilder(final Project project, JTree tree, DefaultTreeModel treeModel, Comparator<NodeDescriptor> comparator, ProjectAbstractTreeStructureBase treeStructure) {
@@ -82,11 +81,6 @@ public class ProjectTreeBuilder extends BaseProjectTreeBuilder {
     myCopyPasteListener = new CopyPasteUtil.DefaultCopyPasteListener(getUpdater());
     CopyPasteManager.getInstance().addContentChangedListener(myCopyPasteListener);
 
-    /*myPropertiesFileListener = new PropertiesFileListener();
-    final PropertiesFilesManager propertiesFilesManager = PropertiesFilesManager.getInstance();
-    if (propertiesFilesManager != null) {
-      propertiesFilesManager.addPropertiesFileListener(myPropertiesFileListener);
-    }*/
     myProblemListener = new MyProblemListener();
     WolfTheProblemSolver.getInstance(project).addProblemListener(myProblemListener);
 
@@ -100,10 +94,6 @@ public class ProjectTreeBuilder extends BaseProjectTreeBuilder {
     PsiManager.getInstance(myProject).removePsiTreeChangeListener(myPsiTreeChangeListener);
     FileStatusManager.getInstance(myProject).removeFileStatusListener(myFileStatusListener);
     CopyPasteManager.getInstance().removeContentChangedListener(myCopyPasteListener);
-   /* final PropertiesFilesManager propertiesFilesManager = PropertiesFilesManager.getInstance();
-    if (propertiesFilesManager != null) {
-      propertiesFilesManager.removePropertiesFileListener(myPropertiesFileListener);
-    }*/
     WolfTheProblemSolver.getInstance(myProject).removeProblemListener(myProblemListener);
   }
 
@@ -188,26 +178,6 @@ public class ProjectTreeBuilder extends BaseProjectTreeBuilder {
     return element;
   }
 
- /* private class PropertiesFileListener implements PropertiesFilesManager.PropertiesFileListener {
-    public void fileAdded(VirtualFile propertiesFile) {
-      fileChanged(propertiesFile, null);
-    }
-
-    public void fileRemoved(VirtualFile propertiesFile) {
-      fileChanged(propertiesFile, null);
-    }
-
-    public void fileChanged(VirtualFile propertiesFile, final VirtualFilePropertyEvent event) {
-      if (!myProject.isDisposed()) {
-        VirtualFile parent = propertiesFile.getParent();
-        if (parent != null && parent.isValid()) {
-          PsiDirectory dir = PsiManager.getInstance(myProject).findDirectory(parent);
-          myUpdater.addSubtreeToUpdateByElement(dir);
-        }
-      }
-    }
-  }*/
-
   private class MyProblemListener extends WolfTheProblemSolver.ProblemListener {
     private final Alarm myUpdateProblemAlarm = new Alarm();
     private final Collection<VirtualFile> myFilesToRefresh = new THashSet<VirtualFile>();
similarity index 57%
rename from java/java-impl/src/com/intellij/ide/util/TreeClassChooserDialog.java
rename to platform/lang-impl/src/com/intellij/ide/util/AbstractTreeClassChooserDialog.java
index 90ccecd83f0a056c30d1eb5172ed6b7732a6ff91..5d9ee72c7f6ae04b9f1733544c0c59e013c8efab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2010 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.
@@ -17,11 +17,9 @@ package com.intellij.ide.util;
 
 import com.intellij.ide.IdeBundle;
 import com.intellij.ide.projectView.BaseProjectTreeBuilder;
-import com.intellij.ide.projectView.PsiClassChildrenSource;
 import com.intellij.ide.projectView.impl.AbstractProjectTreeStructure;
 import com.intellij.ide.projectView.impl.ProjectAbstractTreeStructureBase;
 import com.intellij.ide.projectView.impl.ProjectTreeBuilder;
-import com.intellij.ide.projectView.impl.nodes.ClassTreeNode;
 import com.intellij.ide.util.gotoByName.*;
 import com.intellij.ide.util.treeView.AlphaComparator;
 import com.intellij.ide.util.treeView.NodeRenderer;
@@ -30,17 +28,15 @@ import com.intellij.openapi.application.ModalityState;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Conditions;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
 import com.intellij.pom.Navigatable;
-import com.intellij.psi.*;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiNamedElement;
 import com.intellij.psi.presentation.java.SymbolPresentationUtil;
 import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.PsiShortNamesCache;
-import com.intellij.psi.search.searches.ClassInheritorsSearch;
 import com.intellij.psi.util.PsiUtilBase;
 import com.intellij.ui.ScrollPaneFactory;
 import com.intellij.ui.TabbedPaneWrapper;
@@ -48,6 +44,7 @@ import com.intellij.ui.TreeSpeedSearch;
 import com.intellij.ui.treeStructure.Tree;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.Processor;
+import com.intellij.util.Query;
 import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -69,68 +66,64 @@ import java.awt.event.MouseEvent;
 import java.util.ArrayList;
 import java.util.List;
 
-public class TreeClassChooserDialog extends DialogWrapper implements TreeClassChooser{
+abstract public class AbstractTreeClassChooserDialog<T extends PsiNamedElement> extends DialogWrapper implements TreeChooser<T> {
   private Tree myTree;
-  private PsiClass mySelectedClass = null;
+  private T mySelectedClass = null;
   private final Project myProject;
   private BaseProjectTreeBuilder myBuilder;
   private TabbedPaneWrapper myTabbedPane;
   private ChooseByNamePanel myGotoByNamePanel;
   private final GlobalSearchScope myScope;
-  @NotNull private final ClassFilter myClassFilter;
-  private final PsiClass myBaseClass;
-  private PsiClass myInitialClass;
-  private final PsiClassChildrenSource myClassChildren;
+  @NotNull private final Filter<T> myClassFilter;
+  private final T myBaseClass;
+  private T myInitialClass;
+  private final boolean myIsShowMembers;
 
-  public TreeClassChooserDialog(String title, Project project) {
+  public AbstractTreeClassChooserDialog(String title, Project project) {
     this(title, project, null);
   }
 
-  public TreeClassChooserDialog(String title, Project project, @Nullable PsiClass initialClass) {
+  public AbstractTreeClassChooserDialog(String title, Project project, @Nullable T initialClass) {
     this(title, project, GlobalSearchScope.projectScope(project), null, initialClass);
   }
 
-  public TreeClassChooserDialog(String title, Project project, GlobalSearchScope scope, @Nullable ClassFilter classFilter, @Nullable PsiClass initialClass) {
-    this(title, project, scope, classFilter, null, initialClass, PsiClassChildrenSource.NONE);
+  public AbstractTreeClassChooserDialog(String title,
+                                        Project project,
+                                        GlobalSearchScope scope,
+                                        @Nullable Filter<T> classFilter,
+                                        @Nullable T initialClass) {
+    this(title, project, scope, classFilter, null, initialClass, false);
   }
 
-  public TreeClassChooserDialog(String title,
-                                Project project,
-                                GlobalSearchScope scope,
-                                @Nullable ClassFilter classFilter,
-                                PsiClass baseClass,
-                                @Nullable PsiClass initialClass,
-                                PsiClassChildrenSource classChildren) {
+  public AbstractTreeClassChooserDialog(String title,
+                                        Project project,
+                                        GlobalSearchScope scope,
+                                        @Nullable Filter<T> classFilter,
+                                        T baseClass,
+                                        @Nullable T initialClass,
+                                        boolean isShowMembers) {
     super(project, true);
     myScope = scope;
-    myClassFilter = classFilter == null ? ClassFilter.ALL : classFilter;
+    myClassFilter = classFilter == null ? allFilter() : classFilter;
     myBaseClass = baseClass;
     myInitialClass = initialClass;
-    myClassChildren = classChildren;
+    myIsShowMembers = isShowMembers;
     setTitle(title);
     myProject = project;
     init();
     if (initialClass != null) {
-      selectClass(initialClass);
+      select(initialClass);
     }
 
     handleSelectionChanged();
   }
 
-  public static TreeClassChooserDialog withInnerClasses(String title,
-                                                        Project project,
-                                                        GlobalSearchScope scope,
-                                                        final ClassFilter classFilter,
-                                                        @Nullable PsiClass initialClass) {
-    return new TreeClassChooserDialog(title, project, scope, classFilter, null, initialClass, new PsiClassChildrenSource() {
-      public void addChildren(PsiClass psiClass, List<PsiElement> children) {
-        ArrayList<PsiElement> innerClasses = new ArrayList<PsiElement>();
-        PsiClassChildrenSource.CLASSES.addChildren(psiClass, innerClasses);
-        for (PsiElement innerClass : innerClasses) {
-          if (classFilter.isAccepted((PsiClass)innerClass)) children.add(innerClass);
-        }
+  private Filter<T> allFilter() {
+    return new Filter<T>() {
+      public boolean isAccepted(T element) {
+        return true;
       }
-    });
+    };
   }
 
   protected JComponent createCenterPanel() {
@@ -143,7 +136,7 @@ public class TreeClassChooserDialog extends DialogWrapper implements TreeClassCh
       }
 
       public boolean isShowMembers() {
-        return myClassChildren != PsiClassChildrenSource.NONE;
+        return myIsShowMembers;
       }
 
       public boolean isHideEmptyMiddlePackages() {
@@ -266,29 +259,44 @@ public class TreeClassChooserDialog extends DialogWrapper implements TreeClassCh
   }
 
   protected ChooseByNameModel createChooseByNameModel() {
-    return myBaseClass == null ? new MyGotoClassModel(myProject) : new SubclassGotoClassModel(myProject);
+    if (myBaseClass == null) {
+      return new MyGotoClassModel(myProject, this);
+    }
+    else {
+      BaseClassInheritorsProvider<T> inheritorsProvider = getInheritorsProvider();
+      if (inheritorsProvider != null) {
+        return new SubclassGotoClassModel(myProject, this, inheritorsProvider);
+      }
+      else {
+        throw new IllegalStateException("inheritors provider is null");
+      }
+    }
   }
 
-  private void handleSelectionChanged(){
-    PsiClass selection = calcSelectedClass();
+  @Nullable
+  protected abstract BaseClassInheritorsProvider<T> getInheritorsProvider();
+
+  private void handleSelectionChanged() {
+    T selection = calcSelectedClass();
     setOKActionEnabled(selection != null);
   }
 
   protected void doOKAction() {
     mySelectedClass = calcSelectedClass();
     if (mySelectedClass == null) return;
-    if (!myClassFilter.isAccepted(mySelectedClass)){
-      Messages.showErrorDialog(myTabbedPane.getComponent(), SymbolPresentationUtil.getSymbolPresentableText(mySelectedClass) +  " is not acceptable");
+    if (!myClassFilter.isAccepted(mySelectedClass)) {
+      Messages.showErrorDialog(myTabbedPane.getComponent(),
+                               SymbolPresentationUtil.getSymbolPresentableText(mySelectedClass) + " is not acceptable");
       return;
     }
     super.doOKAction();
   }
 
-  public PsiClass getSelectedClass() {
+  public T getSelected() {
     return mySelectedClass;
   }
 
-  public void selectClass(@NotNull final PsiClass aClass) {
+  public void select(@NotNull final T aClass) {
     selectElementInTree(aClass);
   }
 
@@ -304,18 +312,18 @@ public class TreeClassChooserDialog extends DialogWrapper implements TreeClassCh
     ChooseByNamePopup popup = ChooseByNamePopup.createPopup(myProject, createChooseByNameModel(), getContext());
     popup.invoke(new ChooseByNamePopupComponent.Callback() {
       public void elementChosen(Object element) {
-        mySelectedClass = (PsiClass)element;
+        mySelectedClass = (T)element;
         ((Navigatable)element).navigate(true);
       }
     }, getModalityState(), true);
   }
 
-  private PsiClass getContext() {
+  private T getContext() {
     return myBaseClass != null ? myBaseClass : myInitialClass != null ? myInitialClass : null;
   }
 
 
-  private void selectElementInTree(@NotNull final PsiElement element) {
+  private <E extends PsiElement> void selectElementInTree(@NotNull final PsiElement element) {
     ApplicationManager.getApplication().invokeLater(new Runnable() {
       public void run() {
         if (myBuilder == null) return;
@@ -329,22 +337,22 @@ public class TreeClassChooserDialog extends DialogWrapper implements TreeClassCh
     return ModalityState.stateForComponent(getRootPane());
   }
 
+
   @Nullable
-  private PsiClass calcSelectedClass() {
-    if (myTabbedPane.getSelectedIndex() == 0) {
-      return (PsiClass)myGotoByNamePanel.getChosenElement();
+  protected T calcSelectedClass() {
+    if (getTabbedPane().getSelectedIndex() == 0) {
+      return (T)getGotoByNamePanel().getChosenElement();
     }
     else {
-      TreePath path = myTree.getSelectionPath();
+      TreePath path = getTree().getSelectionPath();
       if (path == null) return null;
       DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
-      Object userObject = node.getUserObject();
-      if (!(userObject instanceof ClassTreeNode)) return null;
-      ClassTreeNode descriptor = (ClassTreeNode)userObject;
-      return descriptor.getPsiClass();
+      return getSelectedFromTreeUserObject(node);
     }
   }
 
+  protected abstract T getSelectedFromTreeUserObject(DefaultMutableTreeNode node);
+
 
   public void dispose() {
     if (myBuilder != null) {
@@ -362,25 +370,65 @@ public class TreeClassChooserDialog extends DialogWrapper implements TreeClassCh
     return myGotoByNamePanel.getPreferredFocusedComponent();
   }
 
-  private class MyGotoClassModel extends GotoClassModel2 {
-    public MyGotoClassModel(Project project) {
+  protected Project getProject() {
+    return myProject;
+  }
+
+  GlobalSearchScope getScope() {
+    return myScope;
+  }
+
+  @NotNull
+  protected Filter<T> getFilter() {
+    return myClassFilter;
+  }
+
+  T getBaseClass() {
+    return myBaseClass;
+  }
+
+  T getInitialClass() {
+    return myInitialClass;
+  }
+
+  protected TabbedPaneWrapper getTabbedPane() {
+    return myTabbedPane;
+  }
+
+  protected Tree getTree() {
+    return myTree;
+  }
+
+  protected ChooseByNamePanel getGotoByNamePanel() {
+    return myGotoByNamePanel;
+  }
+
+  protected static class MyGotoClassModel<T extends PsiNamedElement> extends GotoClassModel2 {
+    private final AbstractTreeClassChooserDialog<T> myTreeClassChooserDialog;
+
+    AbstractTreeClassChooserDialog<T> getTreeClassChooserDialog() {
+      return myTreeClassChooserDialog;
+    }
+
+    public MyGotoClassModel(Project project,
+                            AbstractTreeClassChooserDialog<T> treeClassChooserDialog) {
       super(project);
+      myTreeClassChooserDialog = treeClassChooserDialog;
     }
 
     public Object[] getElementsByName(final String name, final boolean checkBoxState, final String pattern) {
-      final PsiShortNamesCache cache = JavaPsiFacade.getInstance(myProject).getShortNamesCache();
-      PsiClass[] classes = cache.getClassesByName(name, checkBoxState ? myScope : GlobalSearchScope.projectScope(myProject).intersectWith(myScope));
-      if (classes.length == 0) return ArrayUtil.EMPTY_OBJECT_ARRAY;
-      if (classes.length == 1) {
-        return isAccepted(classes[0]) ? classes : ArrayUtil.EMPTY_OBJECT_ARRAY;
+      List<T> classes = myTreeClassChooserDialog.getClassesByName(name, checkBoxState, pattern, myTreeClassChooserDialog.getScope());
+      if (classes.size() == 0) return ArrayUtil.EMPTY_OBJECT_ARRAY;
+      if (classes.size() == 1) {
+        return isAccepted(classes.get(0)) ? classes.toArray(new Object[classes.size()]) : ArrayUtil.EMPTY_OBJECT_ARRAY;
       }
-      List<PsiClass> list = new ArrayList<PsiClass>(classes.length);
-      for (PsiClass aClass : classes) {
+      List<T> list = new ArrayList<T>(classes.size());
+      for (T aClass : classes) {
         if (isAccepted(aClass)) {
           list.add(aClass);
         }
       }
-      return list.toArray(new PsiClass[list.size()]);
+      return list.toArray(new Object[list.size()]);
     }
 
     @Nullable
@@ -388,33 +436,79 @@ public class TreeClassChooserDialog extends DialogWrapper implements TreeClassCh
       return null;
     }
 
-    protected boolean isAccepted(PsiClass aClass) {
-      return myClassFilter.isAccepted(aClass);
+    protected boolean isAccepted(T aClass) {
+      return myTreeClassChooserDialog.getFilter().isAccepted(aClass);
+    }
+  }
+
+
+  @NotNull
+  abstract protected List<T> getClassesByName(final String name,
+                                              final boolean checkBoxState,
+                                              final String pattern,
+                                              final GlobalSearchScope searchScope);
+
+  public static abstract class BaseClassInheritorsProvider<T> {
+    private final T myBaseClass;
+    private final GlobalSearchScope myScope;
+
+    public T getBaseClass() {
+      return myBaseClass;
+    }
+
+    public GlobalSearchScope getScope() {
+      return myScope;
+    }
+
+    public BaseClassInheritorsProvider(T baseClass, GlobalSearchScope scope) {
+      myBaseClass = baseClass;
+      myScope = scope;
+    }
+
+    @NotNull
+    abstract protected Query<T> searchForInheritors(T baseClass, GlobalSearchScope searchScope, boolean checkDeep);
+
+    abstract protected boolean isInheritor(T clazz, T baseClass, boolean checkDeep);
+
+    abstract protected String[] getNames();
+
+    protected Query<T> searchForInheritorsOfBaseClass() {
+      return searchForInheritors(myBaseClass, myScope, true);
+    }
+
+    protected boolean isInheritorOfBaseClass(T aClass) {
+      return isInheritor(aClass, myBaseClass, true);
     }
   }
 
-  private class SubclassGotoClassModel extends MyGotoClassModel {
+  private static class SubclassGotoClassModel<T extends PsiNamedElement> extends MyGotoClassModel<T> {
+    private final BaseClassInheritorsProvider<T> myInheritorsProvider;
 
     private boolean myFastMode = true;
 
-    public SubclassGotoClassModel(final Project project) {
-      super(project);
-      assert myBaseClass != null;
+    public SubclassGotoClassModel(@NotNull final Project project,
+                                  @NotNull final AbstractTreeClassChooserDialog<T> treeClassChooserDialog,
+                                  @NotNull BaseClassInheritorsProvider<T> inheritorsProvider) {
+      super(project, treeClassChooserDialog);
+      myInheritorsProvider = inheritorsProvider;
+      assert myInheritorsProvider.getBaseClass() != null;
     }
 
     public String[] getNames(boolean checkBoxState) {
       if (!myFastMode) {
-        return JavaPsiFacade.getInstance(myProject).getShortNamesCache().getAllClassNames();
+        return myInheritorsProvider.getNames();
       }
       final List<String> names = new ArrayList<String>();
-      myFastMode = ClassInheritorsSearch.search(myBaseClass, myScope, true).forEach(new Processor<PsiClass>() {
+
+      myFastMode = myInheritorsProvider.searchForInheritorsOfBaseClass().forEach(new Processor<T>() {
         private int count;
+
         @Override
-        public boolean process(PsiClass aClass) {
+        public boolean process(T aClass) {
           if (count++ > 1000) {
             return false;
           }
-          if ((myClassFilter.isAccepted(aClass)) && aClass.getName() != null) {
+          if ((getTreeClassChooserDialog().getFilter().isAccepted(aClass)) && aClass.getName() != null) {
             names.add(aClass.getName());
           }
           return true;
@@ -423,52 +517,31 @@ public class TreeClassChooserDialog extends DialogWrapper implements TreeClassCh
       if (!myFastMode) {
         return getNames(checkBoxState);
       }
-      if ((myClassFilter.isAccepted(myBaseClass)) && myBaseClass.getName() != null) {
-        names.add(myBaseClass.getName());
+      if ((getTreeClassChooserDialog().getFilter().isAccepted(myInheritorsProvider.getBaseClass())) &&
+          myInheritorsProvider.getBaseClass().getName() != null) {
+        names.add(myInheritorsProvider.getBaseClass().getName());
       }
       return names.toArray(new String[names.size()]);
     }
 
-    protected boolean isAccepted(PsiClass aClass) {
+
+    protected boolean isAccepted(T aClass) {
       if (myFastMode) {
-        return myClassFilter.isAccepted(aClass);
+        return getTreeClassChooserDialog().getFilter().isAccepted(aClass);
       }
       else {
-        return (aClass == myBaseClass || aClass.isInheritor(myBaseClass, true)) && myClassFilter.isAccepted(aClass);
+        return (aClass == getTreeClassChooserDialog().getBaseClass() ||
+                myInheritorsProvider.isInheritorOfBaseClass(aClass)) &&
+               getTreeClassChooserDialog().getFilter().isAccepted(
+                 aClass);
       }
     }
   }
+
   private class MyCallback extends ChooseByNamePopupComponent.Callback {
     public void elementChosen(Object element) {
-      mySelectedClass = (PsiClass)element;
+      mySelectedClass = (T)element;
       close(OK_EXIT_CODE);
     }
   }
-
-  public static class InheritanceClassFilterImpl implements InheritanceClassFilter{
-    private final PsiClass myBase;
-    private final boolean myAcceptsSelf;
-    private final boolean myAcceptsInner;
-    private final Condition<? super PsiClass> myAdditionalCondition;
-
-    public InheritanceClassFilterImpl(PsiClass base,
-                                      boolean acceptsSelf,
-                                      boolean acceptInner,
-                                      Condition<? super PsiClass> additionalCondition) {
-      myAcceptsSelf = acceptsSelf;
-      myAcceptsInner = acceptInner;
-      if (additionalCondition == null) {
-        additionalCondition = Conditions.alwaysTrue();
-      }
-      myAdditionalCondition = additionalCondition;
-      myBase = base;
-    }
-
-    public boolean isAccepted(PsiClass aClass) {
-      if (!myAcceptsInner && !(aClass.getParent() instanceof PsiJavaFile)) return false;
-      if (!myAdditionalCondition.value(aClass)) return false;
-      // we've already checked for inheritance
-      return myAcceptsSelf || !aClass.getManager().areElementsEquivalent(aClass, myBase);
-    }
-  }
 }
index 83567e55db032a168734d5b98d6dd66408d64a53..11a5f9aa547cac558c650f0bfaaeac3f851cba47 100644 (file)
@@ -523,7 +523,7 @@ public abstract class ChooseByNameBase {
   protected void doClose(final boolean ok) {
     if (myDisposedFlag) return;
 
-    if (posponeCloseWhenListReady(ok)) return;
+    if (postponeCloseWhenListReady(ok)) return;
 
     cancelListUpdater();
     close(ok);
@@ -535,7 +535,7 @@ public abstract class ChooseByNameBase {
     myListUpdater.cancelAll();
   }
 
-  private boolean posponeCloseWhenListReady(boolean ok) {
+  private boolean postponeCloseWhenListReady(boolean ok) {
     if (!isToFixLostTyping()) return false;
 
     final String text = myTextField.getText();
index 1ce9ea5865cb4910a8dab1289eecb24c5a6c76ea..8eba77a1d3a9407aec5118c55c197882e2528f67 100644 (file)
@@ -295,8 +295,12 @@ public class DirectoryIndexImpl extends DirectoryIndex implements ProjectCompone
       VirtualFile parent = file.getParent();
       if (parent == null) return;
 
-      IndexState state = myState.copy();
+      IndexState newState = myState.copy();
+      updateStateWithNewFile(file, parent, newState);
+      myState = newState;
+    }
 
+    private void updateStateWithNewFile(VirtualFile file, VirtualFile parent, IndexState state) {
       DirectoryInfo parentInfo = state.myDirToInfoMap.get(parent);
 
       // fill info for all nested roots
@@ -348,7 +352,6 @@ public class DirectoryIndexImpl extends DirectoryIndex implements ProjectCompone
       if (!parentInfo.getOrderEntries().isEmpty()) {
         state.fillMapWithOrderEntries(file, parentInfo.getOrderEntries(), null, null, null, parentInfo, null);
       }
-      myState = state;
     }
 
     public void beforeFileDeletion(VirtualFileEvent event) {
index 5273de0e288ef7e4a13458e24516c99668174b59..b381d41b5dae745e46a9cb57b36b56202e0a4277 100644 (file)
@@ -21,7 +21,9 @@ import com.intellij.injected.editor.VirtualFileWindow;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.ReadActionProcessor;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.IndexNotReadyException;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.ProjectFileIndex;
 import com.intellij.openapi.roots.ProjectRootManager;
@@ -85,20 +87,25 @@ public class IndexCacheManagerImpl implements CacheManager{
   public boolean processFilesWithWord(@NotNull final Processor<PsiFile> psiFileProcessor, @NotNull final String word, final short occurrenceMask, @NotNull final GlobalSearchScope scope, final boolean caseSensitively) {
     final Set<VirtualFile> vFiles = new THashSet<VirtualFile>();
     final GlobalSearchScope projectScope = GlobalSearchScope.allScope(myProject);
-    ApplicationManager.getApplication().runReadAction(new Runnable() {
-      public void run() {
-        FileBasedIndex.getInstance().processValues(IdIndex.NAME, new IdIndexEntry(word, caseSensitively), null, new FileBasedIndex.ValueProcessor<Integer>() {
-          public boolean process(final VirtualFile file, final Integer value) {
-            ProgressManager.checkCanceled();
-            final int mask = value.intValue();
-            if ((mask & occurrenceMask) != 0) {
-              vFiles.add(file);
+    try {
+      ApplicationManager.getApplication().runReadAction(new Runnable() {
+        public void run() {
+          FileBasedIndex.getInstance().processValues(IdIndex.NAME, new IdIndexEntry(word, caseSensitively), null, new FileBasedIndex.ValueProcessor<Integer>() {
+            public boolean process(final VirtualFile file, final Integer value) {
+              ProgressManager.checkCanceled();
+              final int mask = value.intValue();
+              if ((mask & occurrenceMask) != 0) {
+                vFiles.add(file);
+              }
+              return true;
             }
-            return true;
-          }
-        }, projectScope);
-      }
-    });
+          }, projectScope);
+        }
+      });
+    }
+    catch (IndexNotReadyException e) {
+      throw new ProcessCanceledException();
+    }
 
     if (vFiles.isEmpty()) return true;
 
index ba02345507a20123ddf6d62925572a5a15303381..24c63ca26335f23f49a5e2001b5859ac748ab946 100644 (file)
@@ -59,6 +59,7 @@ public class ASTDiffBuilder implements DiffTreeChangeBuilder<ASTNode, ASTNode> {
     }
     else {
       final ASTNode parent = oldNode.getTreeParent();
+      assert parent != null : "old:" + oldNode + " new:" + newNode;
 
       TreeUtil.ensureParsed(oldNode);
 
index 9f642f8b7d80f7ee3ac2b4ac3347d862e463a60e..56cf4eb7db70b700f0d8e4f855e4efb97e849ee5 100644 (file)
@@ -24,6 +24,7 @@ import com.intellij.openapi.help.HelpManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.impl.DialogWrapperPeerImpl;
 import com.intellij.psi.PsiDirectory;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
@@ -72,7 +73,13 @@ class CopyFilesOrDirectoriesDialog extends DialogWrapper{
         text = doClone ?
                RefactoringBundle.message("copy.files.clone.file.0", file.getVirtualFile().getPresentableUrl()) :
                RefactoringBundle.message("copy.files.copy.file.0", file.getVirtualFile().getPresentableUrl());
-        myNewNameField.setText(file.getName());
+        final String fileName = file.getName();
+        myNewNameField.setText(fileName);
+        final int dotIdx = fileName.lastIndexOf(".");
+        if (dotIdx > -1) {
+          myNewNameField.select(0, dotIdx);
+          myNewNameField.putClientProperty(DialogWrapperPeerImpl.HAVE_INITIAL_SELECTION, true);
+        }
       }
       else {
         PsiDirectory directory = (PsiDirectory)elements[0];
index a1b9e3889b4b32a78173d676d09dc247b5914753..117b2fc2ec3d4285894e7a59977465144a5e7942 100644 (file)
@@ -100,17 +100,31 @@ public class PluginManager {
   public static synchronized IdeaPluginDescriptor[] getPlugins() {
     if (ourPlugins == null) {
       initializePlugins();
-      getLogger().info("Loaded plugins:" + StringUtil.join(ourPlugins, new Function<IdeaPluginDescriptorImpl, String>() {
-        public String fun(IdeaPluginDescriptorImpl descriptor) {
-          final String version = descriptor.getVersion();
-          return descriptor.getName() + (version != null ? " (" + version + ")" : "");
-        }
-      }, ", "));
+      logPlugins();
       ClassloaderUtil.clearJarURLCache();
     }
     return ourPlugins;
   }
 
+  private static void logPlugins() {
+    List<String> loaded = new ArrayList<String>();
+    List<String> disabled = new ArrayList<String>();
+    for (IdeaPluginDescriptorImpl descriptor : ourPlugins) {
+      final String version = descriptor.getVersion();
+      String s = descriptor.getName() + (version != null ? " (" + version + ")" : "");
+      if (descriptor.isEnabled()) {
+        loaded.add(s);
+      }
+      else {
+        disabled.add(s);
+      }
+    }
+    getLogger().info("Loaded plugins:" + StringUtil.join(loaded, ", "));
+    if (!disabled.isEmpty()) {
+      getLogger().info("Disabled plugins: " + StringUtil.join(disabled, ", "));
+    }
+  }
+
   public static void invalidatePlugins() {
     ourPlugins = null;
     ourDisabledPlugins = null;
diff --git a/platform/platform-impl/src/com/intellij/ide/util/TreeChooser.java b/platform/platform-impl/src/com/intellij/ide/util/TreeChooser.java
new file mode 100644 (file)
index 0000000..004247b
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2010 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.util;
+
+import com.intellij.psi.PsiDirectory;
+
+public interface TreeChooser<T> {
+  T getSelected();
+
+  void select(final T aClass);
+
+  void selectDirectory(final PsiDirectory directory);
+
+  void showDialog();
+
+  void showPopup();
+
+  interface Filter<T> {
+    boolean isAccepted(T element);
+  }
+}
index 372c3f13a8c96d488b19514e14958f0b3a472668..ee083e9f7fde84eac4d1658a9d583dece8f2b728 100644 (file)
@@ -683,6 +683,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
         if (!force) {
           if (!showConfirmation()) {
             saveAll();
+            myExitCode = 0;
             return;
           }
         }
@@ -691,15 +692,21 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
 
         saveSettings();
 
-        if (!canExit()) return;
+        if (!canExit()) {
+          myExitCode = 0;
+          return;
+        }
 
-        boolean success = disposeSelf();
-        if (success && !isUnitTestMode()) {
-          System.exit(myExitCode);
+        final boolean success = disposeSelf();
+        if (!success || isUnitTestMode()) {
+          myExitCode = 0;
+          return;
         }
+
+        System.exit(myExitCode);
       }
     };
-    
+
     if (!isDispatchThread()) {
       invokeLater(runnable, ModalityState.NON_MODAL);
     }
index 86cde1b81c7a885919f5b345d2f7d4b596711b2a..bdc2a7644f146a7de84d94586a1aec9df50d64d3 100644 (file)
@@ -37,7 +37,7 @@ import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 
-@SuppressWarnings({"ForLoopReplaceableByForEach"}) // Way too many garbage in AbrstractList.iterator() produced otherwise.
+@SuppressWarnings({"ForLoopReplaceableByForEach"}) // Way too many garbage in AbstractList.iterator() produced otherwise.
 public final class IterationState {
   private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.IterationState");
   private final TextAttributes myMergedAttributes = new TextAttributes();
index 0bad426867c80ddaf7442acecc801cca488f660e..a817cec7f3085dd5454a7e46569fe42a327f611b 100644 (file)
@@ -272,6 +272,7 @@ message.upgrade.from.previous.required=Your license is not valid for use with th
 title.upgrade.needed=Upgrade Needed
 message.evaluation.has.expired=Your {0} evaluation has expired. Your session will be limited to 30 minutes.<br>{1}
 title.evaluation.license.expired=Evaluation License Expired
+message.evaluation.license.expired=Your evaluation license has expired. {0} will now exit.
 message.license.expired=Your license has expired
 title.license.expired=License Expired
 message.license.is.corrupt=License is corrupt
@@ -282,7 +283,7 @@ title.product.evaluation={0} Evaluation
 message.evaluation.N.days={0} days
 message.evaluation.one.day=1 day
 message.evaluation.less.than.one.day=less than 1 day
-message.evaluation.will.expire=Thank you for evaluating {0}.<br>Your evaluation license expires in {1}<br><br>{2}<br>You can then register the commercial license using the Help menu.
+message.evaluation.will.expire=Thank you for evaluating {0}.<br>Your evaluation license expires in {1}<br><br>{2}
 title.license.will.expire={0} License Expires Soon
 message.license.will.expire=Your {0} license expires in {1}.
 error.saving.license.data=Error saving license data.\n{0}
@@ -291,6 +292,7 @@ link.click.here.to.license.server.info=More info
 link.purchase.commercial.license=To purchase a commercial license, please visit
 license.panel.expirable.license.description=The license will expire on {0,date,MMMM dd, yyyy}
 license.panel.maintenance.aware.license.description=Entitled for free updates and upgrades until {0,date,MMMM dd, yyyy}
+license.panel.perpetual.license.description=Perpetual license
 license.panel.current.permanent.ticket.description=Permanent ticket obtained
 license.panel.current.floating.ticket.description=Floating ticket obtained
 license.panel.buildit.evaluation.expires.in.one=1 day left
index f71c8bb6f10e231d9da31583d81e58338c3d1737..9abb7c0f743ffe8bfc1f07d04a8aab8fd156c07a 100644 (file)
@@ -482,11 +482,12 @@ public class JDOMUtil {
    * Returns null if no escapement necessary.
    */
   @Nullable
-  private static String escapeChar(char c, boolean escapeLineEnds) {
+  private static String escapeChar(char c, boolean escapeSpaces, boolean escapeLineEnds) {
     switch (c) {
       case '\n': return escapeLineEnds ? "&#10;" : null;
       case '\r': return escapeLineEnds ? "&#13;" : null;
       case '\t': return escapeLineEnds ? "&#9;" : null;
+      case ' ' : return escapeSpaces  ? "&#20" : null;
       case '<':  return "&lt;";
       case '>':  return "&gt;";
       case '\"': return "&quot;";
@@ -497,15 +498,15 @@ public class JDOMUtil {
 
   @NotNull
   public static String escapeText(String text) {
-    return escapeText(text, false);
+    return escapeText(text, false, false);
   }
 
   @NotNull
-  private static String escapeText(String text, boolean escapeLineEnds) {
+  public static String escapeText(String text, boolean escapeSpaces, boolean escapeLineEnds) {
     StringBuffer buffer = null;
     for (int i = 0; i < text.length(); i++) {
       final char ch = text.charAt(i);
-      final String quotation = escapeChar(ch, escapeLineEnds);
+      final String quotation = escapeChar(ch, escapeSpaces, escapeLineEnds);
 
       if (buffer == null) {
         if (quotation != null) {
@@ -548,11 +549,11 @@ public class JDOMUtil {
 
   public static class MyXMLOutputter extends XMLOutputter {
     public String escapeAttributeEntities(String str) {
-      return escapeText(str, true);
+      return escapeText(str, false, true);
     }
 
     public String escapeElementEntities(String str) {
-      return escapeText(str, false);
+      return escapeText(str, false, false);
     }
   }
 
index b08884e801cd234132ccc2589baf0f6f7e436505..b58fed44fff808a2c396d9dbc06606d884d3a8a7 100644 (file)
@@ -393,13 +393,16 @@ public class FileUtil {
   }
 
   private static String calcCanonicalTempPath() {
-    final String prop = System.getProperty("java.io.tmpdir");
+    final File file = new File(System.getProperty("java.io.tmpdir"));
     try {
-      return new File(prop).getCanonicalPath();
+      final String canonical = file.getCanonicalPath();
+      if (!SystemInfo.isWindows || !canonical.contains(" ")) {
+        return canonical;
+      }
     }
-    catch (IOException e) {
-      return prop;
+    catch (IOException ignore) {
     }
+    return file.getAbsolutePath();
   }
 
   public static void asyncDelete(@NotNull File file) {
index e2c4033377fd0af2653e68a2d9ae27599be82b7a..859e402e3b82975c5eadb06bb34be155a36f0f73 100644 (file)
@@ -816,7 +816,7 @@ set.replaceable.by.enum.set.display.name=Set replaceable with EnumSet
 non.static.inner.class.in.secure.context.display.name=Non-static inner class in secure context
 tail.recursion.display.name=Tail recursion
 finally.block.cannot.complete.normally.display.name='finally' block which can not complete normally
-arithmetic.on.volatile.field.display.name=Arithmetic operation on volatile field
+non.atomic.operation.on.volatile.field.display.name=Non-atomic operation on volatile field
 public.static.collection.field.display.name='public static' collection field
 non.exception.name.ends.with.exception.display.name=Non-exception class name ends with 'Exception'
 synchronized.method.display.name='synchronized' method
@@ -993,7 +993,7 @@ serializable.inner.class.has.serial.version.uid.field.problem.descriptor=Inner c
 serializable.inner.class.with.non.serializable.outer.class.problem.descriptor=Inner class <code>#ref</code> is serializable while its outer class is not #loc
 busy.wait.problem.descriptor=Call to <code>Thread.#ref()</code> in a loop, probably busy-waiting #loc
 sleep.while.holding.lock.problem.descriptor=Call to <code>Thread.#ref()</code> while synchronized #loc
-arithmetic.on.volatile.field.problem.descriptor=Arithmetic operation on volatile field <code>#ref</code> #loc
+non.atomic.operation.on.volatile.field.problem.descriptor=Non-atomic operation on volatile field <code>#ref</code> #loc
 call.to.native.method.while.locked.problem.descriptor=Call to native method <code>#ref()</code> in a synchronized context #loc
 object.notify.problem.descriptor=<code>#ref</code> should probably be replaced with 'notifyAll()' #loc
 condition.signal.problem.descriptor=<code>#ref</code> should probably be replaced with 'signalAll()' #loc
index c3ee767d914f9f927dc09fd5ec6454455c5a091e..466d5a5c6c98b9592a9174a87bd1807c58fb9895 100644 (file)
@@ -821,7 +821,6 @@ public class InspectionGadgetsPlugin implements ApplicationComponent,
     private void registerThreadingInspections() {
         m_inspectionClasses.add(AccessToNonThreadSafeStaticFieldFromInstanceInspection.class);
         m_inspectionClasses.add(AccessToStaticFieldLockedOnInstanceInspection.class);
-        m_inspectionClasses.add(ArithmeticOnVolatileFieldInspection.class);
         m_inspectionClasses.add(AwaitNotInLoopInspection.class);
         m_inspectionClasses.add(AwaitWithoutCorrespondingSignalInspection.class);
         m_inspectionClasses.add(BusyWaitInspection.class);
@@ -834,6 +833,7 @@ public class InspectionGadgetsPlugin implements ApplicationComponent,
         m_inspectionClasses.add(MethodMayBeSynchronizedInspection.class);
         m_inspectionClasses.add(NakedNotifyInspection.class);
         m_inspectionClasses.add(NestedSynchronizedStatementInspection.class);
+        m_inspectionClasses.add(NonAtomicOperationOnVolatileFieldInspection.class);
         m_inspectionClasses.add(NonSynchronizedMethodOverridesSynchronizedMethodInspection.class);
         m_inspectionClasses.add(NotifyCalledOnConditionInspection.class);
         m_inspectionClasses.add(NotifyNotInSynchronizedContextInspection.class);
index fe56825018edf70b890dca79d54953ef37d182c9..9b4f598ac4d5392718cbfd67414ddf18e5327750 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2008 Bas Leijdekkers
+ * Copyright 2006-2010 Bas Leijdekkers
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -30,14 +30,11 @@ public class SynchronizationUtil {
         if (context instanceof PsiSynchronizedStatement) {
             return true;
         }
-        if (context != null) {
-            final PsiModifierListOwner modifierListOwner =
-                    (PsiModifierListOwner)context;
-            if (modifierListOwner.hasModifierProperty(
-                    PsiModifier.SYNCHRONIZED)) {
-                return true;
-            }
+        if (context == null) {
+            return false;
         }
-        return false;
+        final PsiModifierListOwner modifierListOwner =
+                (PsiModifierListOwner)context;
+        return modifierListOwner.hasModifierProperty(PsiModifier.SYNCHRONIZED);
     }
 }
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ArithmeticOnVolatileFieldInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ArithmeticOnVolatileFieldInspection.java
deleted file mode 100644 (file)
index 212a98d..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers
- *
- * 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.siyeh.ig.threading;
-
-import com.intellij.psi.*;
-import com.intellij.psi.tree.IElementType;
-import com.siyeh.InspectionGadgetsBundle;
-import com.siyeh.ig.BaseInspection;
-import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.psiutils.WellFormednessUtils;
-import org.jetbrains.annotations.NotNull;
-
-public class ArithmeticOnVolatileFieldInspection extends BaseInspection {
-
-    @NotNull
-    public String getDisplayName() {
-        return InspectionGadgetsBundle.message(
-                "arithmetic.on.volatile.field.display.name");
-    }
-
-    @NotNull
-    protected String buildErrorString(Object... infos) {
-        return InspectionGadgetsBundle.message(
-                "arithmetic.on.volatile.field.problem.descriptor");
-    }
-
-    public BaseInspectionVisitor buildVisitor() {
-        return new AritmeticOnVolatileFieldInspection();
-    }
-
-    private static class AritmeticOnVolatileFieldInspection
-            extends BaseInspectionVisitor {
-
-        @Override public void visitBinaryExpression(
-                @NotNull PsiBinaryExpression expression) {
-            super.visitBinaryExpression(expression);
-            if (expression.getROperand() == null) {
-                return;
-            }
-            final PsiJavaToken sign = expression.getOperationSign();
-            final IElementType tokenType = sign.getTokenType();
-            if (!JavaTokenType.ASTERISK.equals(tokenType) &&
-                    !JavaTokenType.DIV.equals(tokenType) &&
-                    !JavaTokenType.PLUS.equals(tokenType) &&
-                    !JavaTokenType.MINUS.equals(tokenType) &&
-                    !JavaTokenType.PERC.equals(tokenType)) {
-                return;
-            }
-            final PsiExpression lhs = expression.getLOperand();
-            checkForVolatile(lhs);
-            final PsiExpression rhs = expression.getROperand();
-            checkForVolatile(rhs);
-        }
-
-        @Override public void visitAssignmentExpression(
-                @NotNull PsiAssignmentExpression expression) {
-            super.visitAssignmentExpression(expression);
-            if (!WellFormednessUtils.isWellFormed(expression)) {
-                return;
-            }
-            final PsiJavaToken sign = expression.getOperationSign();
-            final IElementType tokenType = sign.getTokenType();
-            if (!JavaTokenType.ASTERISKEQ.equals(tokenType) &&
-                    !JavaTokenType.DIVEQ.equals(tokenType) &&
-                    !JavaTokenType.PLUSEQ.equals(tokenType) &&
-                    !JavaTokenType.MINUSEQ.equals(tokenType) &&
-                    !JavaTokenType.PERCEQ.equals(tokenType)) {
-                return;
-            }
-            final PsiExpression lhs = expression.getLExpression();
-            checkForVolatile(lhs);
-            final PsiExpression rhs = expression.getRExpression();
-            checkForVolatile(rhs);
-        }
-
-        private void checkForVolatile(PsiExpression expression) {
-            if (!(expression instanceof PsiReferenceExpression)) {
-                return;
-            }
-            final PsiReferenceExpression reference =
-                    (PsiReferenceExpression)expression;
-            final PsiElement referent = reference.resolve();
-            if (!(referent instanceof PsiField)) {
-                return;
-            }
-            final PsiField field = (PsiField)referent;
-            if (field.hasModifierProperty(PsiModifier.VOLATILE)) {
-                registerError(expression);
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/NonAtomicOperationOnVolatileFieldInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/NonAtomicOperationOnVolatileFieldInspection.java
new file mode 100644 (file)
index 0000000..e774adf
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
+ *
+ * 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.siyeh.ig.threading;
+
+import com.intellij.psi.*;
+import com.intellij.psi.tree.IElementType;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.psiutils.SynchronizationUtil;
+import com.siyeh.ig.psiutils.VariableAccessUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class NonAtomicOperationOnVolatileFieldInspection
+        extends BaseInspection {
+
+    @Override
+    @NotNull
+    public String getDisplayName() {
+        return InspectionGadgetsBundle.message(
+                "non.atomic.operation.on.volatile.field.display.name");
+    }
+
+    @Override
+    @NotNull
+    protected String buildErrorString(Object... infos) {
+        return InspectionGadgetsBundle.message(
+                "non.atomic.operation.on.volatile.field.problem.descriptor");
+    }
+
+    @Override
+    public BaseInspectionVisitor buildVisitor() {
+        return new NonAtomicOperationOnVolatileFieldVisitor();
+    }
+
+    private static class NonAtomicOperationOnVolatileFieldVisitor
+            extends BaseInspectionVisitor {
+
+        @Override public void visitAssignmentExpression(
+                @NotNull PsiAssignmentExpression expression) {
+            super.visitAssignmentExpression(expression);
+            final PsiExpression rhs = expression.getRExpression();
+            if (rhs == null) {
+                return;
+            }
+            final PsiExpression lhs = expression.getLExpression();
+            final PsiField volatileField = findNonSynchronizedVolatileField(lhs);
+            if (volatileField ==  null) {
+                return;
+            }
+            final IElementType tokenType = expression.getOperationTokenType();
+            if (tokenType.equals(JavaTokenType.PLUSEQ) ||
+                    tokenType.equals(JavaTokenType.MINUSEQ) ||
+                    tokenType.equals(JavaTokenType.ASTERISKEQ) ||
+                    tokenType.equals(JavaTokenType.DIVEQ) ||
+                    tokenType.equals(JavaTokenType.ANDEQ) ||
+                    tokenType.equals(JavaTokenType.OREQ)||
+                    tokenType.equals(JavaTokenType.XOREQ)||
+                    tokenType.equals(JavaTokenType.PERCEQ)||
+                    tokenType.equals(JavaTokenType.LTLTEQ)||
+                    tokenType.equals(JavaTokenType.GTGTEQ)||
+                    tokenType.equals(JavaTokenType.GTGTGTEQ)) {
+                registerError(lhs);
+                return;
+            }
+            if (VariableAccessUtils.variableIsUsed(volatileField, rhs)) {
+                registerError(lhs);
+            }
+        }
+
+        @Override
+        public void visitPrefixExpression(PsiPrefixExpression expression) {
+            super.visitPrefixExpression(expression);
+            final PsiExpression operand = expression.getOperand();
+            if (operand == null) {
+                return;
+            }
+            final PsiField volatileField =
+                    findNonSynchronizedVolatileField(operand);
+            if (volatileField == null) {
+                return;
+            }
+            registerError(operand);
+        }
+
+        @Override
+        public void visitPostfixExpression(PsiPostfixExpression expression) {
+            super.visitPostfixExpression(expression);
+            final PsiExpression operand = expression.getOperand();
+            final PsiField volatileField =
+                    findNonSynchronizedVolatileField(operand);
+            if (volatileField == null) {
+                return;
+            }
+            registerError(operand);
+        }
+
+        @Nullable
+        private static PsiField findNonSynchronizedVolatileField(
+                PsiExpression expression) {
+            if (!(expression instanceof PsiReferenceExpression)) {
+                return null;
+            }
+            final PsiReferenceExpression reference =
+                    (PsiReferenceExpression)expression;
+            if (SynchronizationUtil.isInSynchronizedContext(reference)) {
+                return null;
+            }
+            final PsiElement referent = reference.resolve();
+            if (!(referent instanceof PsiField)) {
+                return null;
+            }
+            final PsiField field = (PsiField)referent;
+            if (!field.hasModifierProperty(PsiModifier.VOLATILE)) {
+                return null;
+            }
+            return field;
+        }
+    }
+}
\ No newline at end of file
index 52e0dd34efc8b79bf7c6fa47533314686eafddb5..7aeb1b7e87641f05d773514f36883ff15db19a37 100644 (file)
@@ -18,6 +18,7 @@ package com.siyeh.ig.ui;
 import com.intellij.codeInspection.ui.ListTable;
 import com.intellij.codeInspection.ui.ListWrappingTableModel;
 import com.intellij.ide.DataManager;
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
 import com.intellij.openapi.actionSystem.DataContext;
@@ -61,11 +62,11 @@ public class TreeClassChooserAction extends AbstractAction {
         }
         final TreeClassChooserFactory chooserFactory =
                 TreeClassChooserFactory.getInstance(project);
-        final TreeClassChooser.ClassFilter filter;
+        final ClassFilter filter;
         if (ancestorClasses.length == 0) {
-            filter = TreeClassChooser.ClassFilter.ALL;
+            filter = ClassFilter.ALL;
         } else {
-            filter = new TreeClassChooser.ClassFilter() {
+            filter = new ClassFilter() {
                 public boolean isAccepted(PsiClass aClass) {
                     for (String ancestorClass : ancestorClasses) {
                         if (ClassUtils.isSubclass(aClass, ancestorClass)) {
@@ -80,7 +81,7 @@ public class TreeClassChooserAction extends AbstractAction {
                 chooserFactory.createWithInnerClassesScopeChooser(chooserTitle,
                         GlobalSearchScope.allScope(project), filter, null);
         classChooser.showDialog();
-        final PsiClass selectedClass = classChooser.getSelectedClass();
+        final PsiClass selectedClass = classChooser.getSelected();
         if (selectedClass == null) {
             return;
         }
index 9878b9e34d4e5ea312e8cad1dab4aeedac960d9b..a5fe7c1521d5078002cb13916509ee4c7ebfabd0 100644 (file)
@@ -17,6 +17,7 @@ package com.siyeh.ig.ui;
 
 import com.intellij.codeInspection.ui.ListTable;
 import com.intellij.codeInspection.ui.ListWrappingTableModel;
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
 import com.intellij.openapi.actionSystem.*;
@@ -50,9 +51,9 @@ public class UiUtils {
     public static ActionToolbar createAddRemoveTreeClassChooserToolbar(
             ListTable table, String chooserTitle,
             @NonNls String... ancestorClasses) {
-        final TreeClassChooser.ClassFilter filter;
+        final ClassFilter filter;
         if (ancestorClasses.length == 0) {
-            filter = TreeClassChooser.ClassFilter.ALL;
+            filter = ClassFilter.ALL;
         } else {
             filter = new SubclassFilter(ancestorClasses);
         }
@@ -68,8 +69,8 @@ public class UiUtils {
 
     public static ActionToolbar createAddRemoveTreeAnnotationChooserToolbar(
             ListTable table, String chooserTitle) {
-        final TreeClassChooser.ClassFilter filter =
-                new TreeClassChooser.ClassFilter() {
+        final ClassFilter filter =
+                new ClassFilter() {
                     public boolean isAccepted(PsiClass psiClass) {
                         return psiClass.isAnnotationType();
                     }
@@ -88,16 +89,16 @@ public class UiUtils {
 
         private final ListTable table;
         private final String chooserTitle;
-        private final TreeClassChooser.ClassFilter filter;
+        private final ClassFilter myFilter;
 
         public TreeClassChooserAction(
                 @NotNull ListTable table, @NotNull String chooserTitle,
-                @NotNull TreeClassChooser.ClassFilter filter) {
+                @NotNull ClassFilter filter) {
             super(InspectionGadgetsBundle.message("button.add"), "",
                     Icons.ADD_ICON);
             this.table = table;
             this.chooserTitle = chooserTitle;
-            this.filter = filter;
+            this.myFilter = filter;
         }
 
         @Override
@@ -111,9 +112,9 @@ public class UiUtils {
                     TreeClassChooserFactory.getInstance(project);
             final TreeClassChooser classChooser =
                     chooserFactory.createWithInnerClassesScopeChooser(chooserTitle,
-                            GlobalSearchScope.allScope(project), filter, null);
+                            GlobalSearchScope.allScope(project), myFilter, null);
             classChooser.showDialog();
-            final PsiClass selectedClass = classChooser.getSelectedClass();
+            final PsiClass selectedClass = classChooser.getSelected();
             if (selectedClass == null) {
                 return;
             }
@@ -240,7 +241,7 @@ public class UiUtils {
         }
     }
 
-    private static class SubclassFilter implements TreeClassChooser.ClassFilter {
+    private static class SubclassFilter implements ClassFilter {
 
         private final String[] ancestorClasses;
 
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ArithmeticOnVolatileField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ArithmeticOnVolatileField.html
deleted file mode 100644 (file)
index 9fd582c..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<html>
-<body><table> <tr> <td valign="top" height="150">
-<font face="verdana" size="-1">
-This inspection reports any uses of volatile fields in arithmetic operations.
-It's a common misconception that such operations are effectively atomic, but the
-Java Memory Model only specifies that loads and stores on volatile variables are
-atomic. This can lead to unexpected results, including lost updates, when using
-volatile fields in arithmetic operations.
-</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
-</html>
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonAtomicOperationOnVolatileField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonAtomicOperationOnVolatileField.html
new file mode 100644 (file)
index 0000000..7a53e3d
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+<body><table> <tr> <td valign="top" height="150">
+<font face="verdana" size="-1">
+This inspection reports any non-atomic operations on volatile fields. Non-atomic
+operations on volatile fields are operations where the volatile field is read and
+the value is used to update the volatile field. It is possible for the value of the
+field to change between the read and write, making the operation possibly invalid.
+In such cases it is better to surround the operation with a synchronized block or
+make use of one of the  <b><font color="#000080">Atomic*</font></b> or
+    <b><font color="#000080">Atomic*FieldUpdater</font></b> classes
+from the <b><font color="#000080">java.util.concurrent.atomic</font></b> package.
+</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 10, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
+</html>
\ No newline at end of file
index afe0523adc2635d97a0441a02387ed9c5f8eab99..e5f08060b60b1ff19102b7f2fc95c6f4ad941a9a 100644 (file)
@@ -16,6 +16,7 @@
 
 package org.intellij.plugins.intelliLang;
 
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
 import com.intellij.openapi.editor.Document;
@@ -207,14 +208,14 @@ public class AdvancedSettingsUI implements Configurable {
       final GlobalSearchScope scope = GlobalSearchScope.allScope(myProject);
       final PsiClass aClass = JavaPsiFacade.getInstance(myProject).findClass(myField.getText(), scope);
       final TreeClassChooser chooser =
-        factory.createNoInnerClassesScopeChooser("Select Annotation Class", scope, new TreeClassChooser.ClassFilter() {
+        factory.createNoInnerClassesScopeChooser("Select Annotation Class", scope, new ClassFilter() {
           public boolean isAccepted(PsiClass aClass) {
             return aClass.isAnnotationType();
           }
         }, aClass);
 
       chooser.showDialog();
-      final PsiClass psiClass = chooser.getSelectedClass();
+      final PsiClass psiClass = chooser.getSelected();
       if (psiClass != null) {
         myField.setText(psiClass.getQualifiedName());
       }
index 7838e6a13023a13bac55fbecbd2b5716abfbd7ce..d8ba85ac37c244e53c87133ad84e74bcdb664637 100644 (file)
@@ -54,7 +54,6 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
 import java.util.*;
-import java.util.List;
 
 public class MethodParameterPanel extends AbstractInjectionPanel<MethodParameterInjection> {
 
@@ -378,7 +377,7 @@ public class MethodParameterPanel extends AbstractInjectionPanel<MethodParameter
       final TreeClassChooserFactory factory = TreeClassChooserFactory.getInstance(myProject);
       final TreeClassChooser chooser = factory.createAllProjectScopeChooser("Select Class");
       chooser.showDialog();
-      final PsiClass psiClass = chooser.getSelectedClass();
+      final PsiClass psiClass = chooser.getSelected();
       if (psiClass != null) {
         setPsiClass(psiClass.getQualifiedName());
         updateParamTree();
index 23790afe64211418bb8ce0a5255512b35e03a0b0..27392f44db5f7253ab73660e671c84be1c3d3299 100644 (file)
@@ -61,7 +61,7 @@ public final class XmlLanguageInjector implements MultiHostInjector {
 
   public XmlLanguageInjector(Configuration configuration) {
     myConfiguration = configuration;
-    mySupport = InjectorUtils.findInjectionSupport(LanguageInjectionSupport.JAVA_SUPPORT_ID);
+    mySupport = InjectorUtils.findInjectionSupport(LanguageInjectionSupport.XML_SUPPORT_ID);
   }
 
   @NotNull
index 9336260646caf5ebf79a9f4e5755956b868206c2..1ab856936ffaee40171c817eedaa75a65ee518f2 100644 (file)
@@ -214,4 +214,7 @@ android.run.configuration.logcat.tab.title=Logcat
 android.facet.settings.apk.path.label=APK path:
 android.run.confguration.deploy.and.install.check.box=Deplo&y application
 android.manifest.debuggable.attribute.not.true.warning=The manifest 'debuggable' attribute isn't set to 'true'.\nYou have to set it to true in order to debug on a device.\nWould you like to do it?
-android.logcat.no.android.facets.error=There is no Android facets in the project
\ No newline at end of file
+android.logcat.no.android.facets.error=There is no Android facets in the project
+android.facet.compiler.settings.manifest.title=Manifest
+android.facet.settings.compiler.manifest.from.structure=Use AndroidManifest.xml file specified at "Structure" section
+android.facet.settings.compiler.manifest.use.custom=Use custom manifest file:
\ No newline at end of file
index f54ecf4182628cc9d92119f88a2b726b36a5af33..41882f0b06fab990939a42664089f71aee2bab78 100644 (file)
@@ -254,15 +254,16 @@ public class AndroidAptCompiler implements SourceGeneratingCompiler {
                   if (target != null) {
                     AndroidCompileUtil.createSourceRootIfNotExist(sourceRootPath, module);
                     String assetsDirPath = assetsDir != null ? assetsDir.getPath() : null;
-                    VirtualFile manifestFile = AndroidRootUtil.getManifestFile(module);
-                    assert manifestFile != null;
-                    String manifestPath = manifestFile.getPath();
-                    items.add(new AptGenerationItem(module, manifestPath, resPaths, assetsDirPath, sourceRootPath, target,
-                                                    packageName, false));
-
-                    for (String libPackage : AndroidUtils.getDepLibsPackages(module)) {
+                    VirtualFile manifestFile = AndroidRootUtil.getManifestFileForCompiler(facet);
+                    if (manifestFile != null) {
+                      String manifestPath = manifestFile.getPath();
                       items.add(new AptGenerationItem(module, manifestPath, resPaths, assetsDirPath, sourceRootPath, target,
-                                                      libPackage, true));
+                                                      packageName, false));
+
+                      for (String libPackage : AndroidUtils.getDepLibsPackages(module)) {
+                        items.add(new AptGenerationItem(module, manifestPath, resPaths, assetsDirPath, sourceRootPath, target,
+                                                        libPackage, true));
+                      }
                     }
                   }
                 }
index dd54fb1266497c07334e49ff8fede2b2e939e11d..e3d2a779061513bb9f310fa65026c19fe26cb8ed 100644 (file)
@@ -92,7 +92,7 @@ public class AndroidPackagingCompiler implements PackagingCompiler {
     for (Module module : affectedModules) {
       AndroidFacet facet = AndroidFacet.getInstance(module);
       if (facet != null && !facet.getConfiguration().LIBRARY_PROJECT) {
-        VirtualFile manifestFile = AndroidRootUtil.getManifestFile(module);
+        VirtualFile manifestFile = AndroidRootUtil.getManifestFileForCompiler(facet);
         VirtualFile[] sourceRoots = getSourceRootsForModuleAndDependencies(module);
         if (manifestFile != null) {
           AndroidFacetConfiguration configuration = facet.getConfiguration();
index d0a94b84760b8d5fd07b3392136b8ab173914602..699cc023ff2963daac5d08969b0f9b51e438bc15 100644 (file)
@@ -45,7 +45,7 @@ public class AndroidResourcesPackagingCompiler implements ClassPostProcessingCom
     for (Module module : affectedModules) {
       AndroidFacet facet = AndroidFacet.getInstance(module);
       if (facet != null && !facet.getConfiguration().LIBRARY_PROJECT) {
-        VirtualFile manifestFile = AndroidRootUtil.getManifestFile(module);
+        VirtualFile manifestFile = AndroidRootUtil.getManifestFileForCompiler(facet);
         VirtualFile assetsDir = AndroidRootUtil.getAssetsDir(module);
         if (manifestFile != null) {
           AndroidFacetConfiguration configuration = facet.getConfiguration();
index af773936be4c55440d06e507d0599cf47d8fa15e..93a0d69ee056de5a52690488d372f07946e64840 100644 (file)
@@ -49,7 +49,7 @@ public class ResourcesValidityState implements ValidityState {
     IAndroidTarget target = platform != null ? platform.getTarget() : null;
     myAndroidTargetName = target != null ? target.getFullName() : "";
 
-    VirtualFile manifestFile = AndroidRootUtil.getManifestFile(module);
+    VirtualFile manifestFile = AndroidRootUtil.getManifestFileForCompiler(facet);
     if (manifestFile != null) {
       myResourceTimestamps.put(manifestFile.getPath(), manifestFile.getTimeStamp());
     }
@@ -58,7 +58,7 @@ public class ResourcesValidityState implements ValidityState {
       collectFiles(resourcesDir);
     }
     for (AndroidFacet depFacet : AndroidUtils.getAllAndroidDependencies(module, true)) {
-      VirtualFile depManifest = AndroidRootUtil.getManifestFile(depFacet.getModule());
+      VirtualFile depManifest = AndroidRootUtil.getManifestFileForCompiler(depFacet);
       if (depManifest != null) {
         myResourceTimestamps.put(depManifest.getPath(), depManifest.getTimeStamp());
       }
index 2127535251f6021f38361e2d9a7c699b9e845e0b..9cc8d2e7309f57349513fa23d692d1b55f4d660b 100644 (file)
@@ -57,6 +57,9 @@ public class AndroidFacetConfiguration implements FacetConfiguration {
   public boolean USE_CUSTOM_APK_RESOURCE_FOLDER = false;
   public String CUSTOM_APK_RESOURCE_FOLDER = "";
 
+  public boolean USE_CUSTOM_COMPILER_MANIFEST = false;
+  public String CUSTOM_COMPILER_MANIFEST = "";
+
   public String APK_PATH = "";
 
   public boolean ADD_ANDROID_LIBRARY = true;
index 76cbc0dc0bbd6c529152c37c65d5995d60b4cd24..cc727652b4128400e5dc5e36a1fe7c55f5cb7046 100644 (file)
@@ -3,7 +3,7 @@
   <grid id="27dc6" binding="myContentPanel" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
     <margin top="0" left="0" bottom="0" right="0"/>
     <constraints>
-      <xy x="20" y="20" width="460" height="545"/>
+      <xy x="20" y="20" width="512" height="625"/>
     </constraints>
     <properties/>
     <border type="none"/>
               </vspacer>
             </children>
           </grid>
-          <grid id="84519" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+          <grid id="84519" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
             <margin top="4" left="4" bottom="4" right="4"/>
             <constraints>
               <tabbedpane title="Compiler"/>
               <grid id="1f282" binding="myAaptCompilerPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
                 <margin top="0" left="4" bottom="0" right="0"/>
                 <constraints>
-                  <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
                 </constraints>
                 <properties/>
                 <border type="etched" title-resource-bundle="messages/AndroidBundle" title-key="android.apt.settings.title"/>
               <grid id="4c810" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
                 <margin top="0" left="4" bottom="0" right="0"/>
                 <constraints>
-                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                  <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
                 </constraints>
                 <properties/>
                 <border type="etched" title-resource-bundle="messages/AndroidBundle" title-key="android.aidl.settings.title"/>
               <grid id="3e085" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
                 <margin top="0" left="4" bottom="0" right="0"/>
                 <constraints>
-                  <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                  <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
                 </constraints>
                 <properties/>
                 <border type="etched" title-resource-bundle="messages/AndroidBundle" title-key="android.apk.settings.title"/>
               </grid>
               <vspacer id="e716a">
                 <constraints>
-                  <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+                  <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
                 </constraints>
               </vspacer>
               <component id="63343" class="javax.swing.JCheckBox" binding="myCopyResourcesFromArtifacts">
                   <text resource-bundle="messages/AndroidBundle" key="copy.resources.from.artifacts.setting"/>
                 </properties>
               </component>
+              <grid id="50185" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+                <margin top="0" left="0" bottom="0" right="0"/>
+                <constraints>
+                  <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties/>
+                <border type="etched" title-resource-bundle="messages/AndroidBundle" title-key="android.facet.compiler.settings.manifest.title"/>
+                <children>
+                  <component id="f22e9" class="javax.swing.JRadioButton" binding="myUseCompilerManifestFromStructureRadio">
+                    <constraints>
+                      <grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                    <properties>
+                      <text resource-bundle="messages/AndroidBundle" key="android.facet.settings.compiler.manifest.from.structure"/>
+                    </properties>
+                  </component>
+                  <component id="39195" class="javax.swing.JRadioButton" binding="myUseCustomCompilerManifestRadio">
+                    <constraints>
+                      <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                    <properties>
+                      <selected value="false"/>
+                      <text resource-bundle="messages/AndroidBundle" key="android.facet.settings.compiler.manifest.use.custom"/>
+                    </properties>
+                  </component>
+                  <component id="ec790" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myCustomCompilerManifestPathField">
+                    <constraints>
+                      <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                    </constraints>
+                    <properties/>
+                  </component>
+                </children>
+              </grid>
             </children>
           </grid>
         </children>
       <member id="d83b5"/>
       <member id="df739"/>
     </group>
+    <group name="buttonGroup2">
+      <member id="f22e9"/>
+      <member id="39195"/>
+    </group>
   </buttonGroups>
 </form>
index 6ca0c770a7a83606818b06d0936d573a907df704..a2e8b416cae3944a0d7906c67752c419daca589f 100644 (file)
@@ -103,6 +103,9 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
   private JCheckBox myGenerateUnsignedApk;
   private ComboboxWithBrowseButton myApkPathCombo;
   private JLabel myApkPathLabel;
+  private JRadioButton myUseCompilerManifestFromStructureRadio;
+  private JRadioButton myUseCustomCompilerManifestRadio;
+  private TextFieldWithBrowseButton myCustomCompilerManifestPathField;
 
   public AndroidFacetEditorTab(FacetEditorContext context, AndroidFacetConfiguration androidFacetConfiguration) {
     final Project project = context.getProject();
@@ -130,6 +133,9 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
     myCustomAptSourceDirField.getButton().addActionListener(new MyFolderFieldListener(myCustomAptSourceDirField,
                                                                                       AndroidAptCompiler.getCustomResourceDirForApt(facet),
                                                                                       false));
+    myCustomCompilerManifestPathField.getButton().addActionListener(new MyFolderFieldListener(myCustomCompilerManifestPathField,
+                                                                                              AndroidRootUtil.getManifestFileForCompiler(facet),
+                                                                                              true));
 
     myPlatformChooser.addListener(new AndroidPlatformChooserListener() {
       @Override
@@ -176,6 +182,15 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
     myUseCustomSourceDirectoryRadio.addActionListener(listener);
     myUseAptResDirectoryFromPathRadio.addActionListener(listener);
 
+    listener = new ActionListener() {
+      @Override
+      public void actionPerformed(ActionEvent e) {
+        myCustomCompilerManifestPathField.setEnabled(myUseCustomCompilerManifestRadio.isSelected());
+      }
+    };
+    myUseCustomCompilerManifestRadio.addActionListener(listener);
+    myUseCompilerManifestFromStructureRadio.addActionListener(listener);
+
     myIsLibraryProjectCheckbox.addActionListener(new ActionListener() {
       @Override
       public void actionPerformed(ActionEvent e) {
@@ -329,10 +344,17 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
     if (myUseCustomSourceDirectoryRadio.isSelected() != myConfiguration.USE_CUSTOM_APK_RESOURCE_FOLDER) {
       return true;
     }
-
     if (checkRelativePath(myConfiguration.CUSTOM_APK_RESOURCE_FOLDER, myCustomAptSourceDirField.getText())) {
       return true;
     }
+
+    if (myUseCustomCompilerManifestRadio.isSelected() != myConfiguration.USE_CUSTOM_COMPILER_MANIFEST) {
+      return true;
+    }
+    if (checkRelativePath(myConfiguration.CUSTOM_COMPILER_MANIFEST, myCustomCompilerManifestPathField.getText())) {
+      return true;
+    }
+
     if (myCopyResourcesFromArtifacts.isSelected() != myConfiguration.COPY_RESOURCES_FROM_ARTIFACTS) {
       return true;
     }
@@ -495,6 +517,12 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
     }
     myConfiguration.USE_CUSTOM_APK_RESOURCE_FOLDER = useCustomAptSrc;
 
+    boolean useCustomCompilerManifest = myUseCustomCompilerManifestRadio.isSelected();
+    if (myConfiguration.USE_CUSTOM_COMPILER_MANIFEST != useCustomCompilerManifest) {
+      runApt = true;
+    }
+    myConfiguration.USE_CUSTOM_COMPILER_MANIFEST = useCustomCompilerManifest;
+
     if (myConfiguration.REGENERATE_R_JAVA != myGenerateRJavaWhenChanged.isSelected()) {
       runApt = true;
     }
@@ -526,6 +554,25 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
       myConfiguration.CUSTOM_APK_RESOURCE_FOLDER = relPath != null ? '/' + relPath : "";
     }
 
+    String absCompilerManifestPath = myCustomCompilerManifestPathField.getText().trim();
+    if (useCustomCompilerManifest) {
+      if (absCompilerManifestPath.length() == 0) {
+        throw new ConfigurationException("AndroidManifest.xml path not specified in \"Compiler\" section");
+      }
+      String newCustomCompilerManifestPath = '/' + getAndCheckRelativePath(absCompilerManifestPath, false);
+      if (!SdkConstants.FN_ANDROID_MANIFEST_XML.equals(AndroidUtils.getSimpleNameByRelativePath(newCustomCompilerManifestPath))) {
+        throw new ConfigurationException("Manifest file must have name AndroidManifest.xml");
+      }
+      if (!newCustomCompilerManifestPath.equals(myConfiguration.CUSTOM_COMPILER_MANIFEST)) {
+        runApt = true;
+      }
+      myConfiguration.CUSTOM_COMPILER_MANIFEST = newCustomCompilerManifestPath;
+    }
+    else {
+      String relPath = toRelativePath(absCompilerManifestPath);
+      myConfiguration.CUSTOM_COMPILER_MANIFEST = relPath != null ? '/' + relPath : "";
+    }
+
     final AndroidPlatform platform = myPlatformChooser.getSelectedPlatform();
     myConfiguration.setAndroidPlatform(platform);
     final AndroidFacet facet = myConfiguration.getFacet();
@@ -657,6 +704,14 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
     myCustomAptSourceDirField.setText(aptSourceAbsPath != null ? aptSourceAbsPath : "");
     myCustomAptSourceDirField.setEnabled(configuration.USE_CUSTOM_APK_RESOURCE_FOLDER);
 
+    myUseCustomCompilerManifestRadio.setSelected(configuration.USE_CUSTOM_COMPILER_MANIFEST);
+    myUseCompilerManifestFromStructureRadio.setSelected(!configuration.USE_CUSTOM_COMPILER_MANIFEST);
+
+    String compilerManifestPath = configuration.CUSTOM_COMPILER_MANIFEST;
+    String compilerManifestAbsPath = compilerManifestPath.length() > 0 ? toAbsolutePath(compilerManifestPath) : "";
+    myCustomCompilerManifestPathField.setText(compilerManifestAbsPath != null ? compilerManifestAbsPath : "");
+    myCustomCompilerManifestPathField.setEnabled(configuration.USE_CUSTOM_COMPILER_MANIFEST);
+
     String apkPath = configuration.APK_PATH;
     String apkAbsPath = apkPath.length() > 0 ? toAbsolutePath(apkPath) : "";
     myApkPathCombo.getComboBox().getEditor().setItem(apkAbsPath != null ? apkAbsPath : "");
index 62dcd9f1128ee1a676b56660066af8026ceafa62..e63fa861d67797c9ce03e26341f1c1b4bbc4357d 100644 (file)
@@ -47,13 +47,18 @@ public class AndroidRootUtil {
   public static VirtualFile getManifestFile(@NotNull Module module) {
     AndroidFacet facet = AndroidFacet.getInstance(module);
     return facet == null ? null : getFileByRelativeModulePath(module, facet.getConfiguration().MANIFEST_FILE_RELATIVE_PATH, true);
+  }
 
-    /*VirtualFile[] files = ModuleRootManager.getInstance(module).getContentRoots();
-    for (VirtualFile contentRoot : files) {
-      VirtualFile manifest = contentRoot.findChild(SdkConstants.FN_ANDROID_MANIFEST_XML);
-      if (manifest != null) return manifest;
-    }
-    return null;*/
+  @Nullable
+  public static VirtualFile getCustomManifestFileForCompiler(@NotNull AndroidFacet facet) {
+    return getFileByRelativeModulePath(facet.getModule(), facet.getConfiguration().CUSTOM_COMPILER_MANIFEST, false);
+  }
+
+  @Nullable
+  public static VirtualFile getManifestFileForCompiler(AndroidFacet facet) {
+    return facet.getConfiguration().USE_CUSTOM_COMPILER_MANIFEST
+           ? getCustomManifestFileForCompiler(facet)
+           : getManifestFile(facet.getModule());
   }
 
   @Nullable
index 8922b2638565e4fbe47fab66271258b2deb43730..48cdece4dd3ec6d4ae0557d196e6869dab4cd801 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.CommonBundle;
 import com.intellij.execution.ExecutionBundle;
 import com.intellij.execution.configuration.BrowseModuleValueActionListener;
 import com.intellij.execution.ui.ConfigurationModuleSelector;
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
 import com.intellij.openapi.module.Module;
@@ -44,7 +45,7 @@ import org.jetbrains.annotations.Nullable;
 public class AndroidClassBrowser extends BrowseModuleValueActionListener {
   private final ConfigurationModuleSelector myModuleSelector;
   private final String myBaseClassName;
-  private final TreeClassChooser.ClassFilter myAdditionalFilter;
+  private final ClassFilter myAdditionalFilter;
   private final String myDialogTitle;
   private final boolean myIncludeLibraryClasses;
 
@@ -53,7 +54,7 @@ public class AndroidClassBrowser extends BrowseModuleValueActionListener {
                              String baseClassName,
                              String dialogTitle,
                              boolean includeLibraryClasses,
-                             @Nullable TreeClassChooser.ClassFilter additionalFilter) {
+                             @Nullable ClassFilter additionalFilter) {
     super(project);
     myModuleSelector = moduleSelector;
     myBaseClassName = baseClassName;
@@ -85,7 +86,7 @@ public class AndroidClassBrowser extends BrowseModuleValueActionListener {
       myIncludeLibraryClasses ? module.getModuleWithDependenciesAndLibrariesScope(true) : module.getModuleWithDependenciesScope();
     PsiClass initialSelection = facade.findClass(getText(), scope);
     TreeClassChooser chooser = TreeClassChooserFactory.getInstance(project)
-      .createInheritanceClassChooser(myDialogTitle, scope, baseClass, initialSelection, new TreeClassChooser.ClassFilter() {
+      .createInheritanceClassChooser(myDialogTitle, scope, baseClass, initialSelection, new ClassFilter() {
         public boolean isAccepted(PsiClass aClass) {
           if (aClass.getManager().areElementsEquivalent(aClass, baseClass)) {
             return false;
@@ -99,7 +100,7 @@ public class AndroidClassBrowser extends BrowseModuleValueActionListener {
         }
       });
     chooser.showDialog();
-    PsiClass selClass = chooser.getSelectedClass();
+    PsiClass selClass = chooser.getSelected();
     return selClass != null ? selClass.getQualifiedName() : null;
   }
 }
index 86c60e02ed90ba66673aa46111e13a8098f8c144..f6a086c8868242183acbacf632251fdf80e5e664 100644 (file)
@@ -192,8 +192,10 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati
       if (!activateDdmsIfNeccessary(facet)) {
         return null;
       }
-      if (!CHOOSE_DEVICE_MANUALLY) {
-        checkDebuggableOption(facet);
+      if (!CHOOSE_DEVICE_MANUALLY && PREFERRED_AVD.length() == 0) {
+        if (!checkDebuggableOption(facet)) {
+          return null;
+        }
       }
     }
 
@@ -217,7 +219,9 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati
         IDevice[] devices = chooseDevicesManually(facet);
         if (devices.length > 0) {
           if (debug && containsRealDevice(devices)) {
-            checkDebuggableOption(facet);
+            if (!checkDebuggableOption(facet)) {
+              return null;
+            }
           }
           deviceSerialNumbers = new String[devices.length];
           for (int i = 0; i < devices.length; i++) {
@@ -243,7 +247,7 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati
     return null;
   }
 
-  private static void checkDebuggableOption(@NotNull AndroidFacet facet) {
+  private static boolean checkDebuggableOption(@NotNull AndroidFacet facet) {
     Manifest manifest = facet.getManifest();
     // validated in checkConfiguration()
     assert manifest != null;
@@ -253,7 +257,7 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati
       BooleanValueConverter booleanValueConverter = BooleanValueConverter.getInstance(true);
       if (debuggable == null || !booleanValueConverter.isTrue(debuggable)) {
         Project project = facet.getModule().getProject();
-        int result = Messages.showYesNoDialog(project, AndroidBundle.message("android.manifest.debuggable.attribute.not.true.warning"),
+        int result = Messages.showYesNoCancelDialog(project, AndroidBundle.message("android.manifest.debuggable.attribute.not.true.warning"),
                                               CommonBundle.getWarningTitle(),
                                               Messages.getWarningIcon());
         if (result == 0) {
@@ -264,8 +268,10 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati
             }
           });
         }
+        return result != 2;
       }
     }
+    return true;
   }
 
   private static boolean activateDdmsIfNeccessary(@NotNull AndroidFacet facet) {
index 118372f4492a9bbf6b315b8204be41b5c014759b..01e0121a8f6b40398829e4346b100c0d6d93fd70 100644 (file)
@@ -102,7 +102,7 @@ public abstract class AndroidRunningState implements RunProfileState, AndroidDeb
   private volatile ProcessHandler myProcessHandler;
   private final Object myLock = new Object();
 
-  private boolean myDeploy;
+  private boolean myDeploy = true;
 
   public void setDebugMode(boolean debugMode) {
     myDebugMode = debugMode;
@@ -419,7 +419,7 @@ public abstract class AndroidRunningState implements RunProfileState, AndroidDeb
     if (!isAndroidSdk15OrHigher()) {
       return true;
     }
-    String avdName = device.getAvdName();
+    String avdName = device.isEmulator() ? device.getAvdName() : null;
     if (myAvdName != null) {
       return myAvdName.equals(avdName);
     }
index 8a1e9ff08b316b498c832b5168defba9484f2502..c70e52630031002cd0465aad27d85c8a586716fd 100644 (file)
@@ -18,6 +18,7 @@ package org.jetbrains.android.run;
 
 import com.intellij.execution.ExecutionBundle;
 import com.intellij.execution.ui.ConfigurationModuleSelector;
+import com.intellij.ide.util.ClassFilter;
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
 import com.intellij.openapi.module.Module;
@@ -52,7 +53,7 @@ class ApplicationRunParameters implements ConfigurationSpecificEditor<AndroidRun
 
   private final ConfigurationModuleSelector myModuleSelector;
 
-  private class ActivityClassFilter implements TreeClassChooser.ClassFilter {
+  private class ActivityClassFilter implements ClassFilter {
     public boolean isAccepted(PsiClass c) {
       Module module = myModuleSelector.getModule();
       if (module != null) {
@@ -82,7 +83,7 @@ class ApplicationRunParameters implements ConfigurationSpecificEditor<AndroidRun
           .createInheritanceClassChooser("Select activity class", module.getModuleWithDependenciesScope(), activityBaseClass,
                                          initialSelection, new ActivityClassFilter());
         chooser.showDialog();
-        PsiClass selClass = chooser.getSelectedClass();
+        PsiClass selClass = chooser.getSelected();
         if (selClass != null) {
           myActivityField.setText(selClass.getQualifiedName());
         }
index 789e548f774358f90aa41efbaa8d399c6877b8fb..f5b55e346115c0d12d811e6e1bc4658a6f77ee0b 100644 (file)
@@ -426,7 +426,7 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis
       });
     }<