Merge branch 'master' of git.labs.intellij.net:idea/community
authornik <Nikolay.Chashnikov@jetbrains.com>
Wed, 29 Dec 2010 07:27:15 +0000 (10:27 +0300)
committernik <Nikolay.Chashnikov@jetbrains.com>
Wed, 29 Dec 2010 12:26:54 +0000 (15:26 +0300)
145 files changed:
java/idea-ui/src/com/intellij/openapi/projectRoots/ui/SdkEditor.java
java/java-impl/src/com/intellij/codeInsight/completion/ImportStaticLookupActionProvider.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionFeatures.java
java/java-impl/src/com/intellij/codeInsight/completion/StaticMemberProcessor.java
java/java-impl/src/com/intellij/codeInsight/intention/impl/ColorChooserIntentionAction.java
java/java-impl/src/com/intellij/codeInsight/preview/JavaPreviewHintProvider.java
java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java
java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java
java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java
java/java-tests/testData/refactoring/safeDelete/safeDeleteStaticImports/after/A.java [new file with mode: 0644]
java/java-tests/testData/refactoring/safeDelete/safeDeleteStaticImports/after/B.java [new file with mode: 0644]
java/java-tests/testData/refactoring/safeDelete/safeDeleteStaticImports/before/A.java [new file with mode: 0644]
java/java-tests/testData/refactoring/safeDelete/safeDeleteStaticImports/before/B.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/psi/ClsBuilderTest.java
java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java
java/java-tests/testSrc/com/intellij/roots/OrderEnumeratorTest.java
platform/icons/src/ide/errorPoint.png [new file with mode: 0644]
platform/icons/src/ide/errorSign.png [new file with mode: 0644]
platform/lang-api/src/com/intellij/codeInspection/ex/ScopeToolState.java
platform/lang-api/src/com/intellij/openapi/roots/OrderRootType.java
platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DefaultHighlightVisitor.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IndentsPass.java
platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java
platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java
platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java
platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java
platform/lang-impl/src/com/intellij/codeInsight/preview/ColorPreviewComponent.java
platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java
platform/lang-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java
platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java
platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java
platform/lang-impl/src/com/intellij/formatting/BulkReformatListener.java [deleted file]
platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java
platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java
platform/lang-impl/src/com/intellij/formatting/IndentInfo.java
platform/lang-impl/src/com/intellij/ide/bookmarks/Bookmark.java
platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java
platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java
platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
platform/lang-impl/src/com/intellij/injected/editor/SelectionModelWindow.java
platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderEnumeratorBase.java
platform/lang-impl/src/com/intellij/profile/codeInspection/ui/actions/AddScopeAction.java
platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java
platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureGestureDetector.java
platform/lang-impl/src/com/intellij/refactoring/changeSignature/RenameChangeInfo.java
platform/platform-api/src/com/intellij/ide/util/DelegatingProgressIndicator.java
platform/platform-api/src/com/intellij/mock/MockProgressIndicator.java
platform/platform-api/src/com/intellij/openapi/application/Application.java
platform/platform-api/src/com/intellij/openapi/application/ModalityState.java
platform/platform-api/src/com/intellij/openapi/editor/CaretModel.java
platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
platform/platform-api/src/com/intellij/openapi/editor/SelectionModel.java
platform/platform-api/src/com/intellij/openapi/editor/event/DocumentEvent.java
platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
platform/platform-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.java
platform/platform-api/src/com/intellij/openapi/progress/ProgressIndicator.java
platform/platform-api/src/com/intellij/openapi/project/ProjectManager.java
platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
platform/platform-api/src/com/intellij/util/Alarm.java
platform/platform-api/src/com/intellij/util/ui/update/MergingUpdateQueue.java
platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
platform/platform-impl/src/com/intellij/openapi/application/impl/LaterInvocator.java
platform/platform-impl/src/com/intellij/openapi/application/impl/ModalityStateEx.java
platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/PersistentLineMarker.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/PersistentRangeMarker.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/PersistentRangeMarkerUtil.java [new file with mode: 0644]
platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/event/DocumentEventImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java
platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentSelectionModel.java
platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java
platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java
platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java
platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java
platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java
platform/platform-impl/testSrc/com/intellij/ide/bookmarks/BookmarkManagerTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java
platform/platform-resources-en/src/messages/FeatureStatisticsBundle.properties
platform/platform-resources/src/META-INF/XmlPlugin.xml
platform/platform-resources/src/componentSets/VCS.xml
platform/testFramework/src/com/intellij/mock/MockApplication.java
platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java
platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
platform/vcs-api/src/com/intellij/lifecycle/PeriodicalTasksCloser.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ExecutorWrapper.java
plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/cvsExecution/ModalityContext.java
plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsExecution/CvsOperationExecutor.java
plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsExecution/ModalityContextImpl.java
plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvshandlers/UpdateHandler.java
plugins/devkit/src/projectRoots/IdeaJdk.java
plugins/devkit/src/projectRoots/IdeaJdkConfigurable.java
plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutListener.java
plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java
plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java
plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java
plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParser.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/VariableInitializer.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/SwitchStatement.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/VariableDefinitions.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/AssignmentExpression.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/ExpressionStatement.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arguments/CommandArguments.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/UnaryExpressionNotPlusMinus.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/ClosureParameterEnhancer.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/CollectClassMembersUtil.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GroovyVariableValidator.java
plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/ExpressionsParsingTest.groovy
plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy
plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolvePropertyTest.groovy
plugins/groovy/test/org/jetbrains/plugins/groovy/lang/smartEnter/SmartEnterTest.java
plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceVariable/IntroduceVariableTest.java
plugins/groovy/testdata/groovy/actions/smartEnter/listFixer.test [new file with mode: 0644]
plugins/groovy/testdata/groovy/oldCompletion/keyword/ins2.test
plugins/groovy/testdata/groovy/refactoring/introduceVariable/inCase.test [new file with mode: 0644]
plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/RHS.test [new file with mode: 0644]
plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/closureArg2.test [new file with mode: 0644]
plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/fourArgs.test
plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/indexAccess1.test [new file with mode: 0644]
plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/indexAccess2.test [new file with mode: 0644]
plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/indexAccess3.test [new file with mode: 0644]
plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/oddArgCount.test [new file with mode: 0644]
plugins/groovy/testdata/parsing/groovy/statements/switch/swit5.test
plugins/groovy/testdata/resolve/class/innerClassIsNotResolvedInAnonymous/A.groovy [new file with mode: 0644]
plugins/groovy/testdata/resolve/class/innerClassIsResolvedInAnonymous/A.groovy [new file with mode: 0644]
plugins/groovy/testdata/resolve/property/propertyInExprStatement/A.groovy [new file with mode: 0644]
plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/browserCache/RepositoryLoader.java
plugins/testng/lib/testng-jdk15.jar
plugins/testng/src/com/theoryinpractice/testng/configuration/SearchingForTestsTask.java
plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java
resources/src/ProductivityFeaturesRegistry.xml
xml/dom-impl/src/com/intellij/util/xml/impl/PhysicalDomParentStrategy.java
xml/dom-openapi/src/com/intellij/util/xml/actions/generate/AbstractDomGenerateProvider.java
xml/dom-openapi/src/com/intellij/util/xml/actions/generate/DefaultGenerateElementProvider.java
xml/impl/src/com/intellij/lang/xml/XMLExternalAnnotator.java
xml/impl/src/com/intellij/psi/impl/source/xml/XmlElementImpl.java

index f8ebd6dd79e47cd9dd9b630e1d6428c90deaea77..a6718c1224b05fa2f73aa2dcb0b6288a3868997f 100644 (file)
@@ -406,7 +406,11 @@ public class SdkEditor implements Configurable, Place.Navigator {
     }
 
     public VirtualFile[] getRoots(OrderRootType rootType) {
-      return myPathEditors.get(rootType).getRoots();
+      final PathEditor editor = myPathEditors.get(rootType);
+      if (editor == null) {
+        throw new IllegalStateException("no editor for root type " + rootType);
+      }
+      return editor.getRoots();
     }
 
     public void addRoot(VirtualFile root, OrderRootType rootType) {
index 4c8e8b878b4add2340e6599d44cfdaed91f0c5cb..10441159129a3cb527f97fd4eeee304ad1202b45 100644 (file)
@@ -28,8 +28,6 @@ public class ImportStaticLookupActionProvider implements LookupActionProvider {
     consumer.consume(new LookupElementAction(icon, "Import statically") {
       @Override
       public Result performLookupAction() {
-        FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.IMPORT_STATIC);
-
         item.setShouldBeImported(!item.willBeImported());
         return Result.REFRESH_ITEM;
       }
index d02355bb6fcb31b482b0522b67f2b3b56de42057..845a3f79b159dbf8a813e56f8b3b8e2a902d6537 100644 (file)
@@ -361,6 +361,18 @@ public class JavaCompletionContributor extends CompletionContributor {
   public String advertise(@NotNull final CompletionParameters parameters) {
     if (!(parameters.getOriginalFile() instanceof PsiJavaFile)) return null;
 
+    if (parameters.getCompletionType() == CompletionType.BASIC && parameters.getInvocationCount() > 0) {
+      PsiElement position = parameters.getPosition();
+      if (psiElement().withParent(psiReferenceExpression().withFirstChild(psiReferenceExpression().referencing(psiClass()))).accepts(position)) {
+        if (CompletionUtil.shouldShowFeature(parameters, JavaCompletionFeatures.GLOBAL_MEMBER_NAME)) {
+          final String shortcut = getActionShortcut(IdeActions.ACTION_CLASS_NAME_COMPLETION);
+          if (shortcut != null) {
+            return "Pressing " + shortcut + " without a class qualifier would show all accessible static methods";
+          }
+        }
+      }
+    }
+
     if (parameters.getCompletionType() != CompletionType.SMART && shouldSuggestSmartCompletion(parameters.getPosition())) {
       if (CompletionUtil.shouldShowFeature(parameters, CodeCompletionFeatures.EDITING_COMPLETION_SMARTTYPE_GENERAL)) {
         final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION);
index 144bc8ca81a05ee63f39caa88c22b8593fa17234..c775281e16edf94edc62b708d5282668fa0373b9 100644 (file)
@@ -25,7 +25,7 @@ public interface JavaCompletionFeatures {
   @NonNls String SECOND_SMART_COMPLETION_TOAR = "editing.completion.second.smarttype.toar";
   @NonNls String SECOND_SMART_COMPLETION_ASLIST = "editing.completion.second.smarttype.aslist";
   @NonNls String SECOND_SMART_COMPLETION_ARRAY_MEMBER = "editing.completion.second.smarttype.array.member";
-  @NonNls String IMPORT_STATIC = "editing.completion.import.static";
+  @NonNls String GLOBAL_MEMBER_NAME = "editing.completion.global.member.name";
   @NonNls String AFTER_NEW = "editing.completion.smarttype.afternew";
   @NonNls String AFTER_NEW_ANONYMOUS = "editing.completion.smarttype.afternew";
 }
index d0045ccf6fb1bbd0822021d022abcf0bb589eca3..74c6384d32d09c13e688f7d15fab0ac4001f6ec4 100644 (file)
@@ -44,6 +44,8 @@ public abstract class StaticMemberProcessor {
   }
 
   public void processStaticMethodsGlobally(final CompletionResultSet resultSet) {
+    FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.GLOBAL_MEMBER_NAME);
+
     final Consumer<LookupElement> consumer = new Consumer<LookupElement>() {
       @Override
       public void consume(LookupElement element) {
@@ -64,10 +66,7 @@ public abstract class StaticMemberProcessor {
 
             if (classes.add(containingClass)) {
               final boolean shouldImport = myStaticImportedClasses.contains(containingClass);
-              if (!myHintShown &&
-                  !shouldImport &&
-                  FeatureUsageTracker.getInstance().isToBeShown(JavaCompletionFeatures.IMPORT_STATIC, myProject) &&
-                  CompletionService.getCompletionService().getAdvertisementText() == null) {
+              if (!myHintShown && !shouldImport && CompletionService.getCompletionService().getAdvertisementText() == null) {
                 final String shortcut = CompletionContributor.getActionShortcut("EditorRight");
                 if (shortcut != null) {
                   CompletionService.getCompletionService().setAdvertisementText("To import a method statically, press " + shortcut);
index 606b9acef5385a2aeb5e0eea88a3547bec97f1ed..3c878c4fc32f68ed86c9faf541c32ed33bcd09fd 100644 (file)
@@ -27,7 +27,9 @@ import com.intellij.codeInsight.CodeInsightUtilBase;
 import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
-import com.intellij.patterns.PlatformPatterns;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.patterns.PsiJavaPatterns;
+import com.intellij.patterns.PsiMethodPattern;
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.CodeStyleManager;
 import com.intellij.psi.util.PsiTreeUtil;
@@ -35,39 +37,116 @@ import com.intellij.ui.ColorChooser;
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.NotNull;
 
+import javax.swing.*;
 import java.awt.*;
 
+import static com.intellij.patterns.PlatformPatterns.psiElement;
+
+/**
+ * @author spleaner
+ * @author Konstantin Bulenkov
+ */
 public class ColorChooserIntentionAction extends PsiElementBaseIntentionAction {
+  private static final String JAVA_AWT_COLOR = "java.awt.Color";
+
+  private static final PsiMethodPattern DECODE_METHOD = PsiJavaPatterns.psiMethod()
+    .definedInClass(JAVA_AWT_COLOR)
+    .withName("decode");
+
+  private static final PsiMethodPattern GET_COLOR_METHOD = PsiJavaPatterns.psiMethod()
+    .definedInClass(JAVA_AWT_COLOR)
+    .withName("getColor");
+
+
+  public ColorChooserIntentionAction() {
+    setText(CodeInsightBundle.message("intention.color.chooser.dialog"));
+  }
 
   public boolean isAvailable(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) {
-    if (PlatformPatterns.psiElement().inside(PlatformPatterns.psiElement(PsiNewExpression.class)).accepts(element)) {
+    // new Color(...)
+    if (psiElement().inside(psiElement(PsiNewExpression.class)).accepts(element)) {
       final PsiNewExpression expression = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class, false);
       if (expression != null) {
-        final PsiJavaCodeReferenceElement referenceElement = PsiTreeUtil.getChildOfType(expression, PsiJavaCodeReferenceElement.class);
-        if (referenceElement != null) {
-          final PsiReference reference = referenceElement.getReference();
-          if (reference != null) {
-            final PsiElement psiElement = reference.resolve();
-            if (psiElement instanceof PsiClass && "java.awt.Color".equals(((PsiClass)psiElement).getQualifiedName())) {
-              setText(CodeInsightBundle.message("intention.color.chooser.dialog"));
-              return true;
-            }
-          }
-        }
+        final PsiJavaCodeReferenceElement ref = PsiTreeUtil.getChildOfType(expression, PsiJavaCodeReferenceElement.class);
+        if (isJavaAwtColor(ref)) return true;
       }
     }
+    // Color.decode("...")
+    if (isInsideDecodeOrGetColorMethod(element)) {
+      return true;
+    }
 
     return false;
   }
 
+  public static boolean isInsideDecodeOrGetColorMethod(PsiElement element) {
+    if (element instanceof PsiJavaToken && ((PsiJavaToken)element).getTokenType() == JavaTokenType.STRING_LITERAL) {
+      element = element.getParent();
+    }
+
+    return PsiJavaPatterns.psiExpression().methodCallParameter(0, DECODE_METHOD).accepts(element)
+           ||
+           PsiJavaPatterns.psiExpression().methodCallParameter(0, GET_COLOR_METHOD).accepts(element);
+  }
+
+  private static boolean isJavaAwtColor(final PsiJavaCodeReferenceElement ref) {
+    if (ref != null) {
+      final PsiReference reference = ref.getReference();
+      if (reference != null) {
+        final PsiElement psiElement = reference.resolve();
+        if (psiElement instanceof PsiClass && JAVA_AWT_COLOR.equals(((PsiClass)psiElement).getQualifiedName())) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
   @NotNull
   public String getFamilyName() {
-    return CodeInsightBundle.message("intention.color.chooser.dialog");
+    return getText();
   }
 
   public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
     if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;
     PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
+    final JComponent editorComponent = editor.getComponent();
+    if (isInsideDecodeOrGetColorMethod(element)) {
+      invokeForMethodParam(editorComponent, element);
+    } else {
+      invokeForConstructor(editorComponent, element);
+    }
+  }
+
+  private void invokeForMethodParam(JComponent editorComponent, PsiElement element) {
+    final PsiLiteralExpression literal = PsiTreeUtil.getParentOfType(element, PsiLiteralExpression.class);
+    if (literal == null) return;
+    final String text = StringUtil.unquoteString(literal.getText());
+    final int radix = text.startsWith("0x") || text.startsWith("0X") || text.startsWith("#") ? 16 : text.startsWith("0") ? 8 : 10;
+    final String hexPrefix = radix == 16 ? text.startsWith("#") ? "#" : text.substring(0, 2) : null;
+
+    Color oldColor;
+    try {
+      oldColor = Color.decode(text);
+    }
+    catch (NumberFormatException e) {
+      oldColor = Color.GRAY;
+    }
+    Color color = ColorChooser.chooseColor(editorComponent, getText(), oldColor);
+    if (color == null) return;
+    final int rgb = color.getRGB() - ((255 & 0xFF) << 24);
+    if (color != null && rgb != oldColor.getRGB()) {
+      final String newText = radix == 16 ? hexPrefix + String.format("%6s" ,Integer.toHexString(rgb)).replace(' ', '0')
+                           : radix == 8  ? "0" + Integer.toOctalString(rgb)
+                           : Integer.toString(rgb);
+      final PsiManager manager = literal.getManager();
+      final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
+      final PsiExpression newLiteral = factory.createExpressionFromText("\"" + newText + "\"", literal);
+      literal.replace(newLiteral);
+    }
+  }
+
+  private void invokeForConstructor(JComponent editorComponent, PsiElement element) {
     final PsiNewExpression expression = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class);
     if (expression == null) return;
 
@@ -94,46 +173,60 @@ public class ColorChooserIntentionAction extends PsiElementBaseIntentionAction {
         }
       }
 
-      if (i == expressions.length) {
-        switch (values.length) {
-          case 1:
-            c = new Color(values[0]);
-            break;
-          case 3:
-            c = new Color(values[0], values[1], values[2]);
-            break;
-          case 4:
-            c = new Color(values[0], values[1], values[2], values[3]);
-            break;
-          default:
-            break;
+      try {
+        if (i == expressions.length) {
+          switch (values.length) {
+            case 1:
+              c = new Color(values[0]);
+              break;
+            case 3:
+              c = new Color(values[0], values[1], values[2]);
+              break;
+            case 4:
+              c = new Color(values[0], values[1], values[2], values[3]);
+              break;
+            default:
+              break;
+          }
         }
-      }
-      else if (j == expressions.length) {
-        switch (values2.length) {
-          case 3:
-            c = new Color(values2[0], values2[1], values2[2]);
-            break;
-          case 4:
-            c = new Color(values2[0], values2[1], values2[2], values2[3]);
-            break;
-          default:
-            break;
+        else if (j == expressions.length) {
+          switch (values2.length) {
+            case 3:
+              c = new Color(values2[0], values2[1], values2[2]);
+              break;
+            case 4:
+              c = new Color(values2[0], values2[1], values2[2], values2[3]);
+              break;
+            default:
+              break;
+          }
         }
       }
+      catch (Exception e) {
+        c = Color.GRAY;
+      }
     }
 
     c = (c == null) ? Color.GRAY : c;
 
-    final Color color = ColorChooser.chooseColor(editor.getComponent(), CodeInsightBundle.message("intention.color.chooser.dialog"), c);
+    replaceColor(editorComponent, expression, c);
+  }
+
+  private void replaceColor(JComponent editorComponent, PsiNewExpression expression, Color oldColor) {
+    final Color color = ColorChooser.chooseColor(editorComponent, getText(), oldColor);
     if (color != null) {
       final PsiManager manager = expression.getManager();
       final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
       final PsiExpression newCall = factory.createExpressionFromText(
-          "new java.awt.Color(" + color.getRed() + ", " + color.getGreen() + ", " + color.getBlue() + ")", expression);
+          "new " + JAVA_AWT_COLOR +"("
+          + color.getRed() + ", "
+          + color.getGreen() + ", "
+          + color.getBlue()
+          + (oldColor.getAlpha() < 255 ? ", " + oldColor.getAlpha() : "")
+          +")", expression);
       final PsiElement insertedElement = expression.replace(newCall);
       final CodeStyleManager codeStyleManager = manager.getCodeStyleManager();
       codeStyleManager.reformat(insertedElement);
     }
   }
-}
\ No newline at end of file
+}
index a9cdcf97f160b511525da72250ec61ac61f8006e..266e899439a1f61516d6cf09aa1cff920a4bb914 100644 (file)
@@ -15,6 +15,8 @@
  */
 package com.intellij.codeInsight.preview;
 
+import com.intellij.codeInsight.intention.impl.ColorChooserIntentionAction;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.patterns.PlatformPatterns;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiTreeUtil;
@@ -108,7 +110,7 @@ public class JavaPreviewHintProvider implements PreviewHintProvider {
               }
 
               if (c != null) {
-                return new ColorPreviewComponent(null, c);
+                return new ColorPreviewComponent(c);
               }
             }
           }
@@ -116,6 +118,13 @@ public class JavaPreviewHintProvider implements PreviewHintProvider {
       }
     }
 
+    if (ColorChooserIntentionAction.isInsideDecodeOrGetColorMethod(element)) {
+      final String color = StringUtil.unquoteString(element.getText());
+      try {
+        return new ColorPreviewComponent(Color.decode(color));
+      } catch (NumberFormatException ignore) {}
+    }
+
     if (PlatformPatterns.psiElement(PsiIdentifier.class).withParent(PlatformPatterns.psiElement(PsiReferenceExpression.class))
       .accepts(element)) {
       final PsiReference reference = element.getParent().getReference();
@@ -127,7 +136,7 @@ public class JavaPreviewHintProvider implements PreviewHintProvider {
           if ("java.awt.Color".equals(((PsiField)psiElement).getContainingClass().getQualifiedName())) {
             final String colorName = ((PsiField)psiElement).getName().toLowerCase().replace("_", "");
             final String hex = ColorSampleLookupValue.getHexCodeForColorName(colorName);
-            return new ColorPreviewComponent(null, Color.decode("0x" + hex.substring(1)));
+            return new ColorPreviewComponent(Color.decode("0x" + hex.substring(1)));
           }
         }
       }
index cc478cc9dc29375d8615dee254073560991ece45..964ef742c369a536be5325ab7fd92820454f69a5 100644 (file)
@@ -18,6 +18,7 @@ package com.intellij.openapi.projectRoots.impl;
 import com.intellij.openapi.application.PathManager;
 import com.intellij.openapi.project.ProjectBundle;
 import com.intellij.openapi.projectRoots.*;
+import com.intellij.openapi.roots.AnnotationOrderRootType;
 import com.intellij.openapi.roots.JavadocOrderRootType;
 import com.intellij.openapi.roots.OrderRootType;
 import com.intellij.openapi.util.IconLoader;
@@ -485,4 +486,11 @@ public class JavaSdkImpl extends JavaSdk {
     return LocalFileSystem.getInstance().findFileByPath(path);
   }
 
+  @Override
+  public boolean isRootTypeApplicable(OrderRootType type) {
+    return type == OrderRootType.CLASSES ||
+           type == OrderRootType.SOURCES ||
+           type == JavadocOrderRootType.getInstance() ||
+           type == AnnotationOrderRootType.getInstance();
+  }
 }
index fcd9f23942d8f476087a33168859afb0dc6e2b0d..25788159481d6b4619b812f80077a0e2cef121b4 100644 (file)
@@ -277,7 +277,8 @@ public class JavaChangeSignatureDetector implements LanguageChangeSignatureDetec
         final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(psiElement.getProject());
         final Document document = documentManager.getDocument(file);
         if (document != null) {
-          document.setText(oldText);
+          final TextRange textRange = psiElement.getTextRange();
+          document.replaceString(textRange.getStartOffset(), textRange.getEndOffset(), oldText);
           documentManager.commitDocument(document);
         }
       }
index 65a80c335b76aae3989716dbad16889a887c7ae1..6db581792a2759c1c714c4973e31761cd5d0fd86 100644 (file)
@@ -393,7 +393,7 @@ public class JavaSafeDeleteProcessor implements SafeDeleteProcessorDelegate {
     for (PsiReference reference : references) {
       final PsiElement element = reference.getElement();
       if (!isInside(element, allElementsToDelete) && !isInside(element, overridingMethods)) {
-        usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(element, psiMethod, false));
+        usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(element, psiMethod, PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class) != null));
       }
     }
 
@@ -612,7 +612,7 @@ public class JavaSafeDeleteProcessor implements SafeDeleteProcessorDelegate {
           else {
             TextRange range = reference.getRangeInElement();
             usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(reference.getElement(), psiField, range.getStartOffset(),
-                                                                    range.getEndOffset(), false, false));
+                                                                    range.getEndOffset(), false, PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class) != null));
           }
         }
 
diff --git a/java/java-tests/testData/refactoring/safeDelete/safeDeleteStaticImports/after/A.java b/java/java-tests/testData/refactoring/safeDelete/safeDeleteStaticImports/after/A.java
new file mode 100644 (file)
index 0000000..3258116
--- /dev/null
@@ -0,0 +1,3 @@
+public class A {
+  }
+
diff --git a/java/java-tests/testData/refactoring/safeDelete/safeDeleteStaticImports/after/B.java b/java/java-tests/testData/refactoring/safeDelete/safeDeleteStaticImports/after/B.java
new file mode 100644 (file)
index 0000000..dea4708
--- /dev/null
@@ -0,0 +1,4 @@
+
+class B {
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/safeDelete/safeDeleteStaticImports/before/A.java b/java/java-tests/testData/refactoring/safeDelete/safeDeleteStaticImports/before/A.java
new file mode 100644 (file)
index 0000000..73f3445
--- /dev/null
@@ -0,0 +1,4 @@
+public class A {
+  static void b<caret>ar() {}
+}
+
diff --git a/java/java-tests/testData/refactoring/safeDelete/safeDeleteStaticImports/before/B.java b/java/java-tests/testData/refactoring/safeDelete/safeDeleteStaticImports/before/B.java
new file mode 100644 (file)
index 0000000..5ba90f1
--- /dev/null
@@ -0,0 +1,4 @@
+import static A.bar;
+class B {
+
+}
\ No newline at end of file
index 873ef3abc1413728dac149083fa551755ec17328..eae004f73a6d86334b2d0d722e72307b415791ff 100644 (file)
@@ -4,8 +4,6 @@
 package com.intellij.psi;
 
 import com.intellij.JavaTestUtil;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
 import com.intellij.openapi.roots.OrderRootType;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.StringUtil;
@@ -23,11 +21,6 @@ import java.io.FileWriter;
 import java.io.IOException;
 
 public class ClsBuilderTest extends LightIdeaTestCase {
-  @Override
-  protected Sdk getProjectJDK() {
-    return JavaSdkImpl.getMockJdk17();
-  }
-
   public void testUtilList() throws Exception {
     doTest("java/util/List.class");
   }
index 41bfe7c0944ee2e9e7b28b3f80ed7726b8db3a96..c8982184a57ae62522b25638459f7406f9fbfaf5 100644 (file)
@@ -77,6 +77,11 @@ public class SafeDeleteTest extends MultiFileTestCase {
     doTest("UserFlags");
   }
 
+  public void testSafeDeleteStaticImports() throws Exception {
+    myDoCompare = false;
+    doTest("A");
+  }
+
   public void testRemoveOverridersInspiteOfUnsafeUsages() throws Exception {
     myDoCompare = false;
     try {
index fe7aaf2b1c05e6cf267febb98ecd0022a9559c02..61c5abb968f21738cc1a4d8d6ef84b0f0677e3dd 100644 (file)
@@ -77,9 +77,13 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase {
                           depOutput, getJDomJar());
 
     assertClassRoots(orderEntries(myModule).withoutSdk().withoutModuleSourceEntries().recursively(),
-                     depTestOutput, depOutput, getJDomJar());
+                     getJDomJar());
     assertSourceRoots(orderEntries(myModule).withoutSdk().withoutModuleSourceEntries().recursively(),
-                      depSrcRoot, depTestRoot, getJDomSources());
+                      getJDomSources());
+    assertEnumeratorRoots(orderEntries(myModule).withoutSdk().withoutModuleSourceEntries().recursively().classes(),
+                          getJDomJar());
+    assertEnumeratorRoots(orderEntries(myModule).withoutSdk().withoutModuleSourceEntries().recursively().sources(),
+                          getJDomSources());
   }
 
   public void testModuleDependencyScope() throws Exception {
diff --git a/platform/icons/src/ide/errorPoint.png b/platform/icons/src/ide/errorPoint.png
new file mode 100644 (file)
index 0000000..2a08c2f
Binary files /dev/null and b/platform/icons/src/ide/errorPoint.png differ
diff --git a/platform/icons/src/ide/errorSign.png b/platform/icons/src/ide/errorSign.png
new file mode 100644 (file)
index 0000000..d4c1991
Binary files /dev/null and b/platform/icons/src/ide/errorSign.png differ
index 4fe605315da72c14f8fa7ea0e0df8b7cc78ed6c7..9a6771e4f2ef8bbf9c65be80f6497c012900f7de 100644 (file)
@@ -73,6 +73,16 @@ public class ScopeToolState {
     return myScope;
   }
 
+  @Nullable
+  public NamedScope getScope(Project project) {
+    if (myScope == null) {
+      if (project != null) {
+        myScope = NamedScopesHolder.getScope(project, myScopeName);
+      }
+    }
+    return myScope;
+  }
+
   public String getScopeName() {
     return myScopeName;
   }
index 402413f4c5edbd59e4da341660a99174b780a05e..a49de130ca96ad6edf5f58e5fa2a7ca3d220d65a 100644 (file)
@@ -87,7 +87,7 @@ public class OrderRootType {
   public static final OrderRootType PRODUCTION_COMPILATION_CLASSES = new OrderRootType("PRODUCTION_COMPILATION_CLASSES");
 
   /**
-   * Classpath without output directories for this module.
+   * Classpath without output directories for modules.
    * Includes:
    * <li>  classes roots for libraries and jdk
    * <li>  recursively for module dependencies: only exported items
index 023639844e1d0652fbbf8fee16363dc9a7409ccb..c26d7ec945742d21faf99203c768e7194d8c88ff 100644 (file)
@@ -613,15 +613,9 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
       public void run() {
         DocumentEx document = (DocumentEx) myEditor.getDocument();
 
-        document.setInBulkUpdate(true);
-        try {
-          document.setText(documentText);
-          myEditor.getSelectionModel().setSelection(selStart, selEnd);
-          myEditor.getCaretModel().moveToOffset(caret);
-        }
-        finally {
-          document.setInBulkUpdate(false);
-        }
+        document.replaceString(0, myEditor.getCaretModel().getOffset(), documentText.substring(0, caret));
+        document.replaceString(caret, document.getTextLength(), documentText.substring(caret));
+        myEditor.getSelectionModel().setSelection(selStart, selEnd);
       }
     });
   }
index c569d0cab7f1c41ee4368c7baa39dd1a2b1e369c..56f3bd3021b31f2af47806eadee98d899377dcbf 100644 (file)
@@ -116,22 +116,26 @@ public class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
     final boolean dumb = myDumbService.isDumb();
     annotationHolder.setSession(holder.getAnnotationSession());
 
-    //noinspection ForLoopReplaceableByForEach
-    for (int i = 0; i < annotators.size(); i++) {
-      Annotator annotator = annotators.get(i);
-      if (dumb && !DumbService.isDumbAware(annotator)) {
-        continue;
+    try {
+      //noinspection ForLoopReplaceableByForEach
+      for (int i = 0; i < annotators.size(); i++) {
+        Annotator annotator = annotators.get(i);
+        if (dumb && !DumbService.isDumbAware(annotator)) {
+          continue;
+        }
+
+        annotator.annotate(element, annotationHolder);
       }
 
-      annotator.annotate(element, annotationHolder);
-    }
-
-    if (annotationHolder.hasAnnotations()) {
-      for (Annotation annotation : annotationHolder) {
-        holder.add(HighlightInfo.fromAnnotation(annotation));
+      if (annotationHolder.hasAnnotations()) {
+        for (Annotation annotation : annotationHolder) {
+          holder.add(HighlightInfo.fromAnnotation(annotation));
+        }
       }
     }
-    annotationHolder.clear();
+    finally {
+      annotationHolder.clear();
+    }
   }
 
   private void visitErrorElement(final PsiErrorElement element, HighlightInfoHolder myHolder) {
index 3edddd685ba50ef9e1b9273ff087f516b0142862..5bf13131a75111229e14e0282d048731d26f9cb7 100644 (file)
@@ -66,6 +66,7 @@ public class IndentsPass extends TextEditorHighlightingPass implements DumbAware
   };
 
   private static final CustomHighlighterRenderer RENDERER = new CustomHighlighterRenderer() {
+    @SuppressWarnings({"AssignmentToForLoopParameter"})
     public void paint(Editor editor,
                       RangeHighlighter highlighter,
                       Graphics g) {
@@ -112,6 +113,16 @@ public class IndentsPass extends TextEditorHighlightingPass implements DumbAware
       Point start = editor.visualPositionToXY(new VisualPosition(startPosition.line + 1, startPosition.column));
       final VisualPosition endPosition = editor.offsetToVisualPosition(endOffset);
       Point end = editor.visualPositionToXY(new VisualPosition(endPosition.line, endPosition.column));
+      int maxY = end.y;
+
+      Rectangle clip = g.getClipBounds();
+      if (clip != null) {
+        if (clip.y >= end.y || clip.y + clip.height <= start.y) {
+          return;
+        }
+        maxY = Math.min(maxY, clip.y + clip.height);
+      }
+
       final EditorColorsScheme scheme = editor.getColorsScheme();
       g.setColor(selected ? scheme.getColor(EditorColors.SELECTED_INDENT_GUIDE_COLOR) : scheme.getColor(EditorColors.INDENT_GUIDE_COLOR));
       
@@ -130,14 +141,14 @@ public class IndentsPass extends TextEditorHighlightingPass implements DumbAware
       //     1. Show only active indent if it crosses soft wrap-introduced text;
       //     2. Show indent as is if it doesn't intersect with soft wrap-introduced text;
       if (selected) {
-        g.drawLine(start.x + 2, start.y, start.x + 2, end.y);
+        g.drawLine(start.x + 2, start.y, start.x + 2, maxY);
       }
       else {
         int y = start.y;
         int newY = start.y;
         SoftWrapModel softWrapModel = editor.getSoftWrapModel();
         int lineHeight = editor.getLineHeight();
-        for (int i = startLine + 1; i <= endLine; i++) {
+        for (int i = startLine + 1; i < endLine && newY < maxY; i++) {
           List<? extends SoftWrap> softWraps = softWrapModel.getSoftWrapsForLine(i);
           int logicalLineHeight = softWraps.size() * lineHeight;
           if (i > startLine + 1) {
@@ -153,10 +164,15 @@ public class IndentsPass extends TextEditorHighlightingPass implements DumbAware
           else {
             newY += logicalLineHeight;
           }
+
+          FoldRegion foldRegion = foldingModel.getCollapsedRegionAtOffset(doc.getLineEndOffset(i));
+          if (foldRegion != null && foldRegion.getEndOffset() < doc.getTextLength()) {
+            i = doc.getLineNumber(foldRegion.getEndOffset());
+          }
         }
         
-        if (y < end.y) {
-          g.drawLine(start.x + 2, y, start.x + 2, end.y);
+        if (y < maxY) {
+          g.drawLine(start.x + 2, y, start.x + 2, maxY);
         }
       }
     }
index 7c94d6db3d095d3e8b1289c092c28007121bc9dd..5014b1a2dbd3c7736579e5d5ed7581c4983fac32 100644 (file)
@@ -146,16 +146,19 @@ public class PasteHandler extends EditorActionHandler {
       else {
         blockIndentAnchorColumn = col;
       }
-        
-      if (selectionModel.hasSelection()) {
-        ApplicationManager.getApplication().runWriteAction(
-          new Runnable() {
-            public void run() {
-              EditorModificationUtil.deleteSelectedText(editor);
-            }
-          }
-        );
-      }
+      
+      // We assume that EditorModificationUtil.insertStringAtCaret() is smart enough to understand that text that is currently
+      // selected at editor (if any) should be removed.
+      //
+      //if (selectionModel.hasSelection()) {
+      //  ApplicationManager.getApplication().runWriteAction(
+      //    new Runnable() {
+      //      public void run() {
+      //        EditorModificationUtil.deleteSelectedText(editor);
+      //      }
+      //    }
+      //  );
+      //}
 
       RawText rawText = RawText.fromTransferable(content);
 
index 8064fecf576079a5d9be7a584df6aa4c765e3fbd..3a805089df3a64574f9e49bbb564c003ac04a58b 100644 (file)
@@ -268,8 +268,9 @@ public class TypedHandler implements TypedActionHandler {
         PsiFile injectedFile = PsiDocumentManager.getInstance(oldFile.getProject()).getPsiFile(documentWindow);
         final Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile);
         // IDEA-52375 fix: last quote sign should be handled by outer language quote handler
+        final CharSequence charsSequence = editor.getDocument().getCharsSequence();
         if (injectedEditor.getCaretModel().getOffset() == injectedEditor.getDocument().getTextLength() &&
-            charTyped == editor.getDocument().getCharsSequence().charAt(offset)) {
+            offset < charsSequence.length() && charTyped == charsSequence.charAt(offset)) {
           return editor;
         }
         return injectedEditor;
index 82905466722e55bb3fe6b0e48d3e01d072dc95c3..e10fd362f7586883e9c7c42dc252ba19c28239de 100644 (file)
@@ -151,8 +151,11 @@ public class CommentByLineCommentHandler implements CodeInsightActionHandler {
     else {
       if (!hasSelection) {
         // Don't tweak caret position if we're already located on the last document line.
-        if (myEditor.getCaretModel().getLogicalPosition().line < myDocument.getLineCount() - 1) {
-          myEditor.getCaretModel().moveCaretRelatively(0, 1, false, false, true);
+        LogicalPosition position = myEditor.getCaretModel().getLogicalPosition();
+        if (position.line < myDocument.getLineCount() - 1) {
+          int verticalShift = 1 + myEditor.getSoftWrapModel().getSoftWrapsForLine(position.line).size() 
+                              - position.softWrapLinesOnCurrentLogicalLine;
+          myEditor.getCaretModel().moveCaretRelatively(0, verticalShift, false, false, true);
         }
       }
       else {
index eeb186d44c7f5f75297b95ed16f00fe1445640f3..5ff022fa66d40ec08ec2dac430e5a1f22ab65c73 100644 (file)
@@ -154,6 +154,8 @@ public class BraceHighlightingHandler {
     if (!myCodeInsightSettings.HIGHLIGHT_BRACES) return;
 
     if (myEditor.getSelectionModel().hasSelection()) return;
+    
+    if (myEditor.getSoftWrapModel().isInsideOrBeforeSoftWrap(myEditor.getCaretModel().getVisualPosition())) return;
 
     int offset = myEditor.getCaretModel().getOffset();
     final CharSequence chars = myEditor.getDocument().getCharsSequence();
index 080eb804003eca5fa13342cc610419cd44b329cf..069cdbfb44ac2eea0eacdc232159e95a8bd26849 100644 (file)
@@ -25,16 +25,9 @@ import java.awt.*;
 public class ColorPreviewComponent extends JComponent {
   private final Color myColor;
 
-  public ColorPreviewComponent(final String hexValue, final Color color) {
+  public ColorPreviewComponent(final Color color) {
     myColor = color;
     setOpaque(true);
-
-/*    if (hexValue != null) {
-      final JLabel label = new JLabel('#' + hexValue);
-      label.setFont(UIUtil.getToolTipFont());
-      label.setForeground(Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null)[2] >= 0.5f ? Color.BLACK : Color.WHITE);
-      add(label, BorderLayout.SOUTH);
-    } */
   }
 
   public void paintComponent(final Graphics g) {
index f6c58886b4fab4d2d34c8fcad2916a5b27d28554..095d0ab7fae2e53bd80fcc656f911d6bdddaf28a 100644 (file)
@@ -155,10 +155,10 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext {
       final PsiFile file = refElement.getContainingFile();
 
       if (file == null) return false;
-
+      final Project project = file.getProject();
       final Tools tools = myTools.get(tool.getShortName());
       for (ScopeToolState state : tools.getTools()) {
-        final NamedScope namedScope = state.getScope();
+        final NamedScope namedScope = state.getScope(project);
         if (namedScope == null || namedScope.getValue().contains(file, getCurrentProfile().getProfileManager().getScopesManager())) {
           return state.isEnabled() && ((GlobalInspectionToolWrapper)state.getTool()).getTool() == tool;
         }
@@ -358,7 +358,7 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext {
     if (true) {
       final Tools tools = myTools.get(tool.getShortName());
       for (ScopeToolState state : tools.getTools()) {
-        final NamedScope namedScope = state.getScope();
+        final NamedScope namedScope = state.getScope(element.getProject());
         if (namedScope == null || namedScope.getValue().contains(element.getContainingFile(), getCurrentProfile().getProfileManager().getScopesManager())) {
           return state.isEnabled() && state.getTool() == tool;
         }
index 8f3eb70f965ce1df5a72e6504fa5ec7ad95dccb2..a0fabee196aa2ddd9d2cb3bda1bb8f9560b222c7 100644 (file)
@@ -24,6 +24,7 @@ import com.intellij.codeHighlighting.HighlightDisplayLevel;
 import com.intellij.codeInspection.InspectionProfile;
 import com.intellij.codeInspection.InspectionProfileEntry;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.InvalidDataException;
 import com.intellij.openapi.util.WriteExternalException;
@@ -85,8 +86,9 @@ public class ToolsImpl implements Tools {
           return state.getTool();
         }
         else {
-          final DependencyValidationManager validationManager = DependencyValidationManager.getInstance(element.getProject());
-          final NamedScope scope = state.getScope();
+          final Project project = element.getProject();
+          final DependencyValidationManager validationManager = DependencyValidationManager.getInstance(project);
+          final NamedScope scope = state.getScope(project);
           if (scope != null) {
             final PackageSet packageSet = scope.getValue();
             if (packageSet != null && packageSet.contains(element.getContainingFile(), validationManager)) {
@@ -267,9 +269,10 @@ public class ToolsImpl implements Tools {
 
   public HighlightDisplayLevel getLevel(PsiElement element) {
     if (myTools == null || element == null) return myDefaultState.getLevel();
-    final DependencyValidationManager manager = DependencyValidationManager.getInstance(element.getProject());
+    final Project project = element.getProject();
+    final DependencyValidationManager manager = DependencyValidationManager.getInstance(project);
     for (ScopeToolState state : myTools) {
-      final NamedScope scope = state.getScope();
+      final NamedScope scope = state.getScope(project);
       final PackageSet set = scope != null ? scope.getValue() : null;
       if (set != null && set.contains(element.getContainingFile(), manager)) {
         return state.getLevel();
@@ -292,9 +295,10 @@ public class ToolsImpl implements Tools {
   public boolean isEnabled(PsiElement element) {
     if (!myEnabled) return false;
     if (myTools == null || element == null) return myDefaultState.isEnabled();
-    final DependencyValidationManager manager = DependencyValidationManager.getInstance(element.getProject());
+    final Project project = element.getProject();
+    final DependencyValidationManager manager = DependencyValidationManager.getInstance(project);
     for (ScopeToolState state : myTools) {
-      final NamedScope scope = state.getScope();
+      final NamedScope scope = state.getScope(project);
       if (scope != null) {
         final PackageSet set = scope.getValue();
         if (set != null && set.contains(element.getContainingFile(), manager)) {
@@ -309,9 +313,10 @@ public class ToolsImpl implements Tools {
   public InspectionTool getEnabledTool(PsiElement element) {
     if (!myEnabled) return null;
     if (myTools == null || element == null) return myDefaultState.isEnabled() ? (InspectionTool)myDefaultState.getTool() : null;
-    final DependencyValidationManager manager = DependencyValidationManager.getInstance(element.getProject());
+    final Project project = element.getProject();
+    final DependencyValidationManager manager = DependencyValidationManager.getInstance(project);
     for (ScopeToolState state : myTools) {
-      final NamedScope scope = state.getScope();
+      final NamedScope scope = state.getScope(project);
       if (scope != null) {
         final PackageSet set = scope.getValue();
         if (set != null && set.contains(element.getContainingFile(), manager)) {
@@ -354,10 +359,11 @@ public class ToolsImpl implements Tools {
       setEnabled(false);
       return;
     }
-    final DependencyValidationManager validationManager = DependencyValidationManager.getInstance(element.getProject());
+    final Project project = element.getProject();
+    final DependencyValidationManager validationManager = DependencyValidationManager.getInstance(project);
     if (myTools != null) {
       for (ScopeToolState state : myTools) {
-        final NamedScope scope = state.getScope();
+        final NamedScope scope = state.getScope(project);
         if (scope != null) {
           final PackageSet packageSet = scope.getValue();
           if (packageSet != null && packageSet.contains(element.getContainingFile(), validationManager)) {
index 2ac9b534cd71bc79cc607ac1b754ecd29e1e75d7..373e3371e0869225338fd7ca9f745391c4058d01 100644 (file)
@@ -484,7 +484,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren
       for (ScopeToolState state : currentTools.getTools()) {
         final InspectionTool tool = (InspectionTool)state.getTool();
         if (myProvider.checkReportedProblems(tool)) {
-          addTool(tool, ((InspectionProfileImpl)profile).getErrorLevel(key, state.getScope()), isGroupedBySeverity);
+          addTool(tool, ((InspectionProfileImpl)profile).getErrorLevel(key, state.getScope(myProject)), isGroupedBySeverity);
           resultsFound = true;
         }
       }
index 966830d45be2f325f64746b0b954a3b00bd4373d..825010c64b140368d92f849a00ff857c0c8f5e43 100644 (file)
@@ -569,6 +569,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
           // hence, we trim deferred text on per-token basis and don't try to remove adjacent tokens together.
           myDeferredOutput.delete(tokenInfo.startOffset - removedSymbolsNumber, tokenInfo.endOffset - removedSymbolsNumber);
           removedSymbolsNumber += tokenLength;
+          endIndex = i + 1;
         }
         else {
           // We assume here that token construction is smart enough to extend end index in case of subsequent tokens of the same type,
@@ -579,6 +580,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
           );
           tokenInfo.startOffset += remainingNumberOfSymbolsToRemove;
           removedSymbolsNumber = numberOfSymbolsToRemove;
+          endIndex = i;
         }
       }
 
@@ -586,10 +588,6 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
         continue;
       }
 
-      if (endIndex < 0) {
-        endIndex = i;
-      }
-
       tokenInfo.startOffset -= numberOfSymbolsToRemove;
       tokenInfo.endOffset -= numberOfSymbolsToRemove;
       myDeferredTypes.add(tokenInfo.contentType);
index 7b7f2513907aa0c183eadc5d8274f66fd0fe7fed..1cf2f1aeea0fcab29fbeb9ec6ee109facc9a1c37 100644 (file)
@@ -118,7 +118,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable {
     myToolwindowIdZbuffer.remove(id);
   }
 
-  private void registerToolwindow(final @NotNull Executor executor) {
+  private void registerToolwindow(@NotNull final Executor executor) {
     final String toolWindowId = executor.getToolWindowId();
     final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject);
     if (toolWindowManager == null) return; //headless environment
@@ -490,7 +490,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable {
     private Content myContent;
     private final Executor myExecutor;
 
-    private CloseListener(final @NotNull Content content, @NotNull Executor executor) {
+    private CloseListener(@NotNull final Content content, @NotNull Executor executor) {
       myContent = content;
       content.getManager().addContentManagerListener(this);
       ProjectManager.getInstance().addProjectManagerListener(this);
diff --git a/platform/lang-impl/src/com/intellij/formatting/BulkReformatListener.java b/platform/lang-impl/src/com/intellij/formatting/BulkReformatListener.java
deleted file mode 100644 (file)
index 89123d1..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.formatting;
-
-import com.intellij.ide.bookmarks.Bookmark;
-import com.intellij.ide.bookmarks.BookmarkManager;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.diff.Diff;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * There is a possible case that we understand that formatting introduces big number of changes to the underlying document.
- * That number may be big enough for that their subsequent appliance is much slower than building resulting text directly
- * and replacing the whole document text.
- * <p/>
- * Current class defines a contract for a listener interested in such situations.
- * <p/>
- * Not thread-safe.
- * 
- * @author Denis Zhdanov
- * @since 12/23/10 11:38 AM
- */
-public class BulkReformatListener {
-
-  private final List<BookmarkData> myBookmarks = new ArrayList<BookmarkData>();
-
-  private final Project     myProject;
-  private final VirtualFile myVirtualFile;
-
-  public BulkReformatListener(@NotNull Project project, VirtualFile virtualFile) {
-    myProject = project;
-    myVirtualFile = virtualFile;
-  }
-
-  /**
-   * Is expected to be called before bulk processing.
-   * 
-   * @param document    document which text is about to be reformatted at bulk mode
-   * @param newText     formatted text that is about to replace the text at the given document 
-   */
-  public void beforeProcessing(@NotNull Document document, @NotNull CharSequence newText) {
-    reset();
-
-    Diff.Change change = Diff.buildChanges(document.getCharsSequence(), newText);
-    if (change == null) {
-      return;
-    }
-    BookmarkManager manager = BookmarkManager.getInstance(myProject);
-    for (Bookmark bookmark : manager.getValidBookmarks()) {
-      if (bookmark.isValid() && bookmark.getDocument() == document) {
-        int newLine = Diff.translateLine(change, bookmark.getLine());
-        if (newLine >= 0) {
-          myBookmarks.add(new BookmarkData(bookmark.getDescription(), bookmark.getLine()));
-        }
-      }
-    }
-  }
-
-  /**
-   * Is expected to be called just after bulk reformat processing.
-   */
-  public void afterProcessing() {
-    if (myBookmarks.isEmpty()) {
-      return;
-    }
-
-    final BookmarkManager manager = BookmarkManager.getInstance(myProject);
-    for (BookmarkData bookmark : myBookmarks) {
-      manager.addTextBookmark(myVirtualFile, bookmark.line, bookmark.description);
-    }
-    
-    reset();
-  }
-  
-  private void reset() {
-    myBookmarks.clear();
-  }
-  
-  private static class BookmarkData {
-    public final String description;
-    public final int    line;
-
-    BookmarkData(String description, int line) {
-      this.description = description;
-      this.line = line;
-    }
-  }
-}
index c4f84616e28f5afcfbee9e7ee009c291a334c675..452adacfeabf4d1c2291bb167816b1db9f9b5147 100644 (file)
@@ -102,8 +102,6 @@ class FormatProcessor {
   private WhiteSpace                      myLastWhiteSpace;
   private boolean                         myDisposed;
   private CodeStyleSettings.IndentOptions myJavaIndentOptions;
-  private BulkReformatListener myBulkReformatListener;
-
 
   public FormatProcessor(final FormattingDocumentModel docModel,
                          Block rootBlock,
@@ -211,31 +209,24 @@ class FormatProcessor {
     myJavaIndentOptions = javaIndentOptions;
   }
 
-  /**
-   * @param bulkReformatListener    new listener to use; <code>null</code> to reset any listener registered before
-   */
-  public void setBulkReformatListener(@Nullable BulkReformatListener bulkReformatListener) {
-    myBulkReformatListener = bulkReformatListener;
-  }
-
-  private void doModify(final List<LeafBlockWrapper> blocksToModify, final FormattingModel model,
+  private static void doModify(final List<LeafBlockWrapper> blocksToModify, final FormattingModel model,
                                CodeStyleSettings.IndentOptions indentOption, CodeStyleSettings.IndentOptions javaOptions) {
     final int blocksToModifyCount = blocksToModify.size();
     DocumentEx updatedDocument = null;
 
     try {
-      if (blocksToModifyCount > BULK_REPLACE_OPTIMIZATION_CRITERIA) {
-        if (applyChangesAtBulkMode(blocksToModify, model, indentOption)) {
-          return;
-        }
-      }
-
       final boolean bulkReformat = blocksToModifyCount > 50;
       updatedDocument = bulkReformat ? getAffectedDocument(model) : null;
       if (updatedDocument != null) {
         updatedDocument.setInBulkUpdate(true);
       }
       
+      if (blocksToModifyCount > BULK_REPLACE_OPTIMIZATION_CRITERIA) {
+        if (applyChangesAtBulkMode(blocksToModify, model, indentOption)) {
+          return;
+        }
+      }
+      
       int shift = 0;
       for (int i = 0; i < blocksToModifyCount; ++i) {
         final LeafBlockWrapper block = blocksToModify.get(i);
@@ -264,10 +255,9 @@ class FormatProcessor {
    * @param indentOption          indent options to use
    * @return                      <code>true</code> if given changes are applied to the document (i.e. no further processing is required);
    *                              <code>false</code> otherwise
-   * @see BulkReformatListener
    */
-  private boolean applyChangesAtBulkMode(final List<LeafBlockWrapper> blocksToModify, final FormattingModel model,
-                                             CodeStyleSettings.IndentOptions indentOption) 
+  private static boolean applyChangesAtBulkMode(final List<LeafBlockWrapper> blocksToModify, final FormattingModel model,
+                                                CodeStyleSettings.IndentOptions indentOption) 
   {
     FormattingDocumentModel documentModel = model.getDocumentModel();
     Document document = documentModel.getDocument();
@@ -284,14 +274,8 @@ class FormatProcessor {
       changes.add(new TextChangeImpl(newWs, whiteSpace.getStartOffset(), whiteSpace.getEndOffset()));
     }
     CharSequence mergeResult = ourBulkChangesMerger.merge(document.getChars(), document.getTextLength(), changes);
-    if (myBulkReformatListener != null) {
-      myBulkReformatListener.beforeProcessing(document, mergeResult);
-    }
     document.replaceString(0, document.getTextLength(), mergeResult);
     cleanupBlocks(blocksToModify);
-    if (myBulkReformatListener != null) {
-      myBulkReformatListener.afterProcessing();
-    }
     return true;
   }
 
@@ -887,8 +871,7 @@ class FormatProcessor {
     if (myWrapCandidate == myCurrentBlock) return wraps.get(0);
 
     final int wrapsCount = wraps.size();
-    for (int i = 0; i < wrapsCount; ++i) {
-      final WrapImpl wrap = wraps.get(i);
+    for (final WrapImpl wrap : wraps) {
       if (!isSuitableInTheCurrentPosition(wrap)) continue;
       if (wrap.isIsActive()) return wrap;
 
index d464f329c78469381884316c828b46aecfd357a5..57d279aa0fb6e21b5e2e7b4b3f649cc12a8defa7 100644 (file)
@@ -19,12 +19,9 @@ package com.intellij.formatting;
 import com.intellij.openapi.components.ApplicationComponent;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.codeStyle.CodeStyleSettings;
-import com.intellij.psi.formatter.DocumentBasedFormattingModel;
 import com.intellij.psi.formatter.FormattingDocumentModelImpl;
 import com.intellij.psi.formatter.PsiBasedFormattingModel;
 import com.intellij.util.IncorrectOperationException;
@@ -136,7 +133,6 @@ public class FormatterImpl extends FormatterEx
     try {
       FormatProcessor processor =
         new FormatProcessor(model.getDocumentModel(), model.getRootBlock(), settings, indentOptions, affectedRanges);
-      setupFormatProcessorIfPossible(processor, model);
       processor.format(model);
     } finally {
       enableFormatting();
@@ -144,30 +140,6 @@ public class FormatterImpl extends FormatterEx
 
   }
 
-  private static void setupFormatProcessorIfPossible(@NotNull FormatProcessor processor, @NotNull FormattingModel model) {
-    if (!(model instanceof DocumentBasedFormattingModel)) {
-      return;
-    }
-
-    DocumentBasedFormattingModel formattingModel = (DocumentBasedFormattingModel)model;
-    Project project = formattingModel.getProject();
-    if (project == null) {
-      return;
-    }
-
-    PsiFile file = formattingModel.getFile();
-    if (file == null) {
-      return;
-    }
-
-    VirtualFile virtualFile = file.getVirtualFile();
-    if (virtualFile == null) {
-      return;
-    }
-    
-    processor.setBulkReformatListener(new BulkReformatListener(project, virtualFile));
-  }
-  
   public void formatWithoutModifications(FormattingDocumentModel model,
                                          Block rootBlock,
                                          CodeStyleSettings settings,
index 5cc457108db306290856c377e533964fd50d5a2d..6192af71b0cac305a9dcce839cdb05a2b6a0e6a7 100644 (file)
@@ -60,8 +60,12 @@ public class IndentInfo {
       if (options.SMART_TABS) {
         int tabCount = myIndentSpaces / options.TAB_SIZE;
         int leftSpaces = myIndentSpaces - tabCount * options.TAB_SIZE;
-        StringUtil.repeatSymbol(buffer, '\t', tabCount);
-        StringUtil.repeatSymbol(buffer, ' ', leftSpaces + mySpaces);
+        if (tabCount > 0) {
+          StringUtil.repeatSymbol(buffer, '\t', tabCount);
+        }
+        if (leftSpaces + mySpaces > 0) {
+          StringUtil.repeatSymbol(buffer, ' ', leftSpaces + mySpaces);
+        }
       }
       else {
         int size = getTotalSpaces();
index 0ff123f0b562e1402703f9c9a3eb4a5a3b351556..6166d7d7b20199eddcbc35e12f97aa6756b48c7b 100644 (file)
@@ -24,6 +24,7 @@ import com.intellij.lang.LanguageStructureViewBuilder;
 import com.intellij.navigation.ItemPresentation;
 import com.intellij.navigation.NavigationItem;
 import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.RangeMarker;
 import com.intellij.openapi.editor.ex.MarkupModelEx;
 import com.intellij.openapi.editor.markup.GutterIconRenderer;
 import com.intellij.openapi.editor.markup.HighlighterLayer;
@@ -82,7 +83,7 @@ public class Bookmark {
       myHighlighter = null;
     }
 
-    myTarget = new OpenFileDescriptor(project, file, line, -1);
+    myTarget = new OpenFileDescriptor(project, file, line, -1, true);
   }
 
   public Document getDocument() {
@@ -128,8 +129,19 @@ public class Bookmark {
     return myDescription == null || myDescription.trim().length() == 0;
   }
 
+  OpenFileDescriptor getTarget() {
+    return myTarget;
+  }
+
   public boolean isValid() {
-    return getFile().isValid() && (myHighlighter == null || myHighlighter.isValid());
+    if (!getFile().isValid() || (myHighlighter != null && !myHighlighter.isValid())) {
+      return false;
+    }
+
+    // There is a possible case that target document line that is referenced by the current bookmark is removed. We assume
+    // that corresponding range marker becomes invalid then.
+    RangeMarker rangeMarker = myTarget.getRangeMarker();
+    return rangeMarker == null || rangeMarker.isValid();
   }
 
   public void navigate() {
index b0497f856bbaf80a3afbd55b2e95124fb06b9f94..cb23ca337c0a4ff2dad984b686b5390a6f64de8a 100644 (file)
@@ -23,10 +23,7 @@ import com.intellij.openapi.components.Storage;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.EditorFactory;
-import com.intellij.openapi.editor.event.EditorMouseAdapter;
-import com.intellij.openapi.editor.event.EditorMouseEvent;
-import com.intellij.openapi.editor.event.EditorMouseEventArea;
-import com.intellij.openapi.editor.ex.EditorEventMulticasterEx;
+import com.intellij.openapi.editor.event.*;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.vfs.VirtualFileManager;
@@ -48,10 +45,13 @@ import java.util.List;
   }
 )
 public class BookmarkManager implements PersistentStateComponent<Element> {
+  
   private static final int MAX_AUTO_DESCRIPTION_SIZE = 50;
-  private final List<Bookmark> myBookmarks = new ArrayList<Bookmark>();
+
+  private final List<Bookmark>        myBookmarks           = new ArrayList<Bookmark>();
   private final MyEditorMouseListener myEditorMouseListener = new MyEditorMouseListener();
-  private final Project myProject;
+
+  private final Project    myProject;
   private final MessageBus myBus;
 
   public static BookmarkManager getInstance(Project project) {
@@ -61,11 +61,11 @@ public class BookmarkManager implements PersistentStateComponent<Element> {
   public BookmarkManager(Project project, MessageBus bus) {
     myProject = project;
     myBus = bus;
+    EditorFactory.getInstance().getEventMulticaster().addDocumentListener(new MyDocumentListener(), myProject);
   }
 
   public void projectOpened() {
-    EditorEventMulticasterEx eventMulticaster = (EditorEventMulticasterEx)EditorFactory.getInstance()
-      .getEventMulticaster();
+    EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster();
     eventMulticaster.addEditorMouseListener(myEditorMouseListener, myProject);
   }
 
@@ -356,5 +356,26 @@ public class BookmarkManager implements PersistentStateComponent<Element> {
       e.consume();
     }
   }
+  
+  private class MyDocumentListener extends DocumentAdapter {
+    @Override
+    public void documentChanged(DocumentEvent e) {
+      List<Bookmark> bookmarksToRemove = null;
+      for (Bookmark bookmark : myBookmarks) {
+        if (!bookmark.isValid()) {
+          if (bookmarksToRemove == null) {
+            bookmarksToRemove = new ArrayList<Bookmark>();
+          }
+          bookmarksToRemove.add(bookmark);
+        }
+      }
+      
+      if (bookmarksToRemove != null) {
+        for (Bookmark bookmark : bookmarksToRemove) {
+          removeBookmark(bookmark);
+        }
+      }
+    }
+  }
 }
 
index 8b1a5966c91dc6eeec45223cc5341e5cfc557e29..fea238bb3e31aede30434c6ba3650dc7e9a155d7 100644 (file)
 package com.intellij.ide.scriptingContext;
 
 import com.intellij.lang.LanguagePerFileMappings;
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTable;
 import com.intellij.openapi.roots.libraries.LibraryType;
 import com.intellij.openapi.roots.libraries.scripting.ScriptingLibraryManager;
 import com.intellij.openapi.roots.libraries.scripting.ScriptingLibraryTable;
+import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.vfs.VirtualFile;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -29,7 +33,8 @@ import java.util.*;
 /**
  * @author Rustam Vishnyakov
  */
-public class ScriptingLibraryMappings extends LanguagePerFileMappings<ScriptingLibraryTable.LibraryModel> {
+public class ScriptingLibraryMappings extends LanguagePerFileMappings<ScriptingLibraryTable.LibraryModel> implements LibraryTable.Listener,
+                                                                                                                     Disposable {
 
   private final ScriptingLibraryManager myLibraryManager;
   private final Map<VirtualFile, CompoundLibrary> myCompoundLibMap = new HashMap<VirtualFile, CompoundLibrary>();
@@ -38,6 +43,11 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings<ScriptingL
   public ScriptingLibraryMappings(final Project project, final LibraryType libraryType) {
     super(project);
     myLibraryManager = new ScriptingLibraryManager(project, libraryType);
+    if (myLibraryManager.ensureModel()) {
+      LibraryTable libTable = myLibraryManager.getLibraryTable();
+      if (libTable != null) libTable.addListener(this, this);
+    }
+    Disposer.register(project, this);
   }
 
   protected String serialize(final ScriptingLibraryTable.LibraryModel library) {
@@ -50,6 +60,22 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings<ScriptingL
   public void reset() {
     myLibraryManager.reset();
   }
+  
+  private void updateMappings() {
+    myLibraryManager.reset();
+    Map<VirtualFile,ScriptingLibraryTable.LibraryModel> map = getMappings();
+    for (ScriptingLibraryTable.LibraryModel value : map.values()) {
+      if (value instanceof CompoundLibrary) {
+        CompoundLibrary container = (CompoundLibrary) value;
+        for (ScriptingLibraryTable.LibraryModel libraryModel : container.getLibraries()) {
+          String libName = libraryModel.getName(); 
+          if (myLibraryManager.getLibraryByName(libName) == null) {
+            container.removeLibrary(libName); 
+          }
+        }
+      }
+    }
+  }
 
   /**
    * Creates an association between a virtual file and a library specified by name.
@@ -164,6 +190,29 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings<ScriptingL
     return libraryModels;
   }
 
+  @Override
+  public void afterLibraryAdded(Library newLibrary) {
+    updateMappings();
+  }
+
+  @Override
+  public void afterLibraryRenamed(Library library) {
+    updateMappings();
+  }
+
+  @Override
+  public void beforeLibraryRemoved(Library library) {
+  }
+
+  @Override
+  public void afterLibraryRemoved(Library library) {
+    updateMappings();
+  }
+
+  @Override
+  public void dispose() {
+  }
+
   public static class CompoundLibrary extends  ScriptingLibraryTable.LibraryModel {
     private final Map<String, ScriptingLibraryTable.LibraryModel> myLibraries = new TreeMap<String, ScriptingLibraryTable.LibraryModel>();
 
@@ -183,6 +232,10 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings<ScriptingL
       }
       myLibraries.put(libName, library);
     }
+    
+    private void removeLibrary(@NotNull String libName) {
+      myLibraries.remove(libName);
+    }
 
     public boolean containsLibrary(String libName) {
       return myLibraries.containsKey(libName);
@@ -207,6 +260,10 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings<ScriptingL
       }
       return false;
     }
+    
+    public Collection<ScriptingLibraryTable.LibraryModel> getLibraries() {
+      return myLibraries.values();
+    }
 
     @Override
     public boolean isEmpty() {
index 9c227b364a814a8fedf8f8ffe2e5ee3829e18b03..62e0551ce653a5a003f58aabb161ff630bb9c13b 100644 (file)
@@ -19,10 +19,10 @@ package com.intellij.injected.editor;
 import com.intellij.openapi.editor.CaretModel;
 import com.intellij.openapi.editor.LogicalPosition;
 import com.intellij.openapi.editor.VisualPosition;
-import com.intellij.openapi.editor.markup.TextAttributes;
 import com.intellij.openapi.editor.event.CaretEvent;
 import com.intellij.openapi.editor.event.CaretListener;
 import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.editor.markup.TextAttributes;
 import org.jetbrains.annotations.NotNull;
 
 /**
@@ -82,6 +82,11 @@ public class CaretModelWindow implements CaretModel {
     return myEditorWindow.getDocument().hostToInjected(myDelegate.getOffset());
   }
 
+  @Override
+  public boolean isUpToDate() {
+    return myDelegate.isUpToDate();
+  }
+
   private final ListenerWrapperMap<CaretListener> myCaretListeners = new ListenerWrapperMap<CaretListener>();
   public void addCaretListener(@NotNull final CaretListener listener) {
     CaretListener wrapper = new CaretListener() {
index d094df6e76481b206247beaa0569ccc0d4e38d4d..78fcf1afec8f99f9b455c0e9255bc3915ff2558e 100644 (file)
@@ -86,7 +86,13 @@ public class SelectionModelWindow implements SelectionModel {
   }
 
   @Override
-  public void setSelection(@NotNull VisualPosition startPosition, int startOffset, @NotNull VisualPosition endPosition, int endOffset) {
+  public void setSelection(int startOffset, @Nullable VisualPosition endPosition, int endOffset) {
+    TextRange hostRange = myDocument.injectedToHost(new ProperTextRange(startOffset, endOffset));
+    myHostModel.setSelection(hostRange.getStartOffset(), endPosition, hostRange.getEndOffset());
+  }
+
+  @Override
+  public void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset) {
     TextRange hostRange = myDocument.injectedToHost(new ProperTextRange(startOffset, endOffset));
     myHostModel.setSelection(startPosition, hostRange.getStartOffset(), endPosition, hostRange.getEndOffset());
   }
index 4d96b2fbfd7d7de666ef4224d9b8ef74bb5c818e..992622e79adefe709f4541f90e1ed5541951747d 100644 (file)
@@ -44,7 +44,7 @@ abstract class OrderEnumeratorBase extends OrderEnumerator {
   private boolean myWithoutJdk;
   private boolean myWithoutLibraries;
   protected boolean myWithoutDepModules;
-  private boolean myWithoutRootModuleContent;
+  private boolean myWithoutModuleSourceEntries;
   protected boolean myRecursively;
   protected boolean myRecursivelyExportedOnly;
   private boolean myExportedOnly;
@@ -105,7 +105,7 @@ abstract class OrderEnumeratorBase extends OrderEnumerator {
 
   @Override
   public OrderEnumerator withoutModuleSourceEntries() {
-    myWithoutRootModuleContent = true;
+    myWithoutModuleSourceEntries = true;
     return this;
   }
 
@@ -186,7 +186,7 @@ abstract class OrderEnumeratorBase extends OrderEnumerator {
     flags <<= 1;
     if (myWithoutDepModules) flags |= 1;
     flags <<= 1;
-    if (myWithoutRootModuleContent) flags |= 1;
+    if (myWithoutModuleSourceEntries) flags |= 1;
     flags <<= 1;
     if (myRecursively) flags |= 1;
     flags <<= 1;
@@ -208,9 +208,7 @@ abstract class OrderEnumeratorBase extends OrderEnumerator {
         if (!myRecursively && entry instanceof ModuleOrderEntry) continue;
         if (entry instanceof ModuleSourceOrderEntry && !isRootModuleModel(((ModuleSourceOrderEntry)entry).getRootModel())) continue;
       }
-      if (myWithoutRootModuleContent
-          && entry instanceof ModuleSourceOrderEntry
-          && isRootModuleModel(((ModuleSourceOrderEntry)entry).getRootModel())) {
+      if (myWithoutModuleSourceEntries && entry instanceof ModuleSourceOrderEntry) {
         continue;
       }
 
index ccbf7926ae837d16ec68e6bba6e2083cc1e93d7f..e8e6aff1477cbd6ab03c3030febbebbcfd60310a 100644 (file)
@@ -106,7 +106,7 @@ public abstract class AddScopeAction extends AnAction {
     final List<ScopeToolState> nonDefaultTools = getSelectedProfile().getNonDefaultTools(descriptor.getKey().toString());
     if (nonDefaultTools != null) {
       for (ScopeToolState state : nonDefaultTools) {
-        used.add(state.getScope());
+        used.add(state.getScope(project));
       }
     }
     scopes.removeAll(used);
index fe56c7d34a603dbcf98c14a878e08f9bcdf9949c..792c763c64aa51369a48c6f30b46cabe38630a5e 100644 (file)
@@ -590,6 +590,13 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
       commitNecessary = true;
     }
 
+    // Consider that it's worth to perform complete re-parse instead of merge if the whole document text is replaced and
+    // current document lines number is roughly above 5000. This makes sense in situations when external change is performed
+    // for the huge file (that causes the whole document to be reloaded and 'merge' way takes a while to complete).
+    if (event.isWholeTextReplaced() && document.getTextLength() > 500000) {
+      document.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, Boolean.TRUE);
+    }
+    
     if (commitNecessary && ApplicationManager.getApplication().getCurrentWriteAction(ExternalChangeAction.class) != null){
       commitDocument(document);
     }
index 335006d01d7e63a9ba7c9a4f754c541f06be6707..46157ff3f955555754a0cf2d238a3e2470345cb3 100644 (file)
@@ -34,6 +34,7 @@ import com.intellij.openapi.fileEditor.FileEditorManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiUtilBase;
@@ -293,7 +294,8 @@ public class ChangeSignatureGestureDetector extends PsiTreeChangeAdapter impleme
             if (element != null) {
               final ChangeInfo info = LanguageChangeSignatureDetectors.createCurrentChangeInfo(element, myCurrentInfo);
               if (info != null) {
-                myInitialText = document.getText();
+                final TextRange textRange = info.getMethod().getTextRange();
+                myInitialText =  document.getText().substring(textRange.getStartOffset(), textRange.getEndOffset()) ;
                 myInitialChangeInfo = info;
               }
             }
index 6639872e6a031406b67ab3eba96f85a959b7940a..88a7cc96aae2e1f8da723c46026fee9d7bada1a9 100644 (file)
@@ -67,7 +67,7 @@ public abstract class RenameChangeInfo implements ChangeInfo {
 
   @Override
   public PsiElement getMethod() {
-    return null;
+    return getNamedElement();
   }
 
   @Override
index 20a4ba061dccc70779b65cd62a8e6ac70d589af3..e42df3e4d008f9d392112c181652631e5d6c4bb2 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.openapi.progress.EmptyProgressIndicator;
 import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.progress.ProgressManager;
+import org.jetbrains.annotations.NotNull;
 
 /**
  * @author Eugene Zhuravlev
@@ -97,6 +98,7 @@ public class DelegatingProgressIndicator implements ProgressIndicator {
     return getDelegate().isModal();
   }
 
+  @NotNull
   public ModalityState getModalityState() {
     return getDelegate().getModalityState();
   }
index f6d09623546e8e73d3ff212f9cd4aa7448e115c5..fcd265bd616af7c9224307a37964f1c3c634bc30 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.mock;
 
 import com.intellij.openapi.application.ModalityState;
 import com.intellij.openapi.progress.ProgressIndicator;
+import org.jetbrains.annotations.NotNull;
 
 public class MockProgressIndicator implements ProgressIndicator {
   private boolean myIsRunning = false;
@@ -80,6 +81,7 @@ public class MockProgressIndicator implements ProgressIndicator {
     return false;
   }
 
+  @NotNull
   public ModalityState getModalityState() {
     return ModalityState.NON_MODAL;
   }
@@ -96,4 +98,4 @@ public class MockProgressIndicator implements ProgressIndicator {
 
   public void checkCanceled() {
   }
-}
\ No newline at end of file
+}
index da64669c37498d82da448ed4eae959bf67c1c721..3eed0bf0ea52eed14dca16f482e8b9c93ee5029c 100644 (file)
@@ -208,6 +208,7 @@ public interface Application extends ComponentManager {
    *
    * @return the current modality state.
    */
+  @NotNull
   ModalityState getCurrentModalityState();
 
   /**
@@ -216,6 +217,7 @@ public interface Application extends ComponentManager {
    * @param c the component for which the modality state is requested.
    * @return the modality state.
    */
+  @NotNull
   ModalityState getModalityStateForComponent(@NotNull Component c);
 
   /**
@@ -224,6 +226,7 @@ public interface Application extends ComponentManager {
    *
    * @return the modality state for the current thread.
    */
+  @NotNull
   ModalityState getDefaultModalityState();
 
   /**
@@ -232,6 +235,7 @@ public interface Application extends ComponentManager {
    *
    * @return the modality state for no modal dialogs.
    */
+  @NotNull
   ModalityState getNoneModalityState();
 
   /**
index 37ff7f91187c54f3ce53e1b8199986b8bbeaf474..8b3bd0cb50d8a5d874db37d88e84f6381b68994d 100644 (file)
@@ -45,17 +45,20 @@ public abstract class ModalityState {
     }
   }
 
+  @NotNull
   public static ModalityState current() {
     return ApplicationManager.getApplication().getCurrentModalityState();
   }
 
+  @NotNull
   public static ModalityState stateForComponent(Component component){
     return ApplicationManager.getApplication().getModalityStateForComponent(component);
   }
 
+  @NotNull
   public static ModalityState defaultModalityState() {
     return ApplicationManager.getApplication().getDefaultModalityState();
   }
 
-  public abstract boolean dominates(ModalityState anotherState);
+  public abstract boolean dominates(@NotNull ModalityState anotherState);
 }
index b74b38223ad65f2421cfd5a7552cdd876bd3845a..e49f35131b4bce19bad5215e1e742160a9fbd440 100644 (file)
@@ -73,6 +73,17 @@ public interface CaretModel {
    */
   void moveToOffset(int offset, boolean locateBeforeSoftWrap);
 
+  /**
+   * Caret position may be updated on document change (e.g. consider that user updates from VCS that causes addition of text
+   * before caret. Caret offset, visual and logical positions should be updated then). So, there is a possible case
+   * that caret model in in the process of caret position update now.
+   * <p/>
+   * Current method allows to check that.
+   *
+   * @return    <code>true</code> if caret position is up-to-date for now; <code>false</code> otherwise
+   */
+  boolean isUpToDate();
+  
   /**
    * Returns the logical position of the caret.
    *
index e90962dff7d591a32000b9fcf8bccc1beb01d474..11968f74288a9fc735ef76286fbf12cd4cf4dc8f 100644 (file)
@@ -69,12 +69,12 @@ public class LazyRangeMarkerFactory extends AbstractProjectComponent {
     return marker;
   }
 
-  public RangeMarker createRangeMarker(VirtualFile file, int line, int column) {
+  public RangeMarker createRangeMarker(VirtualFile file, int line, int column, boolean persistent) {
     FileDocumentManager fdm = FileDocumentManager.getInstance();
     final Document document = fdm.getCachedDocument(file);
     if (document != null) {
       final int offset = calculateOffset(myProject, file, document, line, column);
-      return document.createRangeMarker(offset, offset);
+      return document.createRangeMarker(offset, offset, persistent);
     }
 
     final LazyMarker marker = new LineColumnLazyMarker(file, line, column);
index 0edb6440b2452dba6eac798df60377d5c28bdae5..b56dde27edd293d84f1a0ab370b9a50e2858c1ce 100644 (file)
@@ -101,17 +101,31 @@ public interface SelectionModel {
    */
   void setSelection(int startOffset, int endOffset);
 
+  /**
+   * Selects target range providing information about visual boundary of selection end.
+   * <p/>
+   * That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
+   * 
+   * @param startOffset     start selection offset
+   * @param endPosition     end visual position of the text range to select (<code>null</code> argument means that
+   *                        no specific visual position should be used)
+   * @param endOffset       end selection offset
+   */
+  void setSelection(int startOffset, @Nullable VisualPosition endPosition, int endOffset);
+  
   /**
    * Selects target range based on its visual boundaries.
    * <p/>
    * That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
    * 
-   * @param startPosition   start visual position of the text range to select
-   * @param endPosition     end visual position of the text range to select
+   * @param startPosition   start visual position of the text range to select (<code>null</code> argument means that
+   *                        no specific visual position should be used)
+   * @param endPosition     end visual position of the text range to select (<code>null</code> argument means that
+   *                        no specific visual position should be used)
    * @param startOffset     start selection offset
    * @param endOffset       end selection offset
    */
-  void setSelection(@NotNull VisualPosition startPosition, int startOffset, @NotNull VisualPosition endPosition, int endOffset);
+  void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset);
   
   /**
    * Removes the selection in the editor.
index 48ee679e45d69f3271d70e4a301044d68ce840be..181072e30c890378def87c426f5bed1916cef592 100644 (file)
@@ -36,5 +36,8 @@ public abstract class DocumentEvent extends EventObject {
   public abstract CharSequence getNewFragment();
 
   public abstract long getOldTimeStamp();
-
+  
+  public boolean isWholeTextReplaced() {
+    return getOffset() == 0 && getNewLength() == getDocument().getTextLength();
+  }
 }
index f880dc1f42ede6174126b239a0844f5da2019082..23ac76ea5acf3f2d3a37b66dd569777c62a4c7ae 100644 (file)
@@ -41,27 +41,31 @@ public class OpenFileDescriptor implements Navigatable {
    */
   public static final DataKey<Editor> NAVIGATE_IN_EDITOR = DataKey.create("NAVIGATE_IN_EDITOR");
 
-  @NotNull private final VirtualFile myFile;
-  private final int myOffset;
-  private final int myLine;
-  private final int myColumn;
+  @NotNull
+  private final VirtualFile myFile;
+  private final int         myOffset;
+  private final int         myLine;
+  private final int         myColumn;
   private final RangeMarker myRangeMarker;
-
-  private final Project myProject;
+  private final Project     myProject;
 
   public OpenFileDescriptor(Project project, @NotNull VirtualFile file, int offset) {
-    this(project, file, -1, -1, offset);
+    this(project, file, -1, -1, offset, false);
   }
 
   public OpenFileDescriptor(Project project, @NotNull VirtualFile file, int line, int col) {
-    this(project, file, line, col, -1);
+    this(project, file, line, col, -1, false);
+  }
+
+  public OpenFileDescriptor(Project project, @NotNull VirtualFile file, int line, int col, boolean persistent) {
+    this(project, file, line, col, -1, persistent);
   }
 
   public OpenFileDescriptor(Project project, @NotNull VirtualFile file) {
-    this(project, file, -1, -1, -1);
+    this(project, file, -1, -1, -1, false);
   }
 
-  private OpenFileDescriptor(final Project project, @NotNull final VirtualFile file, int line, int col, int offset) {
+  private OpenFileDescriptor(final Project project, @NotNull final VirtualFile file, int line, int col, int offset, boolean persistent) {
     myProject = project;
 
     myFile = file;
@@ -72,7 +76,7 @@ public class OpenFileDescriptor implements Navigatable {
       myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, offset);
     }
     else if (line >= 0 ){
-      myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, line, Math.max(0, col));
+      myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, line, Math.max(0, col), persistent);
     }
     else {
       myRangeMarker = null;
@@ -84,11 +88,15 @@ public class OpenFileDescriptor implements Navigatable {
     return myFile;
   }
 
+  @Nullable
+  public RangeMarker getRangeMarker() {
+    return myRangeMarker;
+  }
+
   public int getOffset() {
     return myRangeMarker != null && myRangeMarker.isValid() ? myRangeMarker.getStartOffset() : myOffset;
   }
 
-
   public int getLine() {
     return myLine;
   }
index 4d10437480ac55577569f84c2a44401384adc70f..f8b4a114856c0db0acec485be1b3d39099912c1b 100644 (file)
@@ -17,6 +17,7 @@
 package com.intellij.openapi.progress;
 
 import com.intellij.openapi.application.ModalityState;
+import org.jetbrains.annotations.NotNull;
 
 public class EmptyProgressIndicator implements ProgressIndicator {
   private boolean myIsRunning = false;
@@ -80,6 +81,7 @@ public class EmptyProgressIndicator implements ProgressIndicator {
     return false;
   }
 
+  @NotNull
   public ModalityState getModalityState() {
     return ModalityState.NON_MODAL;
   }
index a0efe9bad7c8407acf9aabefc7be68f3c44fa154..65b64a33ff71c5d899cd3e8a990e6fec9962dfec 100644 (file)
@@ -16,6 +16,7 @@
 package com.intellij.openapi.progress;
 
 import com.intellij.openapi.application.ModalityState;
+import org.jetbrains.annotations.NotNull;
 
 public interface ProgressIndicator {
   void start();
@@ -60,6 +61,7 @@ public interface ProgressIndicator {
 
   boolean isModal();
 
+  @NotNull
   ModalityState getModalityState();
 
   void setModalityProgress(ProgressIndicator modalityProgress);
@@ -69,4 +71,4 @@ public interface ProgressIndicator {
   void setIndeterminate(boolean indeterminate);
 
   void checkCanceled() throws ProcessCanceledException;
-}
\ No newline at end of file
+}
index d901bf9cfc841b6b077b6fc008d1af6718aec5c3..e2228f82c98bb8cc20fff9115a9fc8caab475501 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.intellij.openapi.project;
 
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.util.InvalidDataException;
 import org.jdom.JDOMException;
@@ -41,14 +42,15 @@ public abstract class ProjectManager {
    *
    * @param listener listener to add
    */
-  public abstract void addProjectManagerListener(ProjectManagerListener listener);
+  public abstract void addProjectManagerListener(@NotNull ProjectManagerListener listener);
+  public abstract void addProjectManagerListener(@NotNull ProjectManagerListener listener, @NotNull Disposable parentDisposable);
 
   /**
    * Removes global listener from all projects.
    *
    * @param listener listener to remove
    */
-  public abstract void removeProjectManagerListener(ProjectManagerListener listener);
+  public abstract void removeProjectManagerListener(@NotNull ProjectManagerListener listener);
 
   /**
    * Adds listener to the specified project.
@@ -56,7 +58,7 @@ public abstract class ProjectManager {
    * @param project  project to add listener to
    * @param listener listener to add
    */
-  public abstract void addProjectManagerListener(Project project, ProjectManagerListener listener);
+  public abstract void addProjectManagerListener(@NotNull Project project, @NotNull ProjectManagerListener listener);
 
   /**
    * Removes listener from the specified project.
@@ -64,7 +66,7 @@ public abstract class ProjectManager {
    * @param project  project to remove listener from
    * @param listener listener to remove
    */
-  public abstract void removeProjectManagerListener(Project project, ProjectManagerListener listener);
+  public abstract void removeProjectManagerListener(@NotNull Project project, @NotNull ProjectManagerListener listener);
 
   /**
    * Returns the list of currently opened projects.
@@ -96,7 +98,7 @@ public abstract class ProjectManager {
    * @throws InvalidDataException if the project file contained invalid data
    */
   @Nullable
-  public abstract Project loadAndOpenProject(String filePath) throws IOException, JDOMException, InvalidDataException;
+  public abstract Project loadAndOpenProject(@NotNull String filePath) throws IOException, JDOMException, InvalidDataException;
 
   /**
    * Closes the specified project.
@@ -104,12 +106,12 @@ public abstract class ProjectManager {
    * @param project the project to close.
    * @return true if the project was closed successfully, false if the closing was disallowed by the close listeners.
    */
-  public abstract boolean closeProject(Project project);
+  public abstract boolean closeProject(@NotNull Project project);
 
   /**
    * Asynchronously reloads the specified project.
    *
    * @param project the project to reload.
    */
-  public abstract void reloadProject(Project project);
+  public abstract void reloadProject(@NotNull Project project);
 }
index d22d297ec37c9903be7b2ee3dc51386e806d5870..1a9a6810b74e6071cf87f70643743c8a7f6fd3f1 100644 (file)
@@ -25,6 +25,8 @@ import com.intellij.openapi.help.HelpManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.popup.StackingPopupDispatcher;
 import com.intellij.openapi.util.*;
+import com.intellij.openapi.wm.IdeGlassPaneUtil;
+import com.intellij.openapi.wm.impl.content.GraphicsConfig;
 import com.intellij.ui.IdeBorderFactory;
 import com.intellij.ui.UIBundle;
 import com.intellij.util.Alarm;
@@ -33,6 +35,7 @@ import com.intellij.util.ui.AwtVisitor;
 import com.intellij.util.ui.DialogUtil;
 import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
@@ -121,111 +124,6 @@ public abstract class DialogWrapper {
     }
   };
 
-  //validation
-  private Alarm myValidationAlarm = new Alarm();
-  private int myValidationDelay = 300;
-  //private Dimension myLastPeerSize = null;
-  private String OLD_BORDER = "OLD_BORDER";
-  private JComponent myLastErrorComponent = null;
-  private boolean myDisposed = false;
-  private Boolean myLastPaintButtonBorder = null;
-  private boolean myValidationStarted = false;
-
-  /**
-   * Allows to postpone first start of validation
-   *
-   * @return <code>false</code> if start validation in <code>init()</code> method
-   */
-  protected boolean postponeValidation() {
-    return false;
-  }
-
-  /**
-   * Validates a user input and returns <code>null</code> if everything is fine
-   * or returns a problem description with component where is the problem has been found.
-   *
-   * @return <code>null</code> if everything is OK or a problem descriptor
-   */
-  @Nullable
-  protected ValidationInfo doValidate() {
-    return null;
-  }
-
-  /**
-   * Controls components highlighting
-   *
-   * @return <code>true</code> for problem components highlighting. <code>false</code> otherwise.
-   */
-  protected boolean isShowErrorBorder() {
-    return true;
-  }
-
-  /**
-   * Specifies border color for error highlighting
-   *
-   * @return color for error highlighting
-   */
-  protected Color getErrorColor() {
-    return Color.RED;
-  }
-
-  private void reportProblem(final String message, final JComponent comp) {
-    SwingUtilities.invokeLater(new Runnable() {
-      public void run() {
-        //if (myLastPeerSize == null) {
-        //  myLastPeerSize = myPeer.getSize();
-        //}
-        if (isShowErrorBorder()) {
-          if (myLastErrorComponent != comp) {
-            if (myLastErrorComponent != null) {
-              myLastErrorComponent.setBorder((Border)myLastErrorComponent.getClientProperty(OLD_BORDER));
-              if (myLastErrorComponent instanceof AbstractButton && myLastPaintButtonBorder != null) {
-                ((AbstractButton)myLastErrorComponent).setBorderPainted(myLastPaintButtonBorder);
-              }
-            }
-            myLastErrorComponent = comp;
-            if (comp != null) {
-              if (comp instanceof AbstractButton) {
-                myLastPaintButtonBorder = ((AbstractButton)comp).isBorderPainted();
-                ((AbstractButton)comp).setBorderPainted(true);
-              }
-              final Object border = comp.getClientProperty(OLD_BORDER);
-              if (border == null) {
-                comp.putClientProperty(OLD_BORDER, comp.getBorder());
-              }
-              comp.setBorder(BorderFactory.createLineBorder(getErrorColor(), 1));
-            }
-          }
-        }
-        setErrorText(message);
-        getOKAction().setEnabled(false);
-      }
-
-    });
-  }
-
-
-  private void clearProblems() {
-    SwingUtilities.invokeLater(new Runnable() {
-      public void run() {
-        setErrorText(null);
-        getOKAction().setEnabled(true);
-        //if (myLastPeerSize != null) {
-        //  myPeer.setSize(myLastPeerSize.width, myLastPeerSize.height);
-        //  myLastPeerSize = null;
-        //}
-        if (myLastErrorComponent != null) {
-          myLastErrorComponent.setBorder((Border)myLastErrorComponent.getClientProperty(OLD_BORDER));
-          if (myLastPaintButtonBorder != null && myLastErrorComponent instanceof AbstractButton) {
-            ((AbstractButton)myLastErrorComponent).setBorderPainted(myLastPaintButtonBorder);
-          }
-          myLastErrorComponent = null;
-          myLastPaintButtonBorder = null;
-        }
-      }
-    });
-  }
-
   protected String getDoNotShowMessage() {
     return CommonBundle.message("dialog.options.do.not.show");
   }
@@ -295,6 +193,63 @@ public abstract class DialogWrapper {
     createDefaultActions();
   }
 
+  //validation
+  private final Alarm myValidationAlarm = new Alarm(myDisposable);
+  private int myValidationDelay = 300;
+  private boolean myDisposed = false;
+  private boolean myValidationStarted = false;
+  private Icon ERROR_POINT = IconLoader.getIcon("/ide/errorPoint.png");
+  private Icon ERROR_SIGN = IconLoader.getIcon("/ide/errorSign.png");
+  private final ErrorPainter myErrorPainter = new ErrorPainter();
+
+  /**
+   * Allows to postpone first start of validation
+   *
+   * @return <code>false</code> if start validation in <code>init()</code> method
+   */
+  protected boolean postponeValidation() {
+    return false;
+  }
+
+  /**
+   * Validates a user input and returns <code>null</code> if everything is fine
+   * or returns a problem description with component where is the problem has been found.
+   *
+   * @return <code>null</code> if everything is OK or a problem descriptor
+   */
+  @Nullable
+  protected ValidationInfo doValidate() {
+    return null;
+  }
+
+  public void setValidationDelay(int delay) {
+    myValidationDelay = delay;
+  }
+
+  private void reportProblem(final ValidationInfo info) {
+    myErrorPainter.setValidationInfo(info);
+    if (! info.message.equals(myErrorText.myLabel.getText())) {
+    SwingUtilities.invokeLater(new Runnable() {
+      public void run() {
+        setErrorText(info.message);
+        myPeer.getRootPane().getGlassPane().repaint();
+        getOKAction().setEnabled(false);
+      }
+    });
+  }
+  }
+
+  private void clearProblems() {
+    myErrorPainter.setValidationInfo(null);
+    SwingUtilities.invokeLater(new Runnable() {
+      public void run() {
+        setErrorText(null);
+        myPeer.getRootPane().getGlassPane().repaint();
+        getOKAction().setEnabled(true);
+      }
+    });
+  }
+
   protected void createDefaultActions() {
     myOKAction = new OkAction();
     myCancelAction = new CancelAction();
@@ -614,6 +569,8 @@ public abstract class DialogWrapper {
    */
   protected void dispose() {
     ensureEventDispatchThread();
+    myErrorTextAlarm.cancelAllRequests();
+    myValidationAlarm.cancelAllRequests();
     myDisposed = true;
     if (myButtons != null) {
       for (JButton button : myButtons) {
@@ -920,7 +877,9 @@ public abstract class DialogWrapper {
 
     final JComponent c = createCenterPanel();
     if (c != null) {
-      centerSection.add(wrap(c, isCenterStrictedToPreferredSize()), BorderLayout.CENTER);
+      final JComponent wrap = wrap(c, isCenterStrictedToPreferredSize());
+      centerSection.add(wrap, BorderLayout.CENTER);
+      IdeGlassPaneUtil.installPainter(wrap, myErrorPainter, myDisposable);
     }
 
     final JPanel southSection = new JPanel(new BorderLayout());
@@ -941,7 +900,7 @@ public abstract class DialogWrapper {
   void startTrackingValidation() {
     SwingUtilities.invokeLater(new Runnable() {
       public void run() {
-        if (!myValidationStarted) {
+        if (!myValidationStarted && !myDisposed) {
           myValidationStarted = true;
           initValidation();
         }
@@ -957,7 +916,7 @@ public abstract class DialogWrapper {
         if (result == null) {
           clearProblems();
         } else {
-          reportProblem(result.message, result.component);
+          reportProblem(result);
         }
 
         if (!myDisposed) {
@@ -967,17 +926,6 @@ public abstract class DialogWrapper {
     }, myValidationDelay, ModalityState.current());
   }
 
-  public static final class ValidationInfo {
-    public final String message;
-    public final JComponent component;
-
-    public ValidationInfo(String message, JComponent component) {
-      this.message = message;
-      this.component = component;
-    }
-  }
-
-
   private static JComponent wrap(final JComponent c, boolean strict) {
     if (!strict) return c;
 
@@ -1517,4 +1465,64 @@ public abstract class DialogWrapper {
 
     String getDoNotShowMessage();
   }
+
+  private ErrorPaintingType getErrorPaintingType() {
+    return ErrorPaintingType.SIGN;
+  }
+
+  private class ErrorPainter extends AbstractPainter {
+    private ValidationInfo myInfo;
+
+    @Override
+    public void executePaint(Component component, Graphics2D g) {
+      if (myInfo != null &&  myInfo.component != null) {
+        final JComponent comp = myInfo.component;
+        final int w = comp.getWidth();
+        final int h = comp.getHeight();
+        Point p;
+        switch (getErrorPaintingType()) {
+          case DOT:
+            p = SwingUtilities.convertPoint(comp, 2,  h/2 , component);
+            ERROR_POINT.paintIcon(component, g, p.x, p.y);
+            break;
+          case SIGN:
+            p = SwingUtilities.convertPoint(comp, w,  0, component);
+            ERROR_SIGN.paintIcon(component, g, p.x - 8, p.y - 8);
+            break;
+          case LINE:
+            p = SwingUtilities.convertPoint(comp, 0,  h, component);
+            final GraphicsConfig config = new GraphicsConfig(g);
+            g.setColor(new Color(255, 0, 0 , 100));
+            g.fillRoundRect(p.x, p.y-2, w, 4, 2, 2);
+            config.restore();
+            break;
+        }
+      }
+    }
+
+    @Override
+    public boolean needsRepaint() {
+      return true;
+    }
+
+    public void setValidationInfo(ValidationInfo info) {
+      myInfo = info;
+    }
+  }
+
+  private static enum ErrorPaintingType {DOT, SIGN, LINE}
+
+  public static final class ValidationInfo {
+    public final String message;
+    public final JComponent component;
+
+    public ValidationInfo(@NotNull String message, JComponent component) {
+      this.message = message;
+      this.component = component;
+    }
+
+    public ValidationInfo(@NotNull String message) {
+      this(message, null);
+    }
+  }
 }
index 4aafb948aa95ecb35380612c89370e908a1aebaf..38f800f549f033436581020e8d21a7c6e76fe0cb 100644 (file)
@@ -107,11 +107,13 @@ public class Alarm implements Disposable {
 
   private void _addRequest(final Runnable request, int delayMillis, ModalityState modalityState) {
     synchronized (LOCK) {
+      LOG.assertTrue(!myDisposed, "Already disposed");
       final Request requestToSchedule = new Request(request, modalityState, delayMillis);
 
       if (myActivationComponent == null || myActivationComponent.isShowing()) {
         _add(requestToSchedule);
-      } else {
+      }
+      else {
         if (!myPendingRequests.contains(requestToSchedule)) {
           myPendingRequests.add(requestToSchedule);
         }
index 4e68e64ba9cac4b1114f198cac0892e665bcf035..bcb2e34055f70a7e8b78859110d4e6ff9112173c 100644 (file)
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.Disposer;
 import com.intellij.util.Alarm;
 import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
@@ -368,6 +369,7 @@ public class MergingUpdateQueue implements Runnable, Disposable, Activatable {
     return myModalityStateComponent == ANY_COMPONENT ? null : getModalityState();
   }
 
+  @NotNull
   public ModalityState getModalityState() {
     if (myModalityStateComponent == null) {
       return ModalityState.NON_MODAL;
index f318d33732eccd18a33ebf9a0b6ace714ebf59da..0670963181c98bcf664da28eb3795fe67df0bb13 100644 (file)
@@ -631,17 +631,20 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
     LaterInvocator.invokeAndWait(runnable, modalityState);
   }
 
+  @NotNull
   public ModalityState getCurrentModalityState() {
     Object[] entities = LaterInvocator.getCurrentModalEntities();
     return entities.length > 0 ? new ModalityStateEx(entities) : getNoneModalityState();
   }
 
+  @NotNull
   public ModalityState getModalityStateForComponent(@NotNull Component c) {
     Window window = c instanceof Window ? (Window)c : SwingUtilities.windowForComponent(c);
     if (window == null) return getNoneModalityState(); //?
     return LaterInvocator.modalityStateForWindow(window);
   }
 
+  @NotNull
   public ModalityState getDefaultModalityState() {
     if (EventQueue.isDispatchThread()) {
       return getCurrentModalityState();
@@ -652,6 +655,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
     }
   }
 
+  @NotNull
   public ModalityState getNoneModalityState() {
     return MODALITY_STATE_NONE;
   }
@@ -719,6 +723,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
         return false;
       }
     }
+    Disposer.dispose(confirmExitDialog.getDisposable());
     return true;
   }
 
index 70390c10d3f653e2998ec96d577bbcaebe6d4e8b..dc42c718b0ee6b2535c70ca329ff12a8b27c5240 100644 (file)
@@ -96,6 +96,7 @@ public class LaterInvocator {
     ourModalityStateMulticaster.removeListener(listener);
   }
 
+  @NotNull
   static ModalityStateEx modalityStateForWindow(@NotNull Window window){
     int index = ourModalEntities.indexOf(window);
     if (index < 0){
index 533b4b22f7dacde767cc1c1c392e8f9f7dee1c8f..3545e1c47799962c6d0074bb34cf2b22fa548f08 100644 (file)
@@ -18,6 +18,7 @@ package com.intellij.openapi.application.impl;
 import com.intellij.openapi.application.ModalityState;
 import com.intellij.openapi.progress.ProgressIndicator;
 import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
@@ -44,11 +45,13 @@ public class ModalityStateEx extends ModalityState {
     }
   }
 
-  public ModalityState appendProgress(ProgressIndicator progress){
+  @NotNull
+  public ModalityState appendProgress(@NotNull ProgressIndicator progress){
     return appendEntity(progress);
   }
 
-  ModalityStateEx appendEntity(Object anEntity){
+  @NotNull
+  ModalityStateEx appendEntity(@NotNull Object anEntity){
     ArrayList<Object> list = new ArrayList<Object>();
     for (WeakReference modalEntity : myModalEntities) {
       Object entity = modalEntity.get();
@@ -68,7 +71,7 @@ public class ModalityStateEx extends ModalityState {
     return false;
   }
 
-  public boolean dominates(ModalityState anotherState){
+  public boolean dominates(@NotNull ModalityState anotherState){
     for (WeakReference modalEntity : myModalEntities) {
       Object entity = modalEntity.get();
       if (entity == null) continue;
@@ -93,4 +96,4 @@ public class ModalityStateEx extends ModalityState {
     }
     return buffer.toString();
   }
-}
\ No newline at end of file
+}
index 76932222cc0832f5c5c26a3f5fe841d191679d52..7ea59777c4018ecbc2f32fa534642877ab0423f8 100644 (file)
@@ -541,16 +541,18 @@ public class EditorActionUtil {
   private static void setupSelection(Editor editor,
                                      boolean isWithSelection,
                                      int selectionStart, LogicalPosition blockSelectionStart) {
+    SelectionModel selectionModel = editor.getSelectionModel();
     if (isWithSelection) {
+      CaretModel caretModel = editor.getCaretModel();
       if (editor.isColumnMode()) {
-        editor.getSelectionModel().setBlockSelection(blockSelectionStart, editor.getCaretModel().getLogicalPosition());
+        selectionModel.setBlockSelection(blockSelectionStart, caretModel.getLogicalPosition());
       }
       else {
-        editor.getSelectionModel().setSelection(selectionStart, editor.getCaretModel().getOffset());
+        selectionModel.setSelection(selectionStart, caretModel.getVisualPosition(), caretModel.getOffset());
       }
     }
     else {
-      editor.getSelectionModel().removeSelection();
+      selectionModel.removeSelection();
     }
   }
 
index 3ce855b2c0ba29f45acbf0130e13b9be8da85370..cf21d70e82ce8488157c6349ce26ebd2ed7c80fa 100644 (file)
@@ -284,7 +284,7 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
           }
         }
         else {
-          selectionModel.setSelection(selectionStart, getOffset());
+          selectionModel.setSelection(selectionStart, getVisualPosition(), getOffset());
         }
       }
     }
@@ -427,6 +427,11 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
     }
   }
 
+  @Override
+  public boolean isUpToDate() {
+    return !myIsInUpdate;
+  }
+
   @NotNull
   public LogicalPosition getLogicalPosition() {
     validateCallContext();
index e5d4e7716eefaafea135eae6ba9f2353af6d14ad..e8c0501301bbb47cb72444570b8738daa91d91a7 100644 (file)
@@ -202,6 +202,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
 
   private boolean myUpdateCursor;
   private int myCaretUpdateVShift;
+  
+  @Nullable
   private final Project myProject;
   private long myMouseSelectionChangeTimestamp;
   private int mySavedCaretOffsetForDNDUndoHack;
@@ -252,7 +254,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
     ourCaretBlinkingCommand.start();
   }
 
-  EditorImpl(@NotNull Document document, boolean viewer, Project project) {
+  EditorImpl(@NotNull Document document, boolean viewer, @Nullable Project project) {
     myProject = project;
     myDocument = (DocumentImpl)document;
     myScheme = createBoundColorSchemeDelegate(null);
@@ -508,6 +510,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
     myDescent = -1;
     myPlainFontMetrics = null;
 
+    boolean softWrapsUsedBefore = mySoftWrapModel.isSoftWrappingEnabled();
+    
     mySoftWrapModel.reinitSettings();
     myCaretModel.reinitSettings();
     mySelectionModel.reinitSettings();
@@ -518,7 +522,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
     myFoldingModel.refreshSettings();
     myFoldingModel.rebuild();
 
-
+    if (softWrapsUsedBefore ^ mySoftWrapModel.isSoftWrappingEnabled()) {
+      mySizeContainer.reset();
+      validateSize();
+    }
+    
     final EditorColorsScheme scheme =
       myScheme instanceof DelegateColorScheme? ((DelegateColorScheme)myScheme).getDelegate() : myScheme;
     if (scheme instanceof MyColorSchemeDelegate) {
@@ -2866,7 +2874,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
     final Dimension draft = getSizeWithoutCaret();
     final int additionalSpace = mySettings.getAdditionalColumnsCount() * EditorUtil.getSpaceWidth(Font.PLAIN, this);
 
-    if (!myDocument.isInBulkUpdate()) {
+    if (!myDocument.isInBulkUpdate() && getCaretModel().isUpToDate()) {
       int caretX = visualPositionToXY(getCaretModel().getVisualPosition()).x;
       draft.width = Math.max(caretX, draft.width) + additionalSpace;
     }
index 880b7b16b04ff7e8a614702f9b7fc383afb0f29b..0c99f8a8eb1d769bdac5d740abfd21596ad2df78 100644 (file)
@@ -32,7 +32,7 @@ public class PersistentLineMarker extends RangeMarkerImpl {
   @Override
   protected void changedUpdateImpl(DocumentEvent e) {
     DocumentEventImpl event = (DocumentEventImpl)e;
-    if (event.isWholeTextReplaced()) {
+    if (PersistentRangeMarkerUtil.shouldTranslateViaDiff(event, this)) {
       myLine = event.translateLineViaDiff(myLine);
       if (myLine < 0 || myLine >= getDocument().getLineCount()) {
         invalidate();
index 25732dc1fbcc0675114d52935d6d7d516415e2a9..5216288287173bafa011579bd8dee9bd694d177c 100644 (file)
@@ -20,6 +20,12 @@ import com.intellij.openapi.editor.ex.DocumentEx;
 import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
 
 /**
+ * This class is an extension to range marker that tries to restore its range even in situations when target text referenced by it
+ * is replaced.
+ * <p/>
+ * Example: consider that the user selects all text at editor (Ctrl+A), copies it to the buffer (Ctrl+C) and performs paste (Ctrl+V).
+ * All document text is replaced then but in essence it's the same, hence, we may want particular range markers to be still valid.   
+ * 
  * @author max
  */
 class PersistentRangeMarker extends RangeMarkerImpl {
@@ -54,7 +60,7 @@ class PersistentRangeMarker extends RangeMarkerImpl {
   @Override
   protected void changedUpdateImpl(DocumentEvent e) {
     DocumentEventImpl event = (DocumentEventImpl)e;
-    if (event.isWholeTextReplaced()){
+    if (PersistentRangeMarkerUtil.shouldTranslateViaDiff(event, this)){
       myStartLine = event.translateLineViaDiffStrict(myStartLine);
       if (myStartLine < 0 || myStartLine >= getDocument().getLineCount()){
         invalidate();
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/PersistentRangeMarkerUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/PersistentRangeMarkerUtil.java
new file mode 100644 (file)
index 0000000..2e78c2c
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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.editor.impl;
+
+import com.intellij.openapi.editor.RangeMarker;
+import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Denis Zhdanov
+ * @since 12/27/10 4:26 PM
+ */
+public class PersistentRangeMarkerUtil {
+
+  private PersistentRangeMarkerUtil() {
+  }
+
+  /**
+   * Answers if document region identified by the given range marker should be translated via diff algorithm on document change
+   * identified by the given event.
+   *
+   * @param e             event that describes document change
+   * @param rangeMarker   target range marker which update strategy should be selected
+   * @return              <code>true</code> if target document range referenced by the given range marker should be translated via
+   *                      diff algorithm; <code>false</code> otherwise
+   */
+  public static boolean shouldTranslateViaDiff(@NotNull DocumentEventImpl e, @NotNull RangeMarker rangeMarker) {
+    if (e.isWholeTextReplaced()) {
+      // Perform translation if the whole text is replaced.
+      return true;
+    }
+
+    if (!rangeMarker.isValid()) {
+      // Don't perform complex processing if current range marker is already invalid.
+      return false;
+    }
+
+    if (e.getOffset() >= rangeMarker.getEndOffset() || e.getOffset() + e.getOldLength() <= rangeMarker.getStartOffset()) {
+      // Don't perform complex processing if the change doesn't affect target range.
+      return false;
+    }
+
+    // Perform complex processing only if significant document part is updated.
+    return (Math.max(e.getNewLength(), e.getOldLength()) * 1.0) / e.getDocument().getTextLength() >= 0.8;
+  }
+}
index b7c7ae24706e27ee266799087b7c52b8cf2fc021..e85df820ec754db1cb373f18b4e001b17553a01b 100644 (file)
@@ -252,10 +252,26 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
   public void setSelection(int startOffset, int endOffset) {
     doSetSelection(myEditor.offsetToVisualPosition(startOffset), startOffset, myEditor.offsetToVisualPosition(endOffset), endOffset, false);
   }
-  
+
+  @Override
+  public void setSelection(int startOffset, @Nullable VisualPosition endPosition, int endOffset) {
+    VisualPosition startPosition;
+    if (hasSelection()) {
+      startPosition = getLeadSelectionPosition();
+    }
+    else {
+      startPosition = myEditor.offsetToVisualPosition(startOffset);
+    }
+    setSelection(startPosition, startOffset, endPosition, endOffset);
+  }
+
   @Override
-  public void setSelection(@NotNull VisualPosition startPosition, int startOffset, @NotNull VisualPosition endPosition, int endOffset) {
-    doSetSelection(startPosition, startOffset, endPosition, endOffset, true);
+  public void setSelection(final @Nullable VisualPosition startPosition, int startOffset, final @Nullable VisualPosition endPosition,
+                           int endOffset) 
+  {
+    VisualPosition startPositionToUse = startPosition == null ? myEditor.offsetToVisualPosition(startOffset) : startPosition;
+    VisualPosition endPositionToUse = endPosition == null ? myEditor.offsetToVisualPosition(endOffset) : endPosition;
+    doSetSelection(startPositionToUse, startOffset, endPositionToUse, endOffset, true);
   }
 
   private void doSetSelection(@NotNull VisualPosition startPosition, int startOffset, @NotNull VisualPosition endPosition,
index ec6a5d2e614becb33c57c0fc53550b833ef6221b..42117378489a5b329087a729f9494c9640f8371b 100644 (file)
@@ -134,6 +134,7 @@ public class DocumentEventImpl extends DocumentEvent {
            ", myOldString='" + myOldString + "', myNewString='" + myNewString + "']" + (isWholeTextReplaced() ? " Whole." : ".");
   }
 
+  @Override
   public boolean isWholeTextReplaced() {
     return myIsWholeDocReplaced;
   }
index 51516e563ba0de3d8777335b81a5ea665e7f01a4..3c13bd340bfc99e292b97951ecf79246ac04695b 100644 (file)
@@ -18,8 +18,8 @@ package com.intellij.openapi.editor.textarea;
 import com.intellij.openapi.editor.CaretModel;
 import com.intellij.openapi.editor.LogicalPosition;
 import com.intellij.openapi.editor.VisualPosition;
-import com.intellij.openapi.editor.markup.TextAttributes;
 import com.intellij.openapi.editor.event.CaretListener;
+import com.intellij.openapi.editor.markup.TextAttributes;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
@@ -61,6 +61,11 @@ public class TextComponentCaretModel implements CaretModel {
     myTextComponent.setCaretPosition(Math.min(offset, myTextComponent.getText().length()));
   }
 
+  @Override
+  public boolean isUpToDate() {
+    return true;
+  }
+
   @NotNull
   public LogicalPosition getLogicalPosition() {
     int caretPos = myTextComponent.getCaretPosition();
index c5bd698e5777169d653d4dc360e2e3c30fe0acb3..fd2e94ba1b06dfd2b95ec79e61bc5bd3bac3ea8e 100644 (file)
@@ -96,7 +96,12 @@ public class TextComponentSelectionModel implements SelectionModel {
   }
 
   @Override
-  public void setSelection(@NotNull VisualPosition startPosition, int startOffset, @NotNull VisualPosition endPosition, int endOffset) {
+  public void setSelection(int startOffset, @Nullable VisualPosition endPosition, int endOffset) {
+    setSelection(startOffset, endOffset);
+  }
+
+  @Override
+  public void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset) {
     setSelection(startOffset, endOffset);
   }
 
index 97ff72231abf4aa4c6157833705252eeb4a1d519..948c5352a4b53f4a54a6b8967f5aedb71d0d9769 100644 (file)
@@ -303,6 +303,7 @@ public class ProgressIndicatorBase extends UserDataHolderBase implements Progres
     return myModalityProgress != null;
   }
 
+  @NotNull
   public final ModalityState getModalityState() {
     return myModalityState;
   }
index 1626f26cceee51c172da1f2906e8252ad50dcfaf..bcf6e368e753df08190826e228278164ad1c2774 100644 (file)
@@ -21,6 +21,7 @@ import com.intellij.ide.highlighter.WorkspaceFileType;
 import com.intellij.ide.impl.ProjectUtil;
 import com.intellij.ide.startup.impl.StartupManagerImpl;
 import com.intellij.notification.NotificationsManager;
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.application.*;
 import com.intellij.openapi.application.ex.ApplicationManagerEx;
 import com.intellij.openapi.application.impl.ApplicationImpl;
@@ -417,7 +418,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
     myOpenProjectsArrayCache = myOpenProjects.toArray(new Project[myOpenProjects.size()]);
   }
 
-  public Project loadAndOpenProject(String filePath) throws IOException, JDOMException, InvalidDataException {
+  public Project loadAndOpenProject(@NotNull String filePath) throws IOException, JDOMException, InvalidDataException {
     return loadAndOpenProject(filePath, true);
   }
 
@@ -826,7 +827,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
     }
   }
 
-  public void reloadProject(final Project p) {
+  public void reloadProject(@NotNull final Project p) {
     reloadProjectImpl(p, true, false);
   }
 
@@ -886,7 +887,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
   }
   */
 
-  public boolean closeProject(final Project project) {
+  public boolean closeProject(@NotNull final Project project) {
     return closeProject(project, true, false);
   }
 
@@ -950,16 +951,27 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
     }
   }
 
-  public void addProjectManagerListener(ProjectManagerListener listener) {
+  public void addProjectManagerListener(@NotNull ProjectManagerListener listener) {
     myListeners.add(listener);
   }
 
-  public void removeProjectManagerListener(ProjectManagerListener listener) {
+  @Override
+  public void addProjectManagerListener(@NotNull final ProjectManagerListener listener, @NotNull Disposable parentDisposable) {
+    addProjectManagerListener(listener);
+    Disposer.register(parentDisposable, new Disposable() {
+      @Override
+      public void dispose() {
+        removeProjectManagerListener(listener);
+      }
+    });
+  }
+
+  public void removeProjectManagerListener(@NotNull ProjectManagerListener listener) {
     boolean removed = myListeners.remove(listener);
     LOG.assertTrue(removed);
   }
 
-  public void addProjectManagerListener(Project project, ProjectManagerListener listener) {
+  public void addProjectManagerListener(@NotNull Project project, @NotNull ProjectManagerListener listener) {
     List<ProjectManagerListener> listeners = project.getUserData(LISTENERS_IN_PROJECT_KEY);
     if (listeners == null) {
       listeners = ((UserDataHolderEx)project).putUserDataIfAbsent(LISTENERS_IN_PROJECT_KEY, new ArrayList<ProjectManagerListener>());
@@ -967,7 +979,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
     listeners.add(listener);
   }
 
-  public void removeProjectManagerListener(Project project, ProjectManagerListener listener) {
+  public void removeProjectManagerListener(@NotNull Project project, @NotNull ProjectManagerListener listener) {
     List<ProjectManagerListener> listeners = project.getUserData(LISTENERS_IN_PROJECT_KEY);
     if (listeners != null) {
       boolean removed = listeners.remove(listener);
index 535555f728f1e9e283d9932dd1128c3af58bb2c9..000b276a218b7572879fc92da6751f13cb897f0e 100644 (file)
@@ -48,12 +48,6 @@ public abstract class LocalFileSystemBase extends LocalFileSystem {
 
   @Nullable
   public VirtualFile findFileByPath(@NotNull String path) {
-    /*
-    if (File.separatorChar == '\\') {
-      if (path.indexOf('\\') >= 0) return null;
-    }
-    */
-
     String canonicalPath = getVfsCanonicalPath(path);
     if (canonicalPath == null) return null;
     return super.findFileByPath(canonicalPath);
index 71ed8bef0acff52102d0d4dbca83d777ffcb6597..f54878d042d6a8c6384a3eed1bb25f104d2c3ef7 100644 (file)
@@ -73,8 +73,10 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
 
     final VirtualFile[] a = asArray();
     if (a != null) {
+      Object encoded = encodeName(name);
+      byte[] bytes = encoded instanceof byte[] ? (byte[])encoded : null;
       for (VirtualFile file : a) {
-        if (namesEqual(name, file.getName())) return (NewVirtualFile)file;
+        if (namesEqual(name, bytes, file)) return (NewVirtualFile)file;
       }
 
       return createIfNotFound ? createAndFindChildWithEventFire(name) : null;
@@ -114,6 +116,21 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
     return null;
   }
 
+  private boolean namesEqual(String name, byte[] encoded, VirtualFile file) {
+    if (encoded != null && file instanceof VirtualFileSystemEntry) {
+      Object o = ((VirtualFileSystemEntry)file).rawName();
+      if (!(o instanceof byte[])) return false;
+
+      if (encoded.length != ((byte[])o).length) return false;
+    }
+
+    final String name2 = file.getName();
+    if (getFileSystem().isCaseSensitive()) {
+      return name.equals(name2);
+    }
+    return name.equalsIgnoreCase(name2);
+  }
+
   public VirtualFileSystemEntry createChild(String name, int id) {
     final VirtualFileSystemEntry child;
     final NewVirtualFileSystem fs = getFileSystem();
@@ -155,8 +172,10 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
   public synchronized NewVirtualFile findChildIfCached(final String name) {
     final VirtualFile[] a = asArray();
     if (a != null) {
+      Object encoded = encodeName(name);
+      byte[] bytes = encoded instanceof byte[] ? (byte[])encoded : null;
       for (VirtualFile file : a) {
-        if (namesEqual(name, file.getName())) return (NewVirtualFile)file;
+        if (namesEqual(name, bytes, file)) return (NewVirtualFile)file;
       }
 
       return null;
@@ -360,10 +379,6 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
     return Collections.emptyList();
   }
 
-  private boolean namesEqual(final String name1, final String name2) {
-    return getFileSystem().isCaseSensitive() ? name1.equals(name2) : name1.equalsIgnoreCase(name2);
-  }
-
   private Map<String, VirtualFile> createMap() {
     return getFileSystem().isCaseSensitive()
            ? new THashMap<String, VirtualFile>()
index 45d403a820ecf1b6ecc7f35fbf86d52a8b3270d9..9294c2e2c83fe15c76ba2e4f87883479cec74583 100644 (file)
@@ -39,26 +39,46 @@ import java.nio.charset.Charset;
 public abstract class VirtualFileSystemEntry extends NewVirtualFile {
   protected static final PersistentFS ourPersistence = (PersistentFS)ManagingFS.getInstance();
   private static final byte DIRTY_FLAG = 0x01;
+  private static final Charset UTF_8 = Charset.forName("UTF-8");
 
-  private volatile String myName;
+  private volatile Object myName;
   private volatile VirtualDirectoryImpl myParent;
   private volatile byte myFlags = 0;
   private volatile int myId;
 
   public VirtualFileSystemEntry(final String name, final VirtualDirectoryImpl parent, int id) {
-    myName = name.replace('\\', '/');  // note: on Unix-style FS names may contain backslashes
+    myName = encodeName(name.replace('\\', '/'));  // note: on Unix-style FS names may contain backslashes
     myParent = parent;
     myId = id;
   }
 
+  protected static Object encodeName(String name) {
+    byte[] bytes = name.getBytes(UTF_8);
+    return bytes.length < name.length() * 2 ? bytes : name;
+  }
+
   @NotNull
   public String getName() {
+    String name = decodeName();
+
     // TODO: HACK!!! Get to simpler solution.
     if (myParent == null && getFileSystem() instanceof JarFileSystem) {
-      String jarName = myName.substring(0, myName.length() - JarFileSystem.JAR_SEPARATOR.length());
+      String jarName = name.substring(0, name.length() - JarFileSystem.JAR_SEPARATOR.length());
       return jarName.substring(jarName.lastIndexOf('/') + 1);
     }
 
+    return name;
+  }
+
+  private String decodeName() {
+    Object name = rawName();
+    if (name instanceof String) {
+      return (String)name;
+    }
+    return new String((byte[])name, UTF_8);
+  }
+
+  protected final Object rawName() {
     return myName;
   }
 
@@ -76,12 +96,13 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile {
       }
     }
 
-    if (myName.length() > 0) {
+    String name = decodeName();
+    if (name.length() > 0) {
       final int len = builder.length();
       if (len > 0 && builder.charAt(len - 1) != '/') {
         builder.append('/');
       }
-      builder.append(myName);
+      builder.append(name);
     }
   }
 
@@ -239,13 +260,13 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile {
     return getUrl();
   }
 
-  public void setName(final String newName) {
-    if (newName != null && newName.length() == 0) {
+  public void setName(@NotNull final String newName) {
+    if (newName.length() == 0) {
       throw new IllegalArgumentException("Name of the virtual file cannot be set to empty string");
     }
 
     myParent.removeChild(this);
-    myName = newName != null? newName.replace('\\', '/') : null;
+    myName = encodeName(newName.replace('\\', '/'));
     myParent.addChild(this);
   }
 
diff --git a/platform/platform-impl/testSrc/com/intellij/ide/bookmarks/BookmarkManagerTest.java b/platform/platform-impl/testSrc/com/intellij/ide/bookmarks/BookmarkManagerTest.java
new file mode 100644 (file)
index 0000000..81be185
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * 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.bookmarks;
+
+import com.intellij.openapi.editor.CaretModel;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.LogicalPosition;
+import com.intellij.openapi.editor.impl.AbstractEditorProcessingOnDocumentModificationTest;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Denis Zhdanov
+ * @since 12/27/10 1:43 PM
+ */
+public class BookmarkManagerTest extends AbstractEditorProcessingOnDocumentModificationTest {
+
+  private final List<Bookmark> myBookmarks = new ArrayList<Bookmark>();
+  
+  @Override
+  protected void tearDown() throws Exception {
+    for (Bookmark bookmark : myBookmarks) {
+      getManager().removeBookmark(bookmark);
+    }
+    myBookmarks.clear();
+    super.tearDown();
+  }
+
+  public void testWholeTextReplace() throws IOException {
+    String text =
+      "public class Test {\n" +
+      "    public void test() {\n" +
+      "        int i = 1;\n" +
+      "    }\n" +
+      "}";
+    init(text);
+
+    addBookmark(2);
+    List<Bookmark> bookmarksBefore = getManager().getValidBookmarks();
+    assertEquals(1, bookmarksBefore.size());
+    
+    myEditor.getDocument().setText(text);
+    List<Bookmark> bookmarksAfter = getManager().getValidBookmarks();
+    assertEquals(1, bookmarksAfter.size());
+    assertSame(bookmarksBefore.get(0), bookmarksAfter.get(0));
+    for (Bookmark bookmark : bookmarksAfter) {
+      checkBookmark(bookmark);
+    }
+  }
+  
+  public void testBookmarkLineRemove() throws IOException {
+    String text =
+      "public class Test {\n" +
+      "    public void test() {\n" +
+      "        int i = 1;\n" +
+      "    }\n" +
+      "}";
+    init(text);
+    
+    addBookmark(2);
+    Document document = myEditor.getDocument();
+    myEditor.getSelectionModel().setSelection(document.getLineStartOffset(2) - 1, document.getLineEndOffset(2));
+    delete();
+    assertTrue(getManager().getValidBookmarks().isEmpty());
+  }
+  
+  public void testBookmarkIsSavedAfterRemoteChange() throws IOException {
+    String text =
+      "public class Test {\n" +
+      "    public void test() {\n" +
+      "        int i = 1;\n" +
+      "    }\n" +
+      "}";
+    init(text);
+    addBookmark(2);
+    
+    myEditor.getDocument().setText("111\n222" + text + "333");
+    List<Bookmark> bookmarks = getManager().getValidBookmarks();
+    assertEquals(1, bookmarks.size());
+    Bookmark bookmark = bookmarks.get(0);
+    assertEquals(3, bookmark.getLine());
+    checkBookmark(bookmark);
+  }
+  
+  private void addBookmark(int line) {
+    Bookmark bookmark = getManager().addTextBookmark(getFile().getVirtualFile(), line, "");
+    myBookmarks.add(bookmark);
+  }
+  
+  private static BookmarkManager getManager() {
+    return BookmarkManager.getInstance(getProject());
+  }
+  
+  private static void checkBookmark(Bookmark bookmark) {
+    int line = bookmark.getLine();
+    int anotherLine = line;
+    if (line > 0) {
+      anotherLine--;
+    }
+    else {
+      anotherLine++;
+    }
+    CaretModel caretModel = myEditor.getCaretModel();
+    caretModel.moveToLogicalPosition(new LogicalPosition(anotherLine, 0));
+    OpenFileDescriptor target = bookmark.getTarget();
+    assertTrue(target.canNavigate());
+    target.navigateIn(myEditor);
+    assertEquals(line, caretModel.getLogicalPosition().line);
+  }
+}
index d7d990ba657307097c05d518b5bae28e51e8dc51..b77e9a1f13acbb65b47d70aaeeb18525129f4780 100644 (file)
@@ -629,6 +629,21 @@ public class SoftWrapApplianceOnDocumentModificationTest extends AbstractEditorP
     }
   }
   
+  public void testVerticalCaretShiftOnLineComment() throws IOException {
+    String text =
+      "1. just a line that is long enough to be soft wrapped\n" +
+      "2. just a line that is long enough to be soft wrapped\n" +
+      "3. just a line that is long enough to be soft wrapped\n" +
+      "4. just a line that is long enough to be soft wrapped";
+    init(100, text);
+
+    CaretModel caretModel = myEditor.getCaretModel();
+    caretModel.moveToOffset(text.indexOf("2.") + 2);
+    lineComment();
+    
+    assertEquals(myEditor.offsetToLogicalPosition(text.indexOf("3.") + 2), caretModel.getLogicalPosition());
+  }
+  
   private static TIntHashSet collectSoftWrapStartOffsets(int documentLine) {
     TIntHashSet result = new TIntHashSet();
     for (SoftWrap softWrap : myEditor.getSoftWrapModel().getSoftWrapsForLine(documentLine)) {
index 72bb568e217b4e5e50708a60099e563d47fc474b..c1d1bd08a8e66929e02358d9c33ebd1d1b4447f0 100644 (file)
@@ -49,7 +49,7 @@ editing.completion.second.smarttype.chain=Second smart type completion: chained
 editing.completion.second.smarttype.toar=Second smart type completion: toArray() conversion
 editing.completion.second.smarttype.aslist=Second smart type completion: asList() conversion
 editing.completion.second.smarttype.array.member=Second smart type completion: array member access
-editing.completion.import.static=Static import via code completion
+editing.completion.global.member.name=Global method name code completion
 editing.completion.variable.name=Variable name completion
 editing.completion.replace=Replace By when using lookup
 editing.completion.finishByDotEtc=Finish lookup by special characters
index 05ca6432eb5f05f78f3693453eb72d99fb4352b7..d08536d5be823eab4021a7796ac879cd97b5a341 100644 (file)
 
     <fileTypeIndentOptionsProvider implementation="com.intellij.application.options.XmlIndentOptionsProvider"/>
 
-    <methodNavigationOffsetProvider implementation="com.intellij.codeInsight.navigation.XmlMethodNavigationOffsetProvider"/>
+    <methodNavigationOffsetProvider implementation="com.intellij.codeInsight.navigation.XmlMethodNavigationOffsetProvider" order="last"/>
 
     <annotator language="XML" implementationClass="com.intellij.codeInspection.htmlInspections.XmlWrongClosingTagNameInspection"/>
 
index c4be0b31e1d86ea0caa414f4e7dfc5c1538256ba..93f2c41121a3ddb770197625240d2ca1e6d7c940 100644 (file)
@@ -95,8 +95,5 @@
       <implementation-class>com.intellij.openapi.vcs.impl.VcsFileStatusProvider</implementation-class>
       <skipForDefaultProject/>
     </component>
-    <component>
-      <implementation-class>com.intellij.lifecycle.PeriodicalTasksCloser</implementation-class>
-    </component>
   </project-components>
 </components>
index 269131d50774333af29a90adee986dc41492296a..b09414903c61fcee7a4b5634a58a4981c6ebd7b8 100644 (file)
@@ -169,7 +169,7 @@ public class MockApplication extends MockComponentManager implements Application
   }
 
   @Override
-  public <T> T getCurrentWriteAction(@NotNull Class<T> actionClass) {
+  public <T> T getCurrentWriteAction(@Nullable Class<T> actionClass) {
     return null;
   }
 
@@ -285,21 +285,25 @@ public class MockApplication extends MockComponentManager implements Application
     return Extensions.getRootArea().getExtensionPoint(extensionPointName).getExtensions();
   }
 
+  @NotNull
   @Override
   public ModalityState getCurrentModalityState() {
-    return null;
+    throw new UnsupportedOperationException();
   }
 
+  @NotNull
   @Override
   public ModalityState getModalityStateForComponent(@NotNull Component c) {
-    return null;
+    throw new UnsupportedOperationException();
   }
 
+  @NotNull
   @Override
   public ModalityState getDefaultModalityState() {
-    return null;
+    throw new UnsupportedOperationException();
   }
 
+  @NotNull
   @Override
   public ModalityState getNoneModalityState() {
     if (MODALITY_STATE_NONE == null) {
index f10be1e141b68efd729d8c8e35096f54d36ccd6f..298b52ea93115cc8a05e4c86cea87f0ffa3f4322 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.intellij.testFramework;
 
+import com.intellij.codeInsight.generation.CommentByLineCommentHandler;
 import com.intellij.ide.DataManager;
 import com.intellij.injected.editor.DocumentWindow;
 import com.intellij.injected.editor.EditorWindow;
@@ -491,6 +492,10 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
     doAction(IdeActions.ACTION_EDITOR_PASTE);
   }
   
+  protected static void lineComment() {
+    new CommentByLineCommentHandler().invoke(getProject(), getEditor(), getFile());
+  }
+  
   private static void doAction(@NotNull String actionId) {
     EditorActionManager actionManager = EditorActionManager.getInstance();
     EditorActionHandler actionHandler = actionManager.getActionHandler(actionId);
index cc940ba9a9aa57976a27624216e54d1cc4a44c36..025e2b1cd4642d2d03f44b5109fefff1a6c7d35f 100644 (file)
@@ -262,7 +262,7 @@ public abstract class UsefulTestCase extends TestCase {
     final StringBuilder builder = new StringBuilder();
     for (final Object o : collection) {
       if (o instanceof THashSet) {
-        builder.append(new TreeSet<Object>((Collection<Object>)o));
+        builder.append(new TreeSet<Object>((THashSet)o));
       }
       else {
         builder.append(o);
@@ -423,7 +423,7 @@ public abstract class UsefulTestCase extends TestCase {
   }
 
   public static void printThreadDump() {
-    PerformanceWatcher.getInstance().dumpThreadsToConsole();
+    PerformanceWatcher.dumpThreadsToConsole();
   }
 
   public static void assertEmpty(final Object[] array) {
@@ -642,9 +642,9 @@ public abstract class UsefulTestCase extends TestCase {
     assertNull(throwableName);
   }
 
-  private void assertExceptionOccurred(boolean shouldOccur,
-                                       AbstractExceptionCase exceptionCase,
-                                       String expectedErrorMsg) throws Throwable {
+  private static void assertExceptionOccurred(boolean shouldOccur,
+                                              AbstractExceptionCase exceptionCase,
+                                              String expectedErrorMsg) throws Throwable {
     boolean wasThrown = false;
     try {
       exceptionCase.tryClosure();
index ce1e96106f6757754d068de54a30716c12ec6eeb..5c3bb6d74d801a4d3f46cc72347e614f5590f260 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.intellij.lifecycle;
 
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.application.Application;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.ModalityState;
@@ -26,35 +27,30 @@ import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.project.ProjectManagerListener;
+import com.intellij.openapi.project.ProjectManagerAdapter;
 import com.intellij.openapi.project.impl.ProjectLifecycleListener;
 import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Key;
 import com.intellij.util.concurrency.Semaphore;
-import com.intellij.util.containers.MultiMap;
 import com.intellij.util.messages.MessageBusConnection;
 import com.intellij.vcsUtil.Rethrow;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 
-import java.util.Arrays;
-import java.util.Collection;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
 
-public class PeriodicalTasksCloser implements ProjectManagerListener, ProjectLifecycleListener, ApplicationComponent {
-  private final static Logger LOG = Logger.getInstance("#com.intellij.lifecycle.PeriodicalTasksCloser");
+public class PeriodicalTasksCloser extends ProjectManagerAdapter implements ProjectLifecycleListener, ApplicationComponent {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.lifecycle.PeriodicalTasksCloser");
   private final Object myLock = new Object();
-  private final MultiMap<Project, Pair<String, Runnable>> myInterrupters;
-  //private final Map<Project, TracedLifeCycle> myStates = new HashMap<Project, TracedLifeCycle>();
-  private MessageBusConnection myConnection;
-  private ProjectManager myProjectManager;
 
-  private PeriodicalTasksCloser(final ProjectManager projectManager) {
-    myInterrupters = new MultiMap<Project, Pair<String, Runnable>>();
-    myProjectManager = projectManager;
-    myProjectManager.addProjectManagerListener(this);
-    myConnection = ApplicationManager.getApplication().getMessageBus().connect();
-    myConnection.subscribe(ProjectLifecycleListener.TOPIC, this);
+  PeriodicalTasksCloser(final ProjectManager projectManager) {
+    Application application = ApplicationManager.getApplication();
+    MessageBusConnection connection = application.getMessageBus().connect(application);
+    connection.subscribe(ProjectLifecycleListener.TOPIC, this);
+    projectManager.addProjectManagerListener(this, application);
   }
 
   public static PeriodicalTasksCloser getInstance() {
@@ -63,14 +59,6 @@ public class PeriodicalTasksCloser implements ProjectManagerListener, ProjectLif
 
   @Override
   public void disposeComponent() {
-    /*synchronized (myLock) {
-      myStates.clear(); // +-
-    }*/
-    myProjectManager.removeProjectManagerListener(this);
-    myConnection.disconnect();
-    synchronized (myLock) {
-      myInterrupters.clear();
-    }
   }
 
   @NotNull
@@ -83,65 +71,67 @@ public class PeriodicalTasksCloser implements ProjectManagerListener, ProjectLif
   public void initComponent() {
   }
 
-  public boolean register(final Project project, final String name, final Runnable runnable) {
-    synchronized (myLock) {
-      if (project.isDisposed()) {
-        return false;
+  private static class Interrupter implements Disposable {
+    private final String myName;
+    private final Runnable myRunnable;
+
+    private Interrupter(@NotNull String name, @NotNull Runnable runnable) {
+      myName = name;
+      myRunnable = runnable;
+    }
+
+    @Override
+    public void dispose() {
+      final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
+      if (indicator != null) {
+        indicator.setText(myName);
+        indicator.checkCanceled();
       }
-      /*if (Boolean.FALSE.equals(myStates.get(project))) {
-        return false;
-      }*/
-      myInterrupters.putValue(project, new Pair<String, Runnable>(name, runnable));
-      return true;
+      myRunnable.run();
     }
   }
 
-  public void projectOpened(Project project) {
-    clearForTests();
-    /*clearForTests();
-
+  private static final Key<List<Interrupter>> INTERRUPTERS = Key.create("VCS_INTERRUPTERS");
+  public boolean register(@NotNull Project project, @NotNull String name, @NotNull Runnable runnable) {
     synchronized (myLock) {
-      myStates.put(project, TracedLifeCycle.OPEN);
-    }*/
-  }
-
-  public boolean canCloseProject(Project project) {
-    return true;
-  }
+      if (project.isDisposed()) {
+        return false;
+      }
 
-  private void clearForTests() {
-    if (ApplicationManager.getApplication().isUnitTestMode()) {
-      final Project[] projects = myProjectManager.getOpenProjects();
-      synchronized (myLock) {
-        myInterrupters.keySet().retainAll(Arrays.asList(projects));
+      Interrupter interrupter = new Interrupter(name, runnable);
+      List<Interrupter> list = project.getUserData(INTERRUPTERS);
+      if (list == null) {
+        list = new ArrayList<Interrupter>();
+        project.putUserData(INTERRUPTERS, list);
       }
+      list.add(interrupter);
+      Disposer.register(project, interrupter);
+
+      return true;
     }
   }
 
-  public void projectClosed(Project project) {
-    /*synchronized (myLock) {
-      myStates.remove(project);
-    }*/
+  public boolean canCloseProject(Project project) {
+    return true;
   }
 
   public void projectClosing(final Project project) {
-    /*synchronized (myLock) {
-      myStates.put(project, TracedLifeCycle.CLOSING);
-    }*/
-    final Collection<Pair<String, Runnable>> list;
+    final List<Interrupter> interrupters;
     synchronized (myLock) {
-      list = myInterrupters.remove(project);
+      List<Interrupter> list = project.getUserData(INTERRUPTERS);
+      if (list == null) {
+        interrupters = null;
+      }
+      else {
+        interrupters = new ArrayList<Interrupter>(list);
+        list.clear();
+      }
     }
-    if (list != null) {
+    if (interrupters != null) {
       ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
         public void run() {
-          final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
-          for (Pair<String, Runnable> pair : list) {
-            if (indicator != null) {
-              indicator.setText(pair.getFirst());
-              indicator.checkCanceled();
-            }
-            pair.getSecond().run();
+          for (Interrupter interrupter : interrupters) {
+            Disposer.dispose(interrupter);
           }
         }
       }, "Please wait for safe shutdown of periodical tasks...", true, project);
@@ -158,12 +148,6 @@ public class PeriodicalTasksCloser implements ProjectManagerListener, ProjectLif
 
   @Override
   public void beforeProjectLoaded(@NotNull Project project) {
-    clearForTests();
-    /*clearForTests();
-
-    synchronized (myLock) {
-      myStates.put(project, TracedLifeCycle.OPENING);
-    }*/
   }
 
   public <T> T safeGetComponent(@NotNull final Project project, final Class<T> componentClass) throws ProcessCanceledException {
@@ -204,10 +188,9 @@ public class PeriodicalTasksCloser implements ProjectManagerListener, ProjectLif
     throw new ProcessCanceledException();
   }
 
-  public void invokeAndWaitInterruptedWhenClosing(final Project project, final Runnable runnable, final ModalityState modalityState) {
-    final Ref<Boolean> start = new Ref<Boolean>(Boolean.TRUE);
-    final Application application = ApplicationManager.getApplication();
-    LOG.assertTrue(! application.isDispatchThread());
+  public void invokeAndWaitInterruptedWhenClosing(Project project, @NotNull final Runnable runnable, @NotNull ModalityState modalityState) {
+    final AtomicBoolean start = new AtomicBoolean(true);
+    LOG.assertTrue(!ApplicationManager.getApplication().isDispatchThread());
 
     final Semaphore semaphore = new Semaphore();
     semaphore.down();
@@ -228,9 +211,7 @@ public class PeriodicalTasksCloser implements ProjectManagerListener, ProjectLif
     };
     ApplicationManager.getApplication().invokeLater(runnable1, modalityState, new Condition<Object>() {
       public boolean value(Object o) {
-        synchronized (start) {
-          return ! start.get();
-        }
+        return !start.get();
       }
     });
 
@@ -238,19 +219,8 @@ public class PeriodicalTasksCloser implements ProjectManagerListener, ProjectLif
       if (semaphore.waitFor(1000)) {
         return;
       }
-      final Ref<Boolean> fire = new Ref<Boolean>();
-      if (project != null) {
-        synchronized (myLock) {
-          if (! project.isOpen()) {
-            fire.set(Boolean.TRUE);
-          }
-          if (Boolean.TRUE.equals(fire.get())) {
-            synchronized (start) {
-              start.set(Boolean.FALSE);
-              return;
-            }
-          }
-        }
+      if (project != null && !project.isOpen()) {
+        start.set(false);
       }
     }
   }
index 20ee31cb8f92436aed1717261ede2852f22123d8..ab60aa9b369936f36d9fb6bc070fbf6de0bea176 100644 (file)
@@ -22,28 +22,24 @@ import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.project.Project;
 import com.intellij.util.Consumer;
 import com.intellij.util.concurrency.Semaphore;
+import org.jetbrains.annotations.NotNull;
 
 /**
  * for restarted single threaded executor
  */
 public class ExecutorWrapper {
-  private final Project myProject;
-  private final String myName;
   private final Semaphore mySemaphore;
   private volatile boolean myDisposeStarted;
   private final Object myLock;
   private boolean myInProgress;
-  private final Runnable myStopper;
   private Thread myCurrentWorker;
   private final AtomicSectionsAware myAtomicSectionsAware;
 
-  protected ExecutorWrapper(final Project project, final String name) {
-    myProject = project;
-    myName = name;
+  protected ExecutorWrapper(@NotNull Project project, @NotNull String name) {
     myLock = new Object();
     mySemaphore = new Semaphore();
 
-    myStopper = new Runnable() {
+    Runnable stopper = new Runnable() {
       public void run() {
         synchronized (myLock) {
           myDisposeStarted = true;
@@ -71,7 +67,7 @@ public class ExecutorWrapper {
         return myDisposeStarted;
       }
     };
-    myDisposeStarted = ! PeriodicalTasksCloser.getInstance().register(project, myName, myStopper);
+    myDisposeStarted = ! PeriodicalTasksCloser.getInstance().register(project, name, stopper);
   }
 
   private void taskFinished() {
index ffe22fec545a85e4cc3e94b8ebe11a8b3a731127..89f9c0fc7f1c7f56db3fac26327400c6a821cee0 100644 (file)
 package com.intellij.cvsSupport2.cvsExecution;
 
 import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
 
 public interface ModalityContext {
-  void runInDispatchThread(Runnable action, Project project);
+  void runInDispatchThread(@NotNull Runnable action, Project project);
 
   boolean isForTemporaryConfiguration();
 }
index e87da4419767ae80075d0369d5e17cd0201b6cde..b38c00503f6327b69cca8fb229d1c9a8f54acb4f 100644 (file)
@@ -102,7 +102,7 @@ public class CvsOperationExecutor {
           myResult.addAllErrors(handler.getErrorsExceptAborted());
           myResult.addAllWarnings(handler.getWarnings());
           handler.runComplitingActivities();
-          if ((myProject == null) || (myProject != null && !myProject.isDisposed())) {
+          if (myProject == null || myProject != null && !myProject.isDisposed()) {
             showErrors(handler.getErrorsExceptAborted(), handler.getWarnings(), tabbedWindow);
           }
         }
@@ -118,7 +118,7 @@ public class CvsOperationExecutor {
           }
           finally {
 
-            if ((myProject != null) && (handler != CvsHandler.NULL)) {
+            if (myProject != null && handler != CvsHandler.NULL) {
               StatusBar.Info.set(getStatusMessage(handler), myProject);
             }
           }
@@ -194,7 +194,7 @@ public class CvsOperationExecutor {
   }
 
   private static boolean isInProgress() {
-    return (ProgressManager.getInstance().getProgressIndicator() != null);
+    return ProgressManager.getInstance().getProgressIndicator() != null;
   }
 
   protected void showErrors(final List<VcsException> errors, CvsTabbedWindow tabbedWindow) {
index 8af0d5c34b31994a4308c662362a30c5f592f480..85071fd427bda2dd7b818092e8b7912939e572eb 100644 (file)
@@ -22,6 +22,7 @@ import com.intellij.openapi.application.ModalityState;
 import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
 
 /**
  * author: lesya
@@ -40,7 +41,7 @@ public class ModalityContextImpl implements ModalityContext {
     myIsForTemporaryConfiguration = forTemp;
   }
 
-  public void runInDispatchThread(Runnable action, Project project) {
+  public void runInDispatchThread(@NotNull Runnable action, Project project) {
     Application application = ApplicationManager.getApplication();
     if (application.isUnitTestMode() || application.isDispatchThread()) {
       action.run();
index 5a203d92569b4c0a3672d10768edc41ff31a4c33..d8a95c75f45268f8b74061fd24b6a63551245907 100644 (file)
@@ -56,13 +56,13 @@ public class UpdateHandler extends CommandCvsHandler implements PostCvsActivity
   private final Collection<File> myNotProcessedRepositories = new HashSet<File>();
   private double myDirectoriesToBeProcessedCount;
 
-  private final static CvsMessagePattern UPDATE_PATTERN = new CvsMessagePattern(new String[]{"cvs server: Updating ", "*"}, 2);
+  private static final CvsMessagePattern UPDATE_PATTERN = new CvsMessagePattern(new String[]{"cvs server: Updating ", "*"}, 2);
   private final Project myProject;
   private final Collection<MergedWithConflictProjectOrModuleFile> myCorruptedFiles = new ArrayList<MergedWithConflictProjectOrModuleFile>();
   private final UpdatedFiles myUpdatedFiles;
   private final UpdateSettings myUpdateSettings;
 
-  public UpdateHandler(FilePath[] files, UpdateSettings updateSettings, Project project, @NotNull UpdatedFiles updatedFiles) {
+  public UpdateHandler(FilePath[] files, UpdateSettings updateSettings, @NotNull Project project, @NotNull UpdatedFiles updatedFiles) {
     super(CvsBundle.message("operation.name.update"), new UpdateOperation(new FilePath[0], updateSettings, project),
           FileSetToBeUpdated.selectedFiles(files));
     myFiles = files;
index f8cb4bdd368d77a4cff079485bb10e66ed12ba8e..51f114ffce7ed0c82347bb47e94610e087dcd278 100644 (file)
@@ -19,6 +19,7 @@ import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.PathManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.projectRoots.*;
+import com.intellij.openapi.roots.AnnotationOrderRootType;
 import com.intellij.openapi.roots.JavadocOrderRootType;
 import com.intellij.openapi.roots.OrderRootType;
 import com.intellij.openapi.ui.Messages;
@@ -510,6 +511,14 @@ public class IdeaJdk extends SdkType implements JavaSdkType {
     return SdkType.findInstance(IdeaJdk.class);
   }
 
+  @Override
+  public boolean isRootTypeApplicable(OrderRootType type) {
+    return type == OrderRootType.CLASSES ||
+           type == OrderRootType.SOURCES ||
+           type == JavadocOrderRootType.getInstance() ||
+           type == AnnotationOrderRootType.getInstance();
+  }
+
   enum JDKVersion {
 
     V1_4("1.4"), V1_5("1.5"), V1_6("1.6");
index 9ec3590d58ff5b235fdf11fac9c38684060c2e5b..a0491c94c4ce02fd2f976cf270f86d5ad9663db8 100644 (file)
@@ -127,6 +127,9 @@ public class IdeaJdkConfigurable implements AdditionalDataConfigurable {
         if (myFreeze) return;
         final Sdk javaJdk = (Sdk)e.getItem();
         for (OrderRootType type : OrderRootType.getAllTypes()) {
+          if (!javaJdk.getSdkType().isRootTypeApplicable(type)) {
+            continue;
+          }
           final VirtualFile[] internalRoots = javaJdk.getSdkModificator().getRoots(type);
           final VirtualFile[] configuredRoots = mySdkModificator.getRoots(type);
           for (VirtualFile file : internalRoots) {
index a00b504b9d27734b3d1e72fb6d9f7d6e963919f9..070f03402a7c2076d1878ab19616dbc9ceee1726 100644 (file)
@@ -1,7 +1,6 @@
 package org.jetbrains.plugins.github;
 
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ProjectRootManager;
 import com.intellij.openapi.startup.StartupManager;
 import com.intellij.openapi.vcs.VcsException;
 import com.intellij.openapi.vcs.checkout.CheckoutListener;
@@ -41,11 +40,7 @@ public class GithubCheckoutListener implements CheckoutListener {
 
   @Nullable
   private String getGithubProjectName(final Project project) {
-    final VirtualFile[] roots = ProjectRootManager.getInstance(project).getContentRoots();
-    if (roots.length == 0){
-      return null;
-    }
-    final VirtualFile root = roots[0];
+    final VirtualFile root = project.getBaseDir();
     // Check if git is already initialized and presence of remote branch
     final boolean gitDetected = GitUtil.isUnderGit(root);
     if (gitDetected) {
index c12da2f1be32eb1503c93b24513745dbca769fb6..9906e1c79e536a048680a22d3453d391cfc0d8b4 100644 (file)
@@ -21,7 +21,6 @@ import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ProjectRootManager;
 import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.IconLoader;
 import com.intellij.openapi.vcs.VcsException;
@@ -65,13 +64,7 @@ public class GithubOpenInBrowserAction extends DumbAwareAction {
   @Override
   public void actionPerformed(final AnActionEvent e) {
     final Project project = e.getData(PlatformDataKeys.PROJECT);
-
-    final VirtualFile[] roots = ProjectRootManager.getInstance(project).getContentRoots();
-    if (roots.length == 0) {
-      Messages.showErrorDialog(project, "Project doesn't have any project roots", CANNOT_OPEN_IN_BROWSER);
-      return;
-    }
-    final VirtualFile root = roots[0];
+    final VirtualFile root = project.getBaseDir();
     // Check if git is already initialized and presence of remote branch
     final boolean gitDetected = GitUtil.isUnderGit(root);
     if (!gitDetected) {
index e56dfe7a4cceb105a8f9a854d9f8507a4a3996b7..fcd862c08cc8545de98fad24b590562e0dd3e6d3 100644 (file)
@@ -21,7 +21,6 @@ import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ProjectRootManager;
 import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.IconLoader;
 import com.intellij.openapi.vcs.VcsException;
@@ -69,12 +68,7 @@ public class GithubRebaseAction extends DumbAwareAction {
   @Override
   public void actionPerformed(final AnActionEvent e) {
     final Project project = e.getData(PlatformDataKeys.PROJECT);
-    final VirtualFile[] roots = ProjectRootManager.getInstance(project).getContentRoots();
-    if (roots.length == 0) {
-      Messages.showErrorDialog(project, "Project doesn't have any project roots", CANNOT_PERFORM_GITHUB_REBASE);
-      return;
-    }
-    final VirtualFile root = roots[0];
+    final VirtualFile root = project.getBaseDir();
     // Check if git is already initialized and presence of remote branch
     final boolean gitDetected = GitUtil.isUnderGit(root);
     if (!gitDetected) {
index 8beb2959485c2f2e844d6e7a2552576ed8695490..a4c6a497a6f9afa9de0a7c341af35c0ba7e3c71c 100644 (file)
@@ -9,7 +9,6 @@ import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ProjectRootManager;
 import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.IconLoader;
@@ -61,12 +60,7 @@ public class GithubShareAction extends DumbAwareAction {
   @Override
   public void actionPerformed(final AnActionEvent e) {
     final Project project = e.getData(PlatformDataKeys.PROJECT);
-    final VirtualFile[] roots = ProjectRootManager.getInstance(project).getContentRoots();
-    if (roots.length == 0){
-      Messages.showErrorDialog(project, "Project doesn't have any project roots", "Cannot create new GitHub repository");
-      return;
-    }
-    final VirtualFile root = roots[0];
+    final VirtualFile root = project.getBaseDir();
     // Check if git is already initialized and presence of remote branch
     final boolean gitDetected = GitUtil.isUnderGit(root);
     if (gitDetected) {
index 45c2e8585af42663787658699a2181e180cca269..17a3249496bc69255bab0662d6918ccca4c70cde 100644 (file)
@@ -5,12 +5,12 @@ import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.progress.Task;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ProjectRootManager;
 import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.JDOMUtil;
 import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.vcs.VcsException;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.net.HttpConfigurable;
 import git4idea.GitRemote;
 import git4idea.GitUtil;
 import org.apache.commons.httpclient.HttpClient;
@@ -81,6 +81,15 @@ public class GithubUtil {
 
   public static HttpClient getHttpClient(final String login, final String password) {
     final HttpClient client = new HttpClient();
+    // Configure proxySettings if it is required
+    final HttpConfigurable proxySettings = HttpConfigurable.getInstance();
+    if (proxySettings.USE_HTTP_PROXY){
+      client.getHostConfiguration().setProxy(proxySettings.PROXY_HOST, proxySettings.PROXY_PORT);
+      if (proxySettings.PROXY_AUTHENTICATION) {
+        client.getState().setProxyCredentials(AuthScope.ANY, new UsernamePasswordCredentials(proxySettings.PROXY_LOGIN,
+                                                                                             proxySettings.getPlainProxyPassword()));
+      }
+    }
     client.getParams().setAuthenticationPreemptive(true);
     client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(login, password));
     return client;
@@ -244,11 +253,7 @@ public class GithubUtil {
 
   @Nullable
   public static GitRemote getGithubBoundRepository(final Project project){
-    final VirtualFile[] roots = ProjectRootManager.getInstance(project).getContentRoots();
-    if (roots.length == 0) {
-      return null;
-    }
-    final VirtualFile root = roots[0];
+    final VirtualFile root = project.getBaseDir();
     // Check if git is already initialized and presence of remote branch
     final boolean gitDetected = GitUtil.isUnderGit(root);
     if (!gitDetected) {
index 85c7259d098c926f690683987e1ac4a3b4fbdd7a..54c5e2a04d9223a137897fb6d7736b822c1f0ab6 100644 (file)
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.TailTypes;
 import com.intellij.codeInsight.completion.*;
 import com.intellij.codeInsight.lookup.LookupElement;
 import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.openapi.actionSystem.IdeActions;
 import com.intellij.openapi.editor.ex.EditorEx;
 import com.intellij.openapi.editor.highlighter.HighlighterIterator;
 import com.intellij.openapi.util.Iconable;
@@ -272,23 +273,6 @@ public class GroovyCompletionContributor extends CompletionContributor {
   }
 
   public GroovyCompletionContributor() {
-    extend(CompletionType.BASIC, psiElement(PsiElement.class), new CompletionProvider<CompletionParameters>() {
-      @Override
-      protected void addCompletions(@NotNull CompletionParameters parameters,
-                                    ProcessingContext context,
-                                    @NotNull final CompletionResultSet result) {
-        final PsiElement reference = parameters.getPosition().getParent();
-        if (reference instanceof GrReferenceElement) {
-          if (reference.getParent() instanceof GrImportStatement && ((GrReferenceElement)reference).getQualifier() != null) {
-            result.addElement(LookupElementBuilder.create("*"));
-          }
-
-          completeReference(parameters, result, (GrReferenceElement)reference);
-        }
-      }
-    });
-
-
     //provide 'this' and 'super' completions in ClassName.<caret>
     extend(CompletionType.BASIC, AFTER_DOT, new CompletionProvider<CompletionParameters>() {
       @Override
@@ -305,6 +289,15 @@ public class GroovyCompletionContributor extends CompletionContributor {
         GrReferenceExpression referenceExpression = (GrReferenceExpression)qualifier;
         final PsiElement resolved = referenceExpression.resolve();
         if (!(resolved instanceof PsiClass)) return;
+
+        if (CompletionService.getCompletionService().getAdvertisementText() == null && parameters.getInvocationCount() > 0 &&
+            CompletionUtil.shouldShowFeature(parameters, JavaCompletionFeatures.GLOBAL_MEMBER_NAME)) {
+          final String shortcut = getActionShortcut(IdeActions.ACTION_CLASS_NAME_COMPLETION);
+          if (shortcut != null) {
+            CompletionService.getCompletionService().setAdvertisementText("Pressing " + shortcut + " without a class qualifier would show all accessible static methods");
+          }
+        }
+
         if (!PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, position, false)) return;
 
         for (String keyword : THIS_SUPER) {
@@ -313,6 +306,23 @@ public class GroovyCompletionContributor extends CompletionContributor {
       }
     });
 
+    extend(CompletionType.BASIC, psiElement(PsiElement.class), new CompletionProvider<CompletionParameters>() {
+      @Override
+      protected void addCompletions(@NotNull CompletionParameters parameters,
+                                    ProcessingContext context,
+                                    @NotNull final CompletionResultSet result) {
+        final PsiElement reference = parameters.getPosition().getParent();
+        if (reference instanceof GrReferenceElement) {
+          if (reference.getParent() instanceof GrImportStatement && ((GrReferenceElement)reference).getQualifier() != null) {
+            result.addElement(LookupElementBuilder.create("*"));
+          }
+
+          completeReference(parameters, result, (GrReferenceElement)reference);
+        }
+      }
+    });
+
+
     extend(CompletionType.BASIC, TYPE_IN_VARIABLE_DECLARATION_AFTER_MODIFIER, new CompletionProvider<CompletionParameters>() {
       @Override
       protected void addCompletions(@NotNull CompletionParameters parameters,
@@ -525,8 +535,10 @@ public class GroovyCompletionContributor extends CompletionContributor {
   }
 
   private static void showInfo() {
-    CompletionService.getCompletionService()
-      .setAdvertisementText(GroovyBundle.message("invoke.completion.second.time.to.show.skipped.methods"));
+    if (StringUtil.isEmpty(CompletionService.getCompletionService().getAdvertisementText())) {
+      CompletionService.getCompletionService()
+        .setAdvertisementText(GroovyBundle.message("invoke.completion.second.time.to.show.skipped.methods"));
+    }
   }
 
   private static StaticMemberProcessor completeStaticMembers(PsiElement position) {
index ddcef70089184e42523006374235096b0ebc3b34..7d2d8ad5fa6066c2d1fc50eb5f8716228b7ca723 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.
@@ -27,8 +27,8 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.Separators;
 import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.*;
 import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.blocks.OpenOrClosableBlock;
 import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.declaration.Declaration;
+import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.AssignmentExpression;
 import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.ConditionalExpression;
-import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.ExpressionStatement;
 import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.StrictContextExpression;
 import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.imports.ImportStatement;
 import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.TypeDefinition;
@@ -449,7 +449,7 @@ public class GroovyParser implements PsiParser {
     }
     if (TypeDefinition.parse(builder, this)) return true;
 
-    return ExpressionStatement.parse(builder, this);
+    return AssignmentExpression.parse(builder, this, true);
 
   }
 
@@ -474,4 +474,4 @@ public class GroovyParser implements PsiParser {
     marker.done(GroovyElementTypes.LABELED_STATEMENT);
     return true;
   }
-}
\ No newline at end of file
+}
index 6bcc1da3d68cd50bcb06469006cbfa412c7865e6..4eca5760817ee8bb7fb3feb8b932129059fab507 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.
@@ -30,7 +30,7 @@ public class VariableInitializer implements GroovyElementTypes {
   public static void parse(PsiBuilder builder, GroovyParser parser) {
     if (ParserUtils.getToken(builder, mASSIGN)) {
       ParserUtils.getToken(builder, mNLS);
-      if (!AssignmentExpression.parse(builder, parser)) {
+      if (!AssignmentExpression.parse(builder, parser, true)) {
         builder.error(GroovyBundle.message("expression.expected"));
       }
     }
index fffbc76a7749c5966a49ba542bf6dc8e0d4828be..5d30e5953ca67ed46f31255e72289aee1e8fd85d 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.
@@ -119,7 +119,7 @@ public class SwitchStatement implements GroovyElementTypes {
     ParserUtils.getToken(builder, TokenSet.create(kCASE, kDEFAULT));
 
     if (kCASE.equals(elem)) {
-      AssignmentExpression.parse(builder, parser);
+      AssignmentExpression.parse(builder, parser, true);
     }
     ParserUtils.getToken(builder, mCOLON, GroovyBundle.message("colon.expected"));
     label.done(CASE_LABEL);
index 18db239213f2b272ac6ba9b624ec224b83c66e9a..73f04f469c008a952bc4381677978978ccec0ab2 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.
@@ -229,7 +229,7 @@ public class VariableDefinitions implements GroovyElementTypes {
       PsiBuilder.Marker marker = builder.mark();
       ParserUtils.getToken(builder, mNLS);
 
-      if (!AssignmentExpression.parse(builder, parser)) {
+      if (!AssignmentExpression.parse(builder, parser, true)) {
         marker.rollbackTo();
         builder.error(GroovyBundle.message("expression.expected"));
         return false;
index 00c10ba14f431ac879c7ca05648c2bc1008d99b2..f43fa6498d99b1f73e5510a937efef6d15fad83d 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.
@@ -41,29 +41,53 @@ public class AssignmentExpression implements GroovyElementTypes {
           mSL_ASSIGN,
           mBAND_ASSIGN,
           mBOR_ASSIGN,
-          mBXOR_ASSIGN,                                       
+          mBXOR_ASSIGN,
           mSTAR_STAR_ASSIGN,
           mSR_ASSIGN,
           mBSR_ASSIGN
   );
 
   public static boolean parse(PsiBuilder builder, GroovyParser parser) {
+    return parse(builder, parser, false);
+  }
+
+  public static boolean parse(PsiBuilder builder, GroovyParser parser, boolean comExprAllowed) {
     Marker marker = builder.mark();
     final boolean isTuple = ParserUtils.lookAhead(builder, mLPAREN, mIDENT, mCOMMA);
-    if (isTuple ? TupleParse.parseTuple(builder, TUPLE_EXPRESSION, REFERENCE_EXPRESSION) : ConditionalExpression.parse(builder, parser)) {
+    if (parseSide(builder, parser, isTuple,comExprAllowed)) {
       if (ParserUtils.getToken(builder, ASSIGNMENTS)) {
         ParserUtils.getToken(builder, mNLS);
-        if (!parse(builder, parser)) {
+        if (!parse(builder, parser, comExprAllowed)) {
           builder.error(GroovyBundle.message("expression.expected"));
         }
         marker.done(ASSIGNMENT_EXPRESSION);
-      } else {
+      }
+      else {
         marker.drop();
       }
       return true;
-    } else {
+    }
+    else {
       marker.drop();
       return false;
     }
   }
+
+  private static boolean parseSide(PsiBuilder builder, GroovyParser parser, boolean tuple, boolean comExprAllowed) {
+    if (tuple) {
+      return TupleParse.parseTuple(builder, TUPLE_EXPRESSION, REFERENCE_EXPRESSION);
+    }
+
+    if (comExprAllowed) {
+      Marker marker = builder.mark();
+      if (ExpressionStatement.parse(builder, parser)) {
+        marker.drop();
+        return true;
+      }
+      else {
+        marker.rollbackTo();
+      }
+    }
+    return ConditionalExpression.parse(builder, parser);
+  }
 }
index d27a76a616821cec5a7567c46cff8bbc8037de20..6fe5fb90a9ceda1c21cff4e0f376e11ad81814c5 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.
 
 package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions;
 
-import com.intellij.lang.LighterASTNode;
 import com.intellij.lang.PsiBuilder;
 import com.intellij.psi.tree.IElementType;
 import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.groovy.GroovyBundle;
 import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
 import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
 import org.jetbrains.plugins.groovy.lang.parser.GroovyParser;
+import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.blocks.OpenOrClosableBlock;
 import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.arguments.CommandArguments;
 import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.arithmetic.PathExpression;
+import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.arithmetic.UnaryExpressionNotPlusMinus;
 import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.primary.PrimaryExpression;
+import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils;
 
 /**
  * Main classdef for any general expression parsing
@@ -37,17 +38,28 @@ public class ExpressionStatement implements GroovyElementTypes {
 
   @Nullable
   private static IElementType parseExpressionStatement(PsiBuilder builder, GroovyParser parser) {
-    final LighterASTNode firstDoneMarker = builder.getLatestDoneMarker();
+    if (checkForTypeCast(builder, parser)) return CAST_EXPRESSION;
     PsiBuilder.Marker marker = builder.mark();
-    if (AssignmentExpression.parse(builder, parser) &&
+    final PathExpression.Result result = PathExpression.parseForExprStatement(builder, parser);
+    if (result != PathExpression.Result.WRONG_WAY &&
         !TokenSets.SEPARATORS.contains(builder.getTokenType()) &&
-        CommandArguments.parse(builder, parser)) {
-      marker.done(CALL_EXPRESSION);
-      return CALL_EXPRESSION;
+        !TokenSets.BINARY_OP_SET.contains(builder.getTokenType()) &&
+        !TokenSets.UNARY_OP_SET.contains(builder.getTokenType())) {
+      if (result == PathExpression.Result.CALL_WITH_CLOSURE) {
+        marker.drop();
+        return PATH_METHOD_CALL;
+      }
+      else if (CommandArguments.parse(builder, parser)) {
+        marker.done(CALL_EXPRESSION);
+        return CALL_EXPRESSION;
+      }
     }
     marker.drop();
-    final LighterASTNode latestDoneMarker = builder.getLatestDoneMarker();
-    return latestDoneMarker != null && firstDoneMarker != latestDoneMarker ? latestDoneMarker.getTokenType() : WRONGWAY;
+    return WRONGWAY;
+  }
+
+  private static boolean checkForTypeCast(PsiBuilder builder, GroovyParser parser) {
+    return UnaryExpressionNotPlusMinus.parse(builder, parser, false);
   }
 
   /**
@@ -64,7 +76,7 @@ public class ExpressionStatement implements GroovyElementTypes {
     PsiBuilder.Marker marker = builder.mark();
 
     final IElementType result = parseExpressionStatement(builder, parser);
-    if (result != CALL_EXPRESSION) {
+    if (result != CALL_EXPRESSION && result != PATH_METHOD_CALL) {
       marker.drop();
       return result != WRONGWAY;
     }
@@ -74,19 +86,36 @@ public class ExpressionStatement implements GroovyElementTypes {
         marker.drop();
         break;
       }
-      final PsiBuilder.Marker exprStatement = marker.precede();
+      PsiBuilder.Marker exprStatement = marker.precede();
       marker.done(REFERENCE_EXPRESSION);
 
       if (builder.getTokenType() == mLPAREN) {
         PrimaryExpression.methodCallArgsParse(builder, parser);
         exprStatement.done(PATH_METHOD_CALL);
       }
+      else if (mLBRACK.equals(builder.getTokenType()) &&
+               !ParserUtils.lookAhead(builder, mLBRACK, mCOLON) &&
+               !ParserUtils.lookAhead(builder, mLBRACK, mNLS, mCOLON)) {
+        PathExpression.indexPropertyArgsParse(builder, parser);
+        exprStatement.done(PATH_INDEX_PROPERTY);
+        if (mLPAREN.equals(builder.getTokenType())) {
+          PrimaryExpression.methodCallArgsParse(builder, parser);
+        }
+        else if (mLCURLY.equals(builder.getTokenType())) {
+          PsiBuilder.Marker argsMarker = builder.mark();
+          argsMarker.done(ARGUMENTS);
+        }
+        while (mLCURLY.equals(builder.getTokenType())) {
+          OpenOrClosableBlock.parseClosableBlock(builder, parser);
+        }
+        exprStatement = exprStatement.precede();
+        exprStatement.done(PATH_METHOD_CALL);
+      }
       else if (CommandArguments.parse(builder, parser)) {
         exprStatement.done(CALL_EXPRESSION);
       }
       else {
         exprStatement.drop();
-        builder.error(GroovyBundle.message("expression.expected"));
         break;
       }
 
index d125235f15031b31aedbe0ca2955fa6f45607316..41cd35bedd62e6b191311c048e960b47142f6a6c 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.
@@ -53,6 +53,7 @@ public class CommandArguments implements GroovyElementTypes {
     PsiBuilder.Marker commandMarker = builder.mark();
     if (ArgumentList.argumentLabelStartCheck(builder, parser)) {
       ParserUtils.getToken(builder, mCOLON, GroovyBundle.message("colon.expected"));
+      ParserUtils.getToken(builder, mNLS);
       if (!ExpressionStatement.argParse(builder, parser)) {
         commandMarker.error(GroovyBundle.message("expression.expected"));
       }
@@ -66,4 +67,4 @@ public class CommandArguments implements GroovyElementTypes {
       return ExpressionStatement.argParse(builder, parser);
     }
   }
-}
\ No newline at end of file
+}
index 47b153d77a0612e96c92737c0f341a9755ae58ed..57409390ec7e74139b5e313149c27bf129738a27 100644 (file)
@@ -31,33 +31,42 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.p
 import org.jetbrains.plugins.groovy.lang.parser.parsing.types.TypeArguments;
 import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils;
 
+import static org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.arithmetic.PathExpression.Result.*;
+
 /**
  * @author ilyas
  */
 public class PathExpression implements GroovyElementTypes {
 
   public static boolean parse(PsiBuilder builder, GroovyParser parser) {
+    return parseForExprStatement(builder, parser) != PathExpression.Result.WRONG_WAY;
+  }
 
+  public enum Result{OK, WRONG_WAY, CALL_WITH_CLOSURE}
+
+  public static Result parseForExprStatement(PsiBuilder builder, GroovyParser parser) {
     PsiBuilder.Marker marker = builder.mark();
     final GroovyElementType qualifierType = PrimaryExpression.parse(builder, parser);
     if (qualifierType != WRONGWAY) {
+      Result result = OK;
       if (isPathElementStart(builder)) {
         PsiBuilder.Marker newMarker = marker.precede();
         marker.drop();
-        if (mLCURLY.equals(builder.getTokenType())) {
+        final boolean lCurly = mLCURLY.equals(builder.getTokenType());
+        if (lCurly) {
           PsiBuilder.Marker argsMarker = builder.mark();
           argsMarker.done(ARGUMENTS);
         }
-        pathElementParse(builder, newMarker, parser, qualifierType);
+        result = pathElementParse(builder, newMarker, parser, qualifierType, lCurly?CALL_WITH_CLOSURE:OK);
       }
       else {
         marker.drop();
       }
-      return true;
+      return result;
     }
     else {
       marker.drop();
-      return false;
+      return WRONG_WAY;
     }
   }
 
@@ -71,8 +80,11 @@ public class PathExpression implements GroovyElementTypes {
 
   private static final TokenSet DOTS = TokenSet.create(mSPREAD_DOT, mOPTIONAL_DOT, mMEMBER_POINTER, mDOT);
 
-  private static GroovyElementType pathElementParse(PsiBuilder builder, PsiBuilder.Marker marker, GroovyParser parser,
-                                                    GroovyElementType qualifierType) {
+  private static Result pathElementParse(PsiBuilder builder,
+                                                    PsiBuilder.Marker marker,
+                                                    GroovyParser parser,
+                                                    GroovyElementType qualifierType,
+                                                    Result result) {
 
     GroovyElementType res;
 
@@ -100,7 +112,7 @@ public class PathExpression implements GroovyElementTypes {
           PsiBuilder.Marker argsMarker = builder.mark();
           argsMarker.done(ARGUMENTS);
         }
-        pathElementParse(builder, newMarker, parser, res);
+        result = pathElementParse(builder, newMarker, parser, res, OK);
       }
       else {
         builder.error(GroovyBundle.message("path.selector.expected"));
@@ -111,41 +123,46 @@ public class PathExpression implements GroovyElementTypes {
       PrimaryExpression.methodCallArgsParse(builder, parser);
       if (mLCURLY.equals(builder.getTokenType()) || ParserUtils.lookAhead(builder, mNLS, mLCURLY)) {
         ParserUtils.getToken(builder, mNLS);
-        pathElementParse(builder, marker, parser, qualifierType);
+        result = pathElementParse(builder, marker, parser, qualifierType, OK);
       }
       else {
         PsiBuilder.Marker newMarker = marker.precede();
         marker.done(PATH_METHOD_CALL);
-        pathElementParse(builder, newMarker, parser, qualifierType);
+        result = pathElementParse(builder, newMarker, parser, qualifierType, OK);
       }
     }
     else if (mLCURLY.equals(builder.getTokenType())) {
       appendedBlockParse(builder, parser);
       if (mLCURLY.equals(builder.getTokenType())) {
-        pathElementParse(builder, marker, parser, qualifierType);
+        result = pathElementParse(builder, marker, parser, qualifierType, result);
       }
       else {
         PsiBuilder.Marker newMarker = marker.precede();
         marker.done(PATH_METHOD_CALL);
-        pathElementParse(builder, newMarker, parser, PATH_METHOD_CALL);
+        result = pathElementParse(builder, newMarker, parser, PATH_METHOD_CALL, result);
       }
     }
-    else if (mLBRACK.equals(builder.getTokenType()) &&
-             !ParserUtils.lookAhead(builder, mLBRACK, mCOLON) &&
-             !ParserUtils.lookAhead(builder, mLBRACK, mNLS, mCOLON)) {
+    else if (checkForArrayAccess(builder)) {
       indexPropertyArgsParse(builder, parser);
       PsiBuilder.Marker newMarker = marker.precede();
       marker.done(PATH_INDEX_PROPERTY);
-      if (mLCURLY.equals(builder.getTokenType())) {
+      final boolean lCurly = mLCURLY.equals(builder.getTokenType());
+      if (lCurly) {
         PsiBuilder.Marker argsMarker = builder.mark();
         argsMarker.done(ARGUMENTS);
       }
-      pathElementParse(builder, newMarker, parser, PATH_INDEX_PROPERTY);
+      result = pathElementParse(builder, newMarker, parser, PATH_INDEX_PROPERTY, lCurly?CALL_WITH_CLOSURE : OK);
     }
     else {
       marker.drop();
     }
-    return PATH_EXPRESSION;
+    return result;
+  }
+
+  public static boolean checkForArrayAccess(PsiBuilder builder) {
+    return mLBRACK.equals(builder.getTokenType()) &&
+           !ParserUtils.lookAhead(builder, mLBRACK, mCOLON) &&
+           !ParserUtils.lookAhead(builder, mLBRACK, mNLS, mCOLON);
   }
 
   private static GroovyElementType parseThisSuperExpression(PsiBuilder builder, GroovyElementType qualifierType) {
@@ -221,7 +238,7 @@ public class PathExpression implements GroovyElementTypes {
    * @param builder
    * @return
    */
-  private static GroovyElementType indexPropertyArgsParse(PsiBuilder builder, GroovyParser parser) {
+  public static GroovyElementType indexPropertyArgsParse(PsiBuilder builder, GroovyParser parser) {
     assert mLBRACK.equals(builder.getTokenType());
 
     PsiBuilder.Marker marker = builder.mark();
index 7a4846e047c483b0974069bba904d328453965d2..989cd873d211ac486fd94c4db06c0a0873ee1ffb 100644 (file)
@@ -33,6 +33,10 @@ import static org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDe
 public class UnaryExpressionNotPlusMinus implements GroovyElementTypes {
 
   public static boolean parse(PsiBuilder builder, GroovyParser parser) {
+    return parse(builder, parser, true);
+  }
+
+  public static boolean parse(PsiBuilder builder, GroovyParser parser, boolean runPostfixIfFail) {
     PsiBuilder.Marker marker = builder.mark();
     if (builder.getTokenType() == mLPAREN) {
       final ReferenceElement.ReferenceElementResult result = parseTypeCast(builder);
@@ -42,18 +46,22 @@ public class UnaryExpressionNotPlusMinus implements GroovyElementTypes {
           return true;
         } else {
           marker.rollbackTo();
-          return PostfixExpression.parse(builder, parser);
+          return runPostfix(builder, parser, runPostfixIfFail);
         }
       } else {
         marker.drop();
-        return PostfixExpression.parse(builder, parser);
+        return runPostfix(builder, parser, runPostfixIfFail);
       }
     } else {
       marker.drop();
-      return PostfixExpression.parse(builder, parser);
+      return runPostfix(builder, parser, runPostfixIfFail);
     }
   }
 
+  private static boolean runPostfix(PsiBuilder builder, GroovyParser parser, boolean runPostfixIfFail) {
+    return runPostfixIfFail ? PostfixExpression.parse(builder, parser) : false;
+  }
+
   private static ReferenceElement.ReferenceElementResult parseTypeCast(PsiBuilder builder) {
     PsiBuilder.Marker marker = builder.mark();
     if (!ParserUtils.getToken(builder, mLPAREN, GroovyBundle.message("lparen.expected"))) {
@@ -78,4 +86,4 @@ public class UnaryExpressionNotPlusMinus implements GroovyElementTypes {
       return fail;
     }
   }
-}
\ No newline at end of file
+}
index c6aab0ee20c49466b8c3ef32238dd1a74a5fab8c..d5c3c30655b3daa5f1916fcebee7a4b1ed8f400e 100644 (file)
@@ -7,11 +7,12 @@ import com.intellij.util.containers.hash.HashMap;
 import com.intellij.util.containers.hash.HashSet;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.arithmetic.GrRangeExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
 import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
 import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
@@ -77,14 +78,15 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer {
   @Override
   @Nullable
   protected PsiType getClosureParameterType(GrClosableBlock closure, int index) {
-    final PsiElement parent = closure.getParent();
-    if (!(parent instanceof GrMethodCallExpression)) {
+    PsiElement parent = closure.getParent();
+    if (parent instanceof GrArgumentList) parent = parent.getParent();
+    if (!(parent instanceof GrMethodCall)) {
       return null;
     }
     PsiElementFactory factory = JavaPsiFacade.getInstance(closure.getProject()).getElementFactory();
-    String methodName = findMethodName((GrMethodCallExpression)parent);
+    String methodName = findMethodName((GrMethodCall)parent);
 
-    GrExpression expression = ((GrMethodCallExpression)parent).getInvokedExpression();
+    GrExpression expression = ((GrMethodCall)parent).getInvokedExpression();
     if (!(expression instanceof GrReferenceExpression)) return null;
     final PsiElement resolved = ((GrReferenceExpression)expression).resolve();
     if (!(resolved instanceof GrGdkMethod)) return null;
@@ -174,7 +176,7 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer {
       }
     }
     else if ("withStream".equals(methodName)) {
-      final PsiMethod method = ((GrMethodCallExpression)parent).resolveMethod();
+      final PsiMethod method = ((GrMethodCall)parent).resolveMethod();
       if (method != null) {
         final PsiParameter[] parameters = method.getParameterList().getParameters();
         if (parameters.length > 0) {
@@ -266,7 +268,7 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer {
   }
 
   @Nullable
-  private static String findMethodName(@NotNull GrMethodCallExpression methodCall) {
+  private static String findMethodName(@NotNull GrMethodCall methodCall) {
     GrExpression expression = methodCall.getInvokedExpression();
     if (expression instanceof GrReferenceExpression) {
       return ((GrReferenceExpression)expression).getReferenceName();
index f2e589e4c94048bf7a8802c09464abbbbf803d2f..b344b283ecc8b8e98d496a72ea082473c7064cb7 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.
@@ -25,6 +25,7 @@ import com.intellij.util.containers.HashSet;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
 
 import java.util.ArrayList;
@@ -77,13 +78,13 @@ public class CollectClassMembersUtil {
         Map<String, List<CandidateInfo>> allMethods = new HashMap<String, List<CandidateInfo>>();
         Map<String, CandidateInfo> allInnerClasses = new HashMap<String, CandidateInfo>();
 
-        processClass(aClass, allFields, allMethods, allInnerClasses, new HashSet<PsiClass>(), PsiSubstitutor.EMPTY, includeSynthetic);
+        processClass(aClass, allFields, allMethods, allInnerClasses, new HashSet<PsiClass>(), PsiSubstitutor.EMPTY, includeSynthetic, true);
         return Result.create(Trinity.create(allFields, allMethods, allInnerClasses), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
       }
     }, false);
   }
 
-  private static void processClass(PsiClass aClass, Map<String, CandidateInfo> allFields, Map<String, List<CandidateInfo>> allMethods, Map<String, CandidateInfo> allInnerClasses, Set<PsiClass> visitedClasses, PsiSubstitutor substitutor, boolean includeSynthetic) {
+  private static void processClass(PsiClass aClass, Map<String, CandidateInfo> allFields, Map<String, List<CandidateInfo>> allMethods, Map<String, CandidateInfo> allInnerClasses, Set<PsiClass> visitedClasses, PsiSubstitutor substitutor, boolean includeSynthetic, boolean shouldProcessInnerClasses) {
     if (visitedClasses.contains(aClass)) return;
     visitedClasses.add(aClass);
 
@@ -107,10 +108,12 @@ public class CollectClassMembersUtil {
       addMethod(allMethods, method, substitutor);
     }
 
-    for (final PsiClass inner : aClass.getInnerClasses()) {
-      final String name = inner.getName();
-      if (name != null && !allInnerClasses.containsKey(name)) {
-        allInnerClasses.put(name, new CandidateInfo(inner, substitutor));
+    if (shouldProcessInnerClasses) {
+      for (final PsiClass inner : aClass.getInnerClasses()) {
+        final String name = inner.getName();
+        if (name != null && !allInnerClasses.containsKey(name)) {
+          allInnerClasses.put(name, new CandidateInfo(inner, substitutor));
+        }
       }
     }
 
@@ -118,7 +121,8 @@ public class CollectClassMembersUtil {
       PsiClass superClass = superType.resolve();
       if (superClass != null) {
         final PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, substitutor);
-        processClass(superClass, allFields, allMethods, allInnerClasses, visitedClasses, superSubstitutor, includeSynthetic);
+        processClass(superClass, allFields, allMethods, allInnerClasses, visitedClasses, superSubstitutor, includeSynthetic,
+                     shouldProcessInnerClasses && !(aClass instanceof GrAnonymousClassDefinition));
       }
     }
   }
index aa830adfd79f34f3df44cae559675200f3caff26..934be86330314cbf0adeaea053fa9d93782f2530 100644 (file)
@@ -193,7 +193,8 @@ public abstract class GroovyRefactoringUtil {
     return tempContainer instanceof GrOpenBlock ||
         tempContainer instanceof GrClosableBlock ||
         tempContainer instanceof GroovyFileBase ||
-        tempContainer instanceof GrCaseSection || tempContainer instanceof GrLoopStatement;
+        tempContainer instanceof GrCaseSection ||
+        tempContainer instanceof GrLoopStatement;
   }
 
   public static void sortOccurrences(PsiElement[] occurences) {
index 8eae59f56d3ac5e9ce34438556203751364d3278..3e9bb1f0cb46c3ac72a2fde4487521d20393ddf9 100644 (file)
@@ -160,7 +160,10 @@ public class GroovyVariableValidator implements GroovyIntroduceVariableBase.Vali
                                                     double startOffset) {
     PsiElement prevSibling = startElement.getPrevSibling();
     while (prevSibling != null) {
-      validateVariableOccurrencesDown(prevSibling, conflicts, varName, startOffset);
+      if (!(GroovyRefactoringUtil.isAppropriateContainerForIntroduceVariable(prevSibling) &&
+            prevSibling.getTextRange().getEndOffset() < startOffset)) {
+        validateVariableOccurrencesDown(prevSibling, conflicts, varName, startOffset);
+      }
       prevSibling = prevSibling.getPrevSibling();
     }
 
index d0291b81b1e3ebac1f5c1d3799085126a526f58e..504f149c18b7aebbd7abf1f9b2b449310a88b8dc 100644 (file)
@@ -1,6 +1,17 @@
 /*
- * Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
- * Use is subject to license terms.
+ * 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 org.jetbrains.plugins.groovy.lang.parser
 
@@ -230,10 +241,16 @@ public class ExpressionsParsingTest extends GroovyParsingTestCase {
   public void testcommandExpr$fourArgs() {doTest()}
   public void testcommandExpr$fiveArgs() {doTest()}
   public void testcommandExpr$multiArgs() {doTest()}
+  public void testcommandExpr$RHS() {doTest()}
+  public void testcommandExpr$oddArgCount() {doTest()}
+  public void testcommandExpr$indexAccess1() {doTest()}
+  public void testcommandExpr$indexAccess2() {doTest()}
+  public void testcommandExpr$indexAccess3() {doTest()}
+  public void testcommandExpr$closureArg2() {doTest()}
   /*def testCommandExpr$() {doTest()}
   def testCommandExpr$() {doTest()}
   def testCommandExpr$() {doTest()}
   def testCommandExpr$() {doTest()}
   def testCommandExpr$() {doTest()}*/
 
-}
\ No newline at end of file
+}
index bd72f1f144a9f79c3a5f75db751415f62100e7c4..360c3ad494ab8f9811e6fcfaabc41bad19711e9c 100644 (file)
@@ -1,17 +1,17 @@
 /*
- *  Copyright 2000-2007 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
+ * Copyright 2000-2010 JetBrains s.r.o.
  *
- *  http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  *
- *  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.
+ * 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 org.jetbrains.plugins.groovy.lang.resolve;
 
@@ -183,6 +183,32 @@ class X {
     doTest()
   }
 
+  public void testInnerClassIsNotResolvedInAnonymous() {
+    myFixture.addFileToProject "/p/Super.groovy", """
+package p
+
+interface Super {
+  class Inner {
+  }
+
+  def foo(Inner i);
+}"""
+    assertNull resolve("A.groovy");
+  }
+
+  public void testInnerClassIsResolvedInAnonymous() {
+    myFixture.addFileToProject "/p/Super.groovy", """
+package p
+
+interface Super {
+  class Inner {
+  }
+
+  def foo(Inner i);
+}"""
+    assertInstanceOf resolve("A.groovy"), PsiClass;
+  }
+
   private void doTest() {
     doTest(getTestName(true) + "/" + getTestName(false) + ".groovy");
   }
index 8288a7c0032be86d972ea677085d5f042d390a92..ca69d543bba89d70d73f3e3f2ca384a9e4826550 100644 (file)
@@ -1,17 +1,17 @@
 /*
- *  Copyright 2000-2007 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
+ * Copyright 2000-2010 JetBrains s.r.o.
  *
- *  http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  *
- *  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.
+ * 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 org.jetbrains.plugins.groovy.lang.resolve;
 
@@ -626,4 +626,9 @@ set<caret>Foo(2)
     final GroovyResolveResult result = advancedResolve("A.groovy")
     assertFalse result.staticsOK
   }
+
+  public void testPropertyInExprStatement() {
+    def result = resolve("A.groovy")
+    assertInstanceOf result, GrAccessorMethod
+  }
 }
\ No newline at end of file
index 9beead2250ef727d29795aa4a72eb50cf43d66bb..43efa91103abdfa5c626f613ba4f3f3d40df754e 100644 (file)
@@ -39,7 +39,7 @@ public class SmartEnterTest extends LightCodeInsightFixtureTestCase {
   public void testGotoNextLineInFor() throws Throwable { doTest(); }
   public void testGotoParentInIf() throws Throwable { doTest(); }
 
-  public void _testListFixer() throws Throwable {doTest();}
+  public void testListFixer() throws Throwable {doTest();}
 
   protected static List<SmartEnterProcessor> getSmartProcessors(Language grLanguage) {
     return SmartEnterProcessors.INSTANCE.forKey(grLanguage);
index 54e0cde2b919650e15624ed9440c937455dcf837..3a365236df9a572be737dface5e769fa21bbf3c1 100644 (file)
@@ -17,19 +17,15 @@ package org.jetbrains.plugins.groovy.refactoring.introduceVariable;
 
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.util.InvalidDataException;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiType;
 import com.intellij.psi.impl.source.PostprocessReformattingAspect;
 import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
-import com.intellij.util.IncorrectOperationException;
 import junit.framework.Assert;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.groovy.GroovyFileType;
 import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
 import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
 import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
 import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
@@ -39,7 +35,6 @@ import org.jetbrains.plugins.groovy.refactoring.introduce.variable.GroovyIntrodu
 import org.jetbrains.plugins.groovy.refactoring.introduce.variable.GroovyIntroduceVariableSettings;
 import org.jetbrains.plugins.groovy.util.TestUtils;
 
-import java.io.IOException;
 import java.util.List;
 
 /**
@@ -74,6 +69,7 @@ public class IntroduceVariableTest extends LightCodeInsightFixtureTestCase {
   public void testLoop6() throws Throwable { doTest(); }
   public void testLoop7() throws Throwable { doTest(); }
   public void testLoop8() throws Throwable { doTest(); }
+  public void testInCase() {doTest();}
 
   public void testDuplicatesInsideIf() throws Throwable { doTest(); }
   public void testFromGString() throws Throwable { doTest(); }
@@ -84,8 +80,8 @@ public class IntroduceVariableTest extends LightCodeInsightFixtureTestCase {
 
   protected boolean replaceAllOccurences = false;
 
-  private String processFile(String fileText, boolean explicitType) throws IncorrectOperationException, InvalidDataException, IOException {
-    String result = "";
+  private String processFile(String fileText, boolean explicitType) {
+    String result;
     int startOffset = fileText.indexOf(TestUtils.BEGIN_MARKER);
     if (startOffset < 0) {
       startOffset = fileText.indexOf(ALL_MARKER);
@@ -161,12 +157,12 @@ public class IntroduceVariableTest extends LightCodeInsightFixtureTestCase {
     return result;
   }
 
-  public void doTest(boolean explicitType) throws Exception {
+  public void doTest(boolean explicitType) {
     final List<String> data = TestUtils.readInput(getTestDataPath() + getTestName(true) + ".test");
     assertEquals(data.get(1), processFile(data.get(0), explicitType));
   }
 
-  public void doTest() throws Exception {
+  public void doTest() {
     doTest(false);
   }
 
diff --git a/plugins/groovy/testdata/groovy/actions/smartEnter/listFixer.test b/plugins/groovy/testdata/groovy/actions/smartEnter/listFixer.test
new file mode 100644 (file)
index 0000000..e47e42d
--- /dev/null
@@ -0,0 +1,6 @@
+def foo = ["abc<caret>
+]
+-----
+def foo = ["abc",
+        <caret>
+]
index 9e06c1e06a0e034b76e2f8bd8bfbec313d1eacb2..bfbaa5076bc85264bd3f3c1de9cda55819552a92 100644 (file)
@@ -1,4 +1,5 @@
 boolean a = b in<caret> D
 -----
 in
-instanceof
\ No newline at end of file
+instanceof
+int
diff --git a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/inCase.test b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/inCase.test
new file mode 100644 (file)
index 0000000..31480e8
--- /dev/null
@@ -0,0 +1,16 @@
+switch (e) {
+  case 1:
+    int preved = 4
+    break;
+  case 2:
+    print <begin>5<end>
+}
+-----
+switch (e) {
+  case 1:
+    int preved = 4
+    break;
+  case 2:
+    def preved = 5
+  print preved<caret>
+}
\ No newline at end of file
diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/RHS.test b/plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/RHS.test
new file mode 100644 (file)
index 0000000..fe40d51
--- /dev/null
@@ -0,0 +1,27 @@
+def r2 = drink coffee with sugar
+-----
+Groovy script
+  Variable definitions
+    Modifiers
+      PsiElement(def)('def')
+    PsiWhiteSpace(' ')
+    Variable
+      PsiElement(identifier)('r2')
+      PsiWhiteSpace(' ')
+      PsiElement(=)('=')
+      PsiWhiteSpace(' ')
+      Call expression
+        Reference expression
+          Call expression
+            Reference expression
+              PsiElement(identifier)('drink')
+            PsiWhiteSpace(' ')
+            Command arguments
+              Reference expression
+                PsiElement(identifier)('coffee')
+          PsiWhiteSpace(' ')
+          PsiElement(identifier)('with')
+        PsiWhiteSpace(' ')
+        Command arguments
+          Reference expression
+            PsiElement(identifier)('sugar')
diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/closureArg2.test b/plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/closureArg2.test
new file mode 100644 (file)
index 0000000..d16cd93
--- /dev/null
@@ -0,0 +1,24 @@
+foo {a} bar "x"
+-----
+Groovy script
+  Call expression
+    Reference expression
+      Method call
+        Reference expression
+          PsiElement(identifier)('foo')
+        PsiWhiteSpace(' ')
+        Arguments
+          <empty list>
+        Closable block
+          PsiElement({)('{')
+          Parameter list
+            <empty list>
+          Reference expression
+            PsiElement(identifier)('a')
+          PsiElement(})('}')
+      PsiWhiteSpace(' ')
+      PsiElement(identifier)('bar')
+    PsiWhiteSpace(' ')
+    Command arguments
+      Literal
+        PsiElement(Gstring)('"x"')
index 7b959a644c8532fb69585efb33a5e6b4bba046ef..41604b27ba2366cd249be0fde8ba48f8dde8a6f9 100644 (file)
@@ -18,6 +18,4 @@ Groovy script
         Reference expression
           PsiElement(identifier)('a3')
     PsiWhiteSpace(' ')
-    PsiElement(identifier)('a4')
-  PsiErrorElement:Expression expected
-    <empty list>
\ No newline at end of file
+    PsiElement(identifier)('a4')
\ No newline at end of file
diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/indexAccess1.test b/plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/indexAccess1.test
new file mode 100644 (file)
index 0000000..c2303cc
--- /dev/null
@@ -0,0 +1,36 @@
+foo a1 a2[1](){} a3 a4
+-----
+Groovy script
+  Call expression
+    Reference expression
+      Method call
+        Property by index
+          Reference expression
+            Call expression
+              Reference expression
+                PsiElement(identifier)('foo')
+              PsiWhiteSpace(' ')
+              Command arguments
+                Reference expression
+                  PsiElement(identifier)('a1')
+            PsiWhiteSpace(' ')
+            PsiElement(identifier)('a2')
+          Arguments
+            PsiElement([)('[')
+            Literal
+              PsiElement(Integer)('1')
+            PsiElement(])(']')
+        Arguments
+          PsiElement(()('(')
+          PsiElement())(')')
+        Closable block
+          PsiElement({)('{')
+          Parameter list
+            <empty list>
+          PsiElement(})('}')
+      PsiWhiteSpace(' ')
+      PsiElement(identifier)('a3')
+    PsiWhiteSpace(' ')
+    Command arguments
+      Reference expression
+        PsiElement(identifier)('a4')
diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/indexAccess2.test b/plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/indexAccess2.test
new file mode 100644 (file)
index 0000000..0563f8f
--- /dev/null
@@ -0,0 +1,35 @@
+foo a1 a2[1]{} a3 a4
+-----
+Groovy script
+  Call expression
+    Reference expression
+      Method call
+        Property by index
+          Reference expression
+            Call expression
+              Reference expression
+                PsiElement(identifier)('foo')
+              PsiWhiteSpace(' ')
+              Command arguments
+                Reference expression
+                  PsiElement(identifier)('a1')
+            PsiWhiteSpace(' ')
+            PsiElement(identifier)('a2')
+          Arguments
+            PsiElement([)('[')
+            Literal
+              PsiElement(Integer)('1')
+            PsiElement(])(']')
+        Arguments
+          <empty list>
+        Closable block
+          PsiElement({)('{')
+          Parameter list
+            <empty list>
+          PsiElement(})('}')
+      PsiWhiteSpace(' ')
+      PsiElement(identifier)('a3')
+    PsiWhiteSpace(' ')
+    Command arguments
+      Reference expression
+        PsiElement(identifier)('a4')
diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/indexAccess3.test b/plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/indexAccess3.test
new file mode 100644 (file)
index 0000000..042a26a
--- /dev/null
@@ -0,0 +1,41 @@
+foo a1 a2[1](){}{} a3 a4
+------
+Groovy script
+  Call expression
+    Reference expression
+      Method call
+        Property by index
+          Reference expression
+            Call expression
+              Reference expression
+                PsiElement(identifier)('foo')
+              PsiWhiteSpace(' ')
+              Command arguments
+                Reference expression
+                  PsiElement(identifier)('a1')
+            PsiWhiteSpace(' ')
+            PsiElement(identifier)('a2')
+          Arguments
+            PsiElement([)('[')
+            Literal
+              PsiElement(Integer)('1')
+            PsiElement(])(']')
+        Arguments
+          PsiElement(()('(')
+          PsiElement())(')')
+        Closable block
+          PsiElement({)('{')
+          Parameter list
+            <empty list>
+          PsiElement(})('}')
+        Closable block
+          PsiElement({)('{')
+          Parameter list
+            <empty list>
+          PsiElement(})('}')
+      PsiWhiteSpace(' ')
+      PsiElement(identifier)('a3')
+    PsiWhiteSpace(' ')
+    Command arguments
+      Reference expression
+        PsiElement(identifier)('a4')
\ No newline at end of file
diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/oddArgCount.test b/plugins/groovy/testdata/parsing/groovy/expressions/commandExpr/oddArgCount.test
new file mode 100644 (file)
index 0000000..4222e52
--- /dev/null
@@ -0,0 +1,16 @@
+a.foo s field
+------
+Groovy script
+  Reference expression
+    Call expression
+      Reference expression
+        Reference expression
+          PsiElement(identifier)('a')
+        PsiElement(.)('.')
+        PsiElement(identifier)('foo')
+      PsiWhiteSpace(' ')
+      Command arguments
+        Reference expression
+          PsiElement(identifier)('s')
+    PsiWhiteSpace(' ')
+    PsiElement(identifier)('field')
index 8f4992702e0ed25dcf940c3f6bdbeaa85c6d15b6..8d05b1c1f8e817f38cb3b971abd64e8cd153774c 100644 (file)
@@ -18,15 +18,16 @@ Groovy script
       Case label
         PsiElement(case)('case')
         PsiWhiteSpace(' ')
-        Literal
-          PsiElement(Integer)('1')
+        Call expression
+          Literal
+            PsiElement(Integer)('1')
+          PsiWhiteSpace(' ')
+          Command arguments
+            Reference expression
+              PsiElement(identifier)('expr1')
         PsiErrorElement:':' expected
           <empty list>
-      PsiWhiteSpace(' ')
-      Reference expression
-        PsiElement(identifier)('expr1')
       PsiElement(new line)('\n')
-    Case section
       Case label
         PsiElement(default)('default')
         PsiElement(:)(':')
@@ -39,4 +40,4 @@ Groovy script
           Literal
             PsiElement(string)(''abc'')
       PsiElement(new line)('\n')
-    PsiElement(})('}')
\ No newline at end of file
+    PsiElement(})('}')
diff --git a/plugins/groovy/testdata/resolve/class/innerClassIsNotResolvedInAnonymous/A.groovy b/plugins/groovy/testdata/resolve/class/innerClassIsNotResolvedInAnonymous/A.groovy
new file mode 100644 (file)
index 0000000..7708be9
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+import p.Super
+
+def an = new Super() {
+  def foo(Inn<ref>er i) {
+
+  }
+}
\ No newline at end of file
diff --git a/plugins/groovy/testdata/resolve/class/innerClassIsResolvedInAnonymous/A.groovy b/plugins/groovy/testdata/resolve/class/innerClassIsResolvedInAnonymous/A.groovy
new file mode 100644 (file)
index 0000000..b6b5865
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+import p.Super
+import p.Super.Inner
+def an = new Super() {
+  def foo(Inn<ref>er i) {
+
+  }
+}
\ No newline at end of file
diff --git a/plugins/groovy/testdata/resolve/property/propertyInExprStatement/A.groovy b/plugins/groovy/testdata/resolve/property/propertyInExprStatement/A.groovy
new file mode 100644 (file)
index 0000000..1004949
--- /dev/null
@@ -0,0 +1,10 @@
+class X {
+  def prop
+
+  def foo(def arg) {
+    return this
+  }
+
+}
+
+new X().foo "a" pro<ref>p
index 68da5c966a0ae63a77bb3bd6525e3e81d2be4c5f..6ea6824522c41035546c2223179e501b449a71ea 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.ModalityState;
 import com.intellij.openapi.progress.EmptyProgressIndicator;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.idea.svn.SvnVcs;
 import org.jetbrains.idea.svn.dialogs.RepositoryTreeNode;
 import org.tmatesoft.svn.core.ISVNDirEntryHandler;
@@ -87,6 +88,7 @@ class RepositoryLoader extends Loader {
       @Override
       public void run() {
         ProgressManager.getInstance().runProcess(new LoadTask(data), new EmptyProgressIndicator() {
+          @NotNull
           @Override
           public ModalityState getModalityState() {
             return state;
index 2a9d24e6322699f4722dcefc9c49a6d64559a703..ecdc5647bc32868939d75069b176324fffc9974d 100644 (file)
Binary files a/plugins/testng/lib/testng-jdk15.jar and b/plugins/testng/lib/testng-jdk15.jar differ
index ec877f611a5721b326a3b1ffecf55855e25de4fa..d049dd790065b25e9a984b2bccc51e72dbc6c799 100644 (file)
@@ -168,7 +168,7 @@ public class SearchingForTestsTask extends Task.Backgroundable {
 
   private void logCantRunException(CantRunException e) {
     try {
-      final String message = "CantRunException" + e.getMessage();
+      final String message = "CantRunException" + e.getMessage() + "\n";
       FileUtil.writeToFile(myTempFile, message.getBytes());
     }
     catch (IOException e1) {
index 7c233fd179da712fe937aa63158ef70a5bf4a0bc..ace75292c2d421dfedafe96e961a19a4f378aecb 100644 (file)
@@ -162,7 +162,7 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
 
   public String getStatusLine() {
     StringBuffer sb = new StringBuffer();
-    if (end == 0) {
+    if (end == 0 && start > 0) {
       sb.append("Running: ");
     }
     else {
@@ -328,7 +328,9 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
 
   public void finish() {
     if (end > 0) return;
-    end = System.currentTimeMillis();
+    if (start > 0) {
+      end = System.currentTimeMillis();
+    }
     LvcsHelper.addLabel(this);
 
     SwingUtilities.invokeLater(new Runnable() {
index cacef83771c2e9b657ab24e3888ad59f67f29fe1..aee5801c3a1c1284b04e46e6eefbbaab7bf2759f 100644 (file)
       <dependency id="editing.completion.smarttype.general"/>
       </feature>
     <feature
-      id="editing.completion.import.static"
+      id="editing.completion.global.member.name"
       tip-file="CompletionImportStatic.html"
       min-usage-count="8"
       first-show="10"
index be2e678c9e4631d19142e0143d268994c2bafbe0..31951e84cf8002e8a50f9870abd7e9211eedf31e 100644 (file)
@@ -87,23 +87,27 @@ public class PhysicalDomParentStrategy implements DomParentStrategy {
         //todo remove this assertion before X release
         final PsiElement nav1 = myElement.getNavigationElement();
         final PsiElement nav2 = thatElement.getNavigationElement();
-        if (ApplicationManagerEx.getApplicationEx().isInternal() && nav1 != nav2) {
-          PsiElement cur = findIncluder(myElement);
-          PsiElement nav = findIncluder(nav1);
-          throw new AssertionError(myElement.getText() + "; including=" + (cur == null ? null : cur.getText()) + "; nav=" + (nav == null ? null : nav.getText()));
+        if (nav1 != nav2) {
+          if (ApplicationManagerEx.getApplicationEx().isInternal()) {
+            PsiElement cur = findIncluder(myElement);
+            PsiElement nav = findIncluder(nav1);
+            final PsiElement _nav1 = myElement.getNavigationElement();
+            final PsiElement _nav2 = thatElement.getNavigationElement();
+            throw new AssertionError(myElement.getText() + "; including=" + (cur == null ? null : cur.getText()) + "; nav=" + (nav == null ? null : nav.getText()));
+          }
+
+          throw new AssertionError(nav1.getContainingFile() +
+                                ":" +
+                                nav1.getTextRange().getStartOffset() +
+                                "!=" +
+                                nav2.getContainingFile() +
+                                ":" +
+                                nav2.getTextRange().getStartOffset() +
+