diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index a299bba3bb1c..9586c74ecb05 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -77,6 +77,7 @@ import com.intellij.packaging.artifacts.ArtifactManager; import com.intellij.packaging.impl.artifacts.ArtifactImpl; import com.intellij.packaging.impl.artifacts.ArtifactUtil; import com.intellij.packaging.impl.compiler.ArtifactCompileScope; +import com.intellij.packaging.impl.compiler.ArtifactCompilerUtil; import com.intellij.pom.Navigatable; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.PsiDocumentManager; @@ -2474,6 +2475,7 @@ public class CompileDriver { } } } + affectedOutputPaths.addAll(ArtifactCompilerUtil.getArtifactOutputsContainingSourceFiles(myProject)); if (!affectedOutputPaths.isEmpty()) { final StringBuilder paths = new StringBuilder(); diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerUtil.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerUtil.java index f512c68e7a0b..6915ae2e3379 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerUtil.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerUtil.java @@ -18,14 +18,32 @@ package com.intellij.packaging.impl.compiler; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.compiler.CompilerMessageCategory; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.packaging.artifacts.Artifact; +import com.intellij.packaging.artifacts.ArtifactManager; +import com.intellij.packaging.elements.ComplexPackagingElement; +import com.intellij.packaging.elements.PackagingElement; +import com.intellij.packaging.elements.PackagingElementResolvingContext; +import com.intellij.packaging.impl.artifacts.ArtifactUtil; +import com.intellij.packaging.impl.artifacts.PackagingElementPath; +import com.intellij.packaging.impl.artifacts.PackagingElementProcessor; +import com.intellij.packaging.impl.elements.ArtifactPackagingElement; +import com.intellij.packaging.impl.elements.FileOrDirectoryCopyPackagingElement; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -65,4 +83,40 @@ public class ArtifactCompilerUtil { String fullPath = jarEntry.getPath(); return new File(FileUtil.toSystemDependentName(fullPath.substring(fullPath.indexOf(JarFileSystem.JAR_SEPARATOR)))); } + + + @NotNull + public static Set getArtifactOutputsContainingSourceFiles(final @NotNull Project project) { + final List allOutputs = new ArrayList(); + for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) { + ContainerUtil.addIfNotNull(artifact.getOutputFile(), allOutputs); + } + + final Set affectedOutputPaths = new HashSet(); + final PackagingElementResolvingContext context = ArtifactManager.getInstance(project).getResolvingContext(); + for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) { + ArtifactUtil.processPackagingElements(artifact, null, new PackagingElementProcessor>() { + @Override + public boolean shouldProcessSubstitution(ComplexPackagingElement element) { + return !(element instanceof ArtifactPackagingElement); + } + + @Override + public boolean process(@NotNull PackagingElement element, @NotNull PackagingElementPath path) { + if (element instanceof FileOrDirectoryCopyPackagingElement) { + final VirtualFile file = ((FileOrDirectoryCopyPackagingElement)element).findFile(); + if (file != null) { + for (VirtualFile output : allOutputs) { + if (VfsUtilCore.isAncestor(output, file, false)) { + affectedOutputPaths.add(output); + } + } + } + } + return true; + } + }, context, true); + } + return affectedOutputPaths; + } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java index 0e8f314847b5..0dbb2f44ac76 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -730,16 +730,9 @@ public class JavaCompletionUtil { if (psiClass.isValid() && !psiClass.getManager().areElementsEquivalent(psiClass, resolveReference(ref))) { final boolean staticImport = ref instanceof PsiImportStaticReferenceElement; - CodeEditUtil.setAllowSuspendNodesReformatting(true); - PsiElement newElement; - try { - newElement = staticImport - ? ((PsiImportStaticReferenceElement)ref).bindToTargetClass(psiClass) - : ref.bindToElement(psiClass); - } - finally { - CodeEditUtil.setAllowSuspendNodesReformatting(false); - } + PsiElement newElement = staticImport + ? ((PsiImportStaticReferenceElement)ref).bindToTargetClass(psiClass) + : ref.bindToElement(psiClass); newElement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(newElement); if (newElement != null) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaAnnotationElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaAnnotationElementType.java index 90eab205435b..962e371793b3 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaAnnotationElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaAnnotationElementType.java @@ -48,12 +48,12 @@ public class JavaAnnotationElementType extends JavaStubElementType extends StubBasedPsiElementBase implements StubBasedPsiElement { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.JavaStubPsiElement"); - public JavaStubPsiElement(final T stub, IStubElementType nodeType) { + public JavaStubPsiElement(@NotNull T stub, @NotNull IStubElementType nodeType) { super(stub, nodeType); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java index 38ff553b541d..ac27a012a2a9 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java @@ -44,11 +44,11 @@ public class PsiParameterImpl extends JavaStubPsiElement imple private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiParameterImpl"); private volatile PatchedSoftReference myCachedType = null; - public PsiParameterImpl(final PsiParameterStub stub) { + public PsiParameterImpl(@NotNull PsiParameterStub stub) { super(stub, JavaStubElementTypes.PARAMETER); } - public PsiParameterImpl(final ASTNode node) { + public PsiParameterImpl(@NotNull ASTNode node) { super(node); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterListImpl.java index b224bac150d7..687c19f90dfe 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterListImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterListImpl.java @@ -31,11 +31,11 @@ import org.jetbrains.annotations.NotNull; public class PsiParameterListImpl extends JavaStubPsiElement implements PsiParameterList { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiParameterListImpl"); - public PsiParameterListImpl(final PsiParameterListStub stub) { + public PsiParameterListImpl(@NotNull PsiParameterListStub stub) { super(stub, JavaStubElementTypes.PARAMETER_LIST); } - public PsiParameterListImpl(final ASTNode node) { + public PsiParameterListImpl(@NotNull ASTNode node) { super(node); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterElement.java index c373753f96ae..0d3aeac52c66 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterElement.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterElement.java @@ -18,7 +18,6 @@ package com.intellij.psi.impl.source.tree.java; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.JavaTokenType; -import com.intellij.psi.impl.source.Constants; import com.intellij.psi.impl.source.tree.ChildRole; import com.intellij.psi.impl.source.tree.CompositeElement; import com.intellij.psi.impl.source.tree.JavaElementType; @@ -29,7 +28,7 @@ public class ParameterElement extends CompositeElement{ private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ParameterElement"); public ParameterElement() { - super(Constants.PARAMETER); + super(JavaElementType.PARAMETER); } protected ParameterElement(IElementType type) { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy index b691004f3053..d05310987c1a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -621,7 +621,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase { public void testSpacesAroundEq() throws Throwable { doTest('='); } - public void testClassBeforeCast() throws Throwable { doTest '\n' } + public void _testClassBeforeCast() throws Throwable { doTest '\n' } public void testNoAllClassesOnQualifiedReference() throws Throwable { configureByFile(getTestName(false) + ".java"); diff --git a/platform/core-api/src/com/intellij/psi/stubs/IStubElementType.java b/platform/core-api/src/com/intellij/psi/stubs/IStubElementType.java index e698723506e7..a03fb0c5f9b8 100644 --- a/platform/core-api/src/com/intellij/psi/stubs/IStubElementType.java +++ b/platform/core-api/src/com/intellij/psi/stubs/IStubElementType.java @@ -32,9 +32,9 @@ public abstract class IStubElementType *
  • This method is called with 'false' argument;
  • *
  • Document is processed at dedicated 'try' block;
  • - *
  • This method is called with 'false' argument from 'finally' section;
  • + *
  • This method is called with 'true' argument from 'finally' section;
  • * */ diff --git a/platform/lang-api/src/com/intellij/psi/stubs/EmptyStubElementType.java b/platform/lang-api/src/com/intellij/psi/stubs/EmptyStubElementType.java index 15d0b7d7d84d..89195d017325 100644 --- a/platform/lang-api/src/com/intellij/psi/stubs/EmptyStubElementType.java +++ b/platform/lang-api/src/com/intellij/psi/stubs/EmptyStubElementType.java @@ -17,7 +17,7 @@ public abstract class EmptyStubElementType extends IStubEl } @Override - public final EmptyStub createStub(T psi, StubElement parentStub) { + public final EmptyStub createStub(@NotNull T psi, StubElement parentStub) { return createStub(parentStub); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/generation/surroundWith/SurroundWithHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/generation/surroundWith/SurroundWithHandler.java index 7b57fa44d292..91972927595b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/generation/surroundWith/SurroundWithHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/generation/surroundWith/SurroundWithHandler.java @@ -118,6 +118,7 @@ public class SurroundWithHandler implements CodeInsightActionHandler { final PsiElement[] elements = descriptor.getElementsToSurround(file, startOffset, endOffset); if (elements.length > 0) { for (PsiElement element : elements) { + assert element != null : "descriptor " + descriptor + " returned null element"; assert element.isValid() : descriptor; } for (Surrounder s: descriptor.getSurrounders()) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EndHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EndHandler.java index 419d88935ad3..4ed85cc4e528 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EndHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EndHandler.java @@ -36,6 +36,7 @@ public class EndHandler extends EditorActionHandler { return; } + lookup.markSelectionTouched(); ListScrollingUtil.moveEnd(lookup.getList()); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/HomeHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/HomeHandler.java index a8699b9454c8..3e742eb90e94 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/HomeHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/HomeHandler.java @@ -36,6 +36,7 @@ public class HomeHandler extends EditorActionHandler { return; } + lookup.markSelectionTouched(); ListScrollingUtil.moveHome(lookup.getList()); } } diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java index 1d20e51a57e2..ba8cd9f2fbdd 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java @@ -95,7 +95,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo private static final int FLUSH_DELAY = 200; //TODO : make it an option - private static final Key CONSOLE_VIEW_IN_EDITOR_VIEW = Key.create("CONSOLE_VIEW_IN_EDITOR_VIEW"); + public static final Key CONSOLE_VIEW_IN_EDITOR_VIEW = Key.create("CONSOLE_VIEW_IN_EDITOR_VIEW"); static { final EditorActionManager actionManager = EditorActionManager.getInstance(); diff --git a/platform/lang-impl/src/com/intellij/indentation/IndentationParser.java b/platform/lang-impl/src/com/intellij/indentation/IndentationParser.java index 76b41402461d..7edfc9f94405 100644 --- a/platform/lang-impl/src/com/intellij/indentation/IndentationParser.java +++ b/platform/lang-impl/src/com/intellij/indentation/IndentationParser.java @@ -79,7 +79,7 @@ public abstract class IndentationParser implements PsiParser { currentIndent = 0; } } - builder.advanceLexer(); + advanceLexer(builder); } // Close all left opened markers @@ -90,10 +90,20 @@ public abstract class IndentationParser implements PsiParser { stack.pop().second.done(myBlockElementType); } + return buildTree(fileMarker, builder, root); + } + + protected ASTNode buildTree(final PsiBuilder.Marker fileMarker, + final PsiBuilder builder, + final IElementType root) { fileMarker.done(root); return builder.getTreeBuilt(); } + protected void advanceLexer(PsiBuilder builder) { + builder.advanceLexer(); + } + private void passEOLsAndIndents(final PsiBuilder builder) { IElementType tokenType = builder.getTokenType(); while (tokenType == myEolTokenType || tokenType == myIndentTokenType){ diff --git a/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java b/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java index 51e387171e96..58aa34bdc7f7 100644 --- a/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java @@ -20,10 +20,13 @@ package com.intellij.ui; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.impl.ProjectLifecycleListener; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.Function; import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.MessageBusConnection; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.util.HashMap; @@ -42,6 +45,12 @@ public class IconDeferrerImpl extends IconDeferrer { clear(); } }); + connection.subscribe(ProjectLifecycleListener.TOPIC, new ProjectLifecycleListener.Adapter() { + @Override + public void afterProjectClosed(@NotNull Project project) { + clear(); + } + }); } private void clear() { diff --git a/platform/platform-api/src/com/intellij/util/ui/UpDownHandler.java b/platform/lang-impl/src/com/intellij/util/ui/UpDownHandler.java similarity index 66% rename from platform/platform-api/src/com/intellij/util/ui/UpDownHandler.java rename to platform/lang-impl/src/com/intellij/util/ui/UpDownHandler.java index 6a2b94d393f5..a05102599a44 100644 --- a/platform/platform-api/src/com/intellij/util/ui/UpDownHandler.java +++ b/platform/lang-impl/src/com/intellij/util/ui/UpDownHandler.java @@ -15,10 +15,14 @@ */ package com.intellij.util.ui; +import com.intellij.codeInsight.lookup.LookupEx; +import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CustomShortcutSet; +import com.intellij.openapi.editor.impl.EditorComponentImpl; +import com.intellij.ui.EditorTextField; import javax.swing.*; @@ -36,22 +40,12 @@ public class UpDownHandler { register(input, affectedComponent, true); } - public static void register(JComponent input, final JComponent affectedComponent, boolean registerOnBothComponents) { + public static void register(final JComponent input, final JComponent affectedComponent, boolean registerOnBothComponents) { final SelectionMover mover = new SelectionMover(affectedComponent); - final AnAction up = new AnAction("Up") { - @Override - public void actionPerformed(AnActionEvent e) { - mover.move(-1); - } - }; + final AnAction up = new UpDownAction(mover, input, true); up.registerCustomShortcutSet(UP_KEY, input); - - final AnAction down = new AnAction("Down") { - @Override - public void actionPerformed(AnActionEvent e) { - mover.move(1); - } - }; + + final AnAction down = new UpDownAction(mover, input, false); down.registerCustomShortcutSet(DOWN_KEY, input); if (registerOnBothComponents) { up.registerCustomShortcutSet(UP_KEY, affectedComponent); @@ -103,4 +97,36 @@ public class UpDownHandler { } } } + + static class UpDownAction extends AnAction { + private final int myDirection; + private final SelectionMover myMover; + private final JComponent myInput; + + UpDownAction(SelectionMover mover, JComponent input, boolean isUp) { + super(isUp ? "Up" : "Down"); + myMover = mover; + myInput = input; + myDirection = isUp ? -1 : 1; + } + + @Override + public void actionPerformed(AnActionEvent e) { + myMover.move(myDirection); + } + + @Override + public void update(AnActionEvent e) { + final LookupEx lookup; + if (myInput instanceof EditorTextField) { + lookup = LookupManager.getActiveLookup(((EditorTextField)myInput).getEditor()); + } else if (myInput instanceof EditorComponentImpl) { + lookup = LookupManager.getActiveLookup(((EditorComponentImpl)myInput).getEditor()); + } else { + lookup = null; + } + + e.getPresentation().setEnabled(lookup == null); + } + } } diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java index 15bcc6c4ab7e..92faf0983a2b 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java @@ -53,7 +53,12 @@ public class JBEditorTabs extends JBTabsImpl { super.paintLastGhost(g2d); } } - + + @Override + public boolean isTabDraggingEnabled() { + return super.isTabDraggingEnabled() && isSingleRow(); + } + public boolean isGhostsAlwaysVisible() { return super.isGhostsAlwaysVisible() && !isEditorTabs(); } @@ -71,7 +76,7 @@ public class JBEditorTabs extends JBTabsImpl { int _height = effectiveBounds.height - insets.top - insets.bottom; - if ((!isSingleRow() && label.getBounds().y > 0 /* for multiline */) || (isSingleRow() && isHorizontalTabs())) { + if ((!isSingleRow() /* for multiline */) || (isSingleRow() && isHorizontalTabs())) { if (isSingleRow() && getPosition() == JBTabsPosition.bottom) { _y += TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT; } else { diff --git a/platform/platform-impl/src/com/intellij/ide/ClipboardSynchronizer.java b/platform/platform-impl/src/com/intellij/ide/ClipboardSynchronizer.java index 47bdc4769a07..117815929b75 100644 --- a/platform/platform-impl/src/com/intellij/ide/ClipboardSynchronizer.java +++ b/platform/platform-impl/src/com/intellij/ide/ClipboardSynchronizer.java @@ -25,12 +25,15 @@ import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.registry.Registry; import com.intellij.ui.mac.foundation.Foundation; import com.intellij.ui.mac.foundation.ID; +import com.intellij.ui.mac.foundation.MacUtil; +import com.sun.jna.Callback; import com.sun.jna.IntegerType; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import sun.awt.datatransfer.DataTransferer; +import javax.swing.*; import java.awt.*; import java.awt.datatransfer.*; import java.io.IOException; @@ -180,8 +183,31 @@ public class ClipboardSynchronizer implements ApplicationComponent { private static class MacClipboardHandler extends ClipboardHandler { + private static final String CLIPBOARD_CONTENTS = "CLIPBOARD_CONTENTS"; private Pair myFullTransferable; + private static Callback myClipboardQueryCallback = new Callback() { + public void callback(ID self, String selector, ID params) { + JRootPane pane = getRootPane(); + if (pane != null) { + Transferable transferable = getClipboardContentNatively(); + if (transferable != null) { + pane.putClientProperty(CLIPBOARD_CONTENTS, transferable); + } + } + } + }; + + static { + if (SystemInfo.isMac) { + final ID delegateClass = Foundation.allocateObjcClassPair(Foundation.getClass("NSObject"), "ClipboardSynchronizer_"); + if (!Foundation.addMethod(delegateClass, Foundation.createSelector("run:"), myClipboardQueryCallback, "v*")) { + throw new RuntimeException("Unable to add method to objective-c delegate class!"); + } + Foundation.registerObjcClassPair(delegateClass); + } + } + @Nullable private Transferable doGetContents() throws IllegalStateException { if (Registry.is("ide.mac.useNativeClipboard")) { @@ -247,43 +273,45 @@ public class ClipboardSynchronizer implements ApplicationComponent { super.setContent(content, owner); } } + + @Nullable + private static JRootPane getRootPane() { + Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); + if (window == null) return null; + return SwingUtilities.getRootPane(window); + } + @Nullable public static Transferable getContentsSafe() { + if (Registry.is("ide.mac.useNativeClipboard.async")) { + JRootPane pane = getRootPane(); + if (pane != null) { + ID synchronizer_ = Foundation.getClass("ClipboardSynchronizer_"); + final ID synchronizer = Foundation.invoke(Foundation.invoke(synchronizer_, "alloc"), "init"); + Foundation + .invoke(synchronizer, "performSelectorOnMainThread:withObject:waitUntilDone:", Foundation.createSelector("run:"), null, false); + + MacUtil.startModal(pane); + + Foundation.cfRelease(synchronizer); + + Object contents = pane.getClientProperty(CLIPBOARD_CONTENTS); + pane.putClientProperty(CLIPBOARD_CONTENTS, null); + if (contents != null) { + return (Transferable) contents; + } + + return null; + } + } + final Ref result = new Ref(); Foundation.executeOnMainThread(new Runnable() { @Override public void run() { - String plainText = "public.utf8-plain-text"; - String jvmObject = "application/x-java-jvm"; - - ID pasteboard = Foundation.invoke("NSPasteboard", "generalPasteboard"); - ID types = Foundation.invoke(pasteboard, "types"); - IntegerType count = Foundation.invoke(types, "count"); - - ID plainTextType = null; - - for (int i = 0; i < count.intValue(); i++) { - ID each = Foundation.invoke(types, "objectAtIndex:", i); - String eachType = Foundation.toStringViaUTF8(each); - if (plainText.equals(eachType)) { - plainTextType = each; - break; - } - } - - // will put string value even if we doesn't found java object. this is needed because java caches clipboard value internally and - // will reset it ONLY IF we'll put jvm-object into clipboard (see our setContent optimizations which avoids putting jvm-objects - // into clipboard) - - if (plainTextType != null) { - ID text = Foundation.invoke(pasteboard, "stringForType:", plainTextType); - String value = Foundation.toStringViaUTF8(text); - if (value == null) { - LOG.info(String.format("[Clipboard] Strange string value (null?) for type: %s", plainTextType)); - } - else { - result.set(new StringSelection(value)); - } + Transferable transferable = getClipboardContentNatively(); + if (transferable != null) { + result.set(transferable); } } }, true, true); @@ -291,6 +319,45 @@ public class ClipboardSynchronizer implements ApplicationComponent { return result.get(); } } + + @Nullable + private static Transferable getClipboardContentNatively() { + String plainText = "public.utf8-plain-text"; + String jvmObject = "application/x-java-jvm"; + + ID pasteboard = Foundation.invoke("NSPasteboard", "generalPasteboard"); + ID types = Foundation.invoke(pasteboard, "types"); + IntegerType count = Foundation.invoke(types, "count"); + + ID plainTextType = null; + + for (int i = 0; i < count.intValue(); i++) { + ID each = Foundation.invoke(types, "objectAtIndex:", i); + String eachType = Foundation.toStringViaUTF8(each); + if (plainText.equals(eachType)) { + plainTextType = each; + break; + } + } + + // will put string value even if we doesn't found java object. this is needed because java caches clipboard value internally and + // will reset it ONLY IF we'll put jvm-object into clipboard (see our setContent optimizations which avoids putting jvm-objects + // into clipboard) + + Transferable result = null; + if (plainTextType != null) { + ID text = Foundation.invoke(pasteboard, "stringForType:", plainTextType); + String value = Foundation.toStringViaUTF8(text); + if (value == null) { + LOG.info(String.format("[Clipboard] Strange string value (null?) for type: %s", plainTextType)); + } + else { + result = new StringSelection(value); + } + } + + return result; + } private static class LinuxClipboardHandler extends ClipboardHandler { private static final FlavorTable FLAVOR_MAP = (FlavorTable)SystemFlavorMap.getDefaultFlavorMap(); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index e0a2c305e1a0..0378c3835c03 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -809,7 +809,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myPanel.addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { - myMarkupModel.repaint(0, myDocument.getTextLength()); + myMarkupModel.recalcEditorDimensions(); + myMarkupModel.repaint(-1, -1); } }); } @@ -1570,7 +1571,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myEditorComponent.setSize(dim); myEditorComponent.fireResized(); - myMarkupModel.repaint(0, myDocument.getTextLength()); + myMarkupModel.recalcEditorDimensions(); + myMarkupModel.repaint(-1, -1); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java index e9610b3edf8a..af3064934e2d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java @@ -112,7 +112,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark return myMinMarkHeight; } - private void recalcEditorDimensions() { + void recalcEditorDimensions() { EditorImpl.MyScrollBar scrollBar = myEditor.getVerticalScrollBar(); int scrollBarHeight = scrollBar.getSize().height; @@ -751,10 +751,10 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark LOG.assertTrue(success); } - public void markDirtied(@NotNull ProperTextRange pos) { - int start = Math.max(0, pos.getStartOffset() - myEditor.getLineHeight()); - int end = myEditorScrollbarTop + myEditorTargetHeight == 0 ? pos.getEndOffset() + myEditor.getLineHeight() - : Math.min(myEditorScrollbarTop + myEditorTargetHeight, pos.getEndOffset() + myEditor.getLineHeight()); + public void markDirtied(@NotNull ProperTextRange yPositions) { + int start = Math.max(0, yPositions.getStartOffset() - myEditor.getLineHeight()); + int end = myEditorScrollbarTop + myEditorTargetHeight == 0 ? yPositions.getEndOffset() + myEditor.getLineHeight() + : Math.min(myEditorScrollbarTop + myEditorTargetHeight, yPositions.getEndOffset() + myEditor.getLineHeight()); ProperTextRange adj = new ProperTextRange(start, Math.max(end, start)); if (myDirtyYPositions == null) { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java index f779b2b28be4..567503997d9b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java @@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileSystemUtil; import com.intellij.openapi.util.io.FileUtil; @@ -175,6 +176,8 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap private WatchRequest[] normalizeRootsForRefresh() { if (myCachedNormalizedRequests != null) return myCachedNormalizedRequests; List result = new ArrayList(); + + // No need to call for a read action here since we're only called with it on hands already. WRITE_LOCK.lock(); try { NextRoot: @@ -338,37 +341,43 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap } @Override - public WatchRequest addRootToWatch(@NotNull String rootPath, boolean toWatchRecursively) { + public WatchRequest addRootToWatch(@NotNull final String rootPath, final boolean toWatchRecursively) { if (rootPath.length() == 0 || !FileWatcher.getInstance().isOperational()) return null; - WRITE_LOCK.lock(); - try { - final WatchRequestImpl result = new WatchRequestImpl(rootPath, toWatchRecursively); - boolean alreadyWatched = isAlreadyWatched(result); - if (!alreadyWatched) { - final VirtualFile existingFile = findFileByPathIfCached(rootPath); - if (existingFile != null) { - final ModalityState modalityState = ModalityState.defaultModalityState(); - RefreshQueue.getInstance().refresh(true, toWatchRecursively, null, modalityState, existingFile); - if (existingFile.isDirectory() && !toWatchRecursively && existingFile instanceof NewVirtualFile) { - for (VirtualFile child : ((NewVirtualFile)existingFile).getCachedChildren()) { - RefreshQueue.getInstance().refresh(true, false, null, modalityState, child); + Application app = ApplicationManager.getApplication(); + return app.runReadAction(new Computable() { + @Override + public WatchRequest compute() { + WRITE_LOCK.lock(); + try { + final WatchRequestImpl result = new WatchRequestImpl(rootPath, toWatchRecursively); + boolean alreadyWatched = isAlreadyWatched(result); + if (!alreadyWatched) { + final VirtualFile existingFile = findFileByPathIfCached(rootPath); + if (existingFile != null) { + final ModalityState modalityState = ModalityState.defaultModalityState(); + RefreshQueue.getInstance().refresh(true, toWatchRecursively, null, modalityState, existingFile); + if (existingFile.isDirectory() && !toWatchRecursively && existingFile instanceof NewVirtualFile) { + for (VirtualFile child : ((NewVirtualFile)existingFile).getCachedChildren()) { + RefreshQueue.getInstance().refresh(true, false, null, modalityState, child); + } + } } } + myRootsToWatch.add(result); + if (alreadyWatched) { + result.myDominated = true; + return result; + } + myCachedNormalizedRequests = null; + setUpFileWatcher(); + return result; + } + finally { + WRITE_LOCK.unlock(); } } - myRootsToWatch.add(result); - if (alreadyWatched) { - result.myDominated = true; - return result; - } - myCachedNormalizedRequests = null; - setUpFileWatcher(); - return result; - } - finally { - WRITE_LOCK.unlock(); - } + }); } private boolean isAlreadyWatched(final WatchRequest request) { @@ -383,33 +392,38 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap public Set addRootsToWatch(@NotNull final Collection rootPaths, final boolean toWatchRecursively) { if (!FileWatcher.getInstance().isOperational()) return Collections.emptySet(); - Set result = new HashSet(); - Set filesToSynchronize = new HashSet(); + final Set result = new HashSet(); + final Set filesToSynchronize = new HashSet(); - WRITE_LOCK.lock(); - try { - for (String rootPath : rootPaths) { - LOG.assertTrue(rootPath != null); - if (rootPath.length() > 0) { - final WatchRequestImpl request = new WatchRequestImpl(rootPath, toWatchRecursively); - final VirtualFile existingFile = findFileByPathIfCached(rootPath); - if (existingFile != null) { - if (!isAlreadyWatched(request)) { - filesToSynchronize.add(existingFile); + Application application = ApplicationManager.getApplication(); + application.runReadAction(new Runnable() { + public void run() { + WRITE_LOCK.lock(); + try { + for (String rootPath : rootPaths) { + LOG.assertTrue(rootPath != null); + if (rootPath.length() > 0) { + final WatchRequestImpl request = new WatchRequestImpl(rootPath, toWatchRecursively); + final VirtualFile existingFile = findFileByPathIfCached(rootPath); + if (existingFile != null) { + if (!isAlreadyWatched(request)) { + filesToSynchronize.add(existingFile); + } + } + result.add(request); + myRootsToWatch.add(request); //add in any case, safe to add inplace without copying myRootsToWatch before the loop } } - result.add(request); - myRootsToWatch.add(request); //add in any case, safe to add inplace without copying myRootsToWatch before the loop + myCachedNormalizedRequests = null; + setUpFileWatcher(); + } + finally { + WRITE_LOCK.unlock(); } } - myCachedNormalizedRequests = null; - setUpFileWatcher(); - } - finally { - WRITE_LOCK.unlock(); - } + }); - if (!ApplicationManager.getApplication().isUnitTestMode() && !filesToSynchronize.isEmpty()) { + if (!application.isUnitTestMode() && !filesToSynchronize.isEmpty()) { for (VirtualFile file : filesToSynchronize) { if (file instanceof NewVirtualFile && file.getFileSystem() instanceof LocalFileSystem) { ((NewVirtualFile)file).markDirtyRecursively(); @@ -423,30 +437,38 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap @Override public void removeWatchedRoot(@NotNull final WatchRequest watchRequest) { - WRITE_LOCK.lock(); - try { - if (myRootsToWatch.remove((WatchRequestImpl)watchRequest) && !((WatchRequestImpl)watchRequest).myDominated) { - myCachedNormalizedRequests = null; - setUpFileWatcher(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + WRITE_LOCK.lock(); + try { + if (myRootsToWatch.remove((WatchRequestImpl)watchRequest) && !((WatchRequestImpl)watchRequest).myDominated) { + myCachedNormalizedRequests = null; + setUpFileWatcher(); + } + } + finally { + WRITE_LOCK.unlock(); + } } - } - finally { - WRITE_LOCK.unlock(); - } + }); } @Override public void removeWatchedRoots(@NotNull final Collection rootsToWatch) { - WRITE_LOCK.lock(); - try { - if (myRootsToWatch.removeAll(rootsToWatch)) { - myCachedNormalizedRequests = null; - setUpFileWatcher(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + WRITE_LOCK.lock(); + try { + if (myRootsToWatch.removeAll(rootsToWatch)) { + myCachedNormalizedRequests = null; + setUpFileWatcher(); + } + } + finally { + WRITE_LOCK.unlock(); + } } - } - finally { - WRITE_LOCK.unlock(); - } + }); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java index 59028eb5373d..58b53843c80f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -1183,7 +1183,9 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements button.dispose(); myId2StripeButton.remove(id); // - myId2FocusWatcher.remove(id); + ToolWindowFocusWatcher watcher = (ToolWindowFocusWatcher)myId2FocusWatcher.remove(id); + watcher.deinstall(); + // Destroy decorator final InternalDecorator decorator = getInternalDecorator(id); decorator.dispose(); @@ -1946,11 +1948,17 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements */ private final class ToolWindowFocusWatcher extends FocusWatcher { private final String myId; + private final ToolWindowImpl myToolWindow; private ToolWindowFocusWatcher(final ToolWindowImpl toolWindow) { myId = toolWindow.getId(); install(toolWindow.getComponent()); + myToolWindow = toolWindow; + } + + public void deinstall() { + deinstall(myToolWindow.getComponent()); } protected boolean isFocusedComponentChangeValid(final Component comp, final AWTEvent cause) { diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 3dd265f62fcb..8eb94ba4ebdd 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -152,7 +152,10 @@ dir.diff.default.src.folder= dir.diff.default.trg.folder= show.live.templates.in.completion=false documentation.component.editor.font=false + ide.mac.useNativeClipboard=true +ide.mac.useNativeClipboard.async=false + show.all.classes.on.first.completion=false limited.relevance.sorting.in.completion=false limited.relevance.sorting.in.completion.description=Whether only 5 most relevant items are shown at the top of the completion list, or it's sorted by relevance completely @@ -166,4 +169,4 @@ show.anonymous.in.structure.view=false show.anonymous.in.structure.view.description=Enables Java anonymous classes in Structure View enable.groovy.hotswap=true -enable.groovy.hotswap.description=Whether IDEA should add a special java agent to the debugged process which allows to hot-swap Groovy changes in some cases \ No newline at end of file +enable.groovy.hotswap.description=Whether IDEA should add a special java agent to the debugged process which allows to hot-swap Groovy changes in some cases diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java index f3765c2b727b..ded368b51aae 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java @@ -32,6 +32,7 @@ import com.intellij.openapi.util.DefaultJDOMExternalizer; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMExternalizable; import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.*; import com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager; @@ -70,7 +71,7 @@ public class CreatePatchCommitExecutor implements CommitExecutorWithHelp, Projec @Nls public String getActionText() { - return VcsBundle.message("create.patch.commit.action.text"); + return VcsBundle.message("create.patch.commit.action.title"); } @Override diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/DiffShelvedChangesAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/DiffShelvedChangesAction.java index c4b37c443f04..b9a1702e25d0 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/DiffShelvedChangesAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/DiffShelvedChangesAction.java @@ -141,7 +141,7 @@ public class DiffShelvedChangesAction extends AnAction implements DumbAware { VcsBalloonProblemNotifier.showOverChangesView(project, "Show Diff: Cannot find base for: " + StringUtil.join(missing, ",\n"), MessageType.WARNING); } - ShowDiffAction.showDiffImpl(project, diffRequestPresentables, toSelectIdx, new ShowDiffUIContext(false)); + ShowDiffAction.showDiffImpl(project, diffRequestPresentables, toSelectIdx, new ShowDiffUIContext(true)); } private static class PatchesPreloader { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java index 3bcfd4a6f6d0..27beb9ccae27 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java @@ -77,6 +77,7 @@ public class LineStatusTracker { private boolean myAnathemaThrown; private FileEditorManager myFileEditorManager; private final VirtualFile myVirtualFile; + private volatile boolean myReleased; private LineStatusTracker(final Document document, final Document upToDateDocument, final Project project, final VirtualFile virtualFile) { myVirtualFile = virtualFile; @@ -89,10 +90,12 @@ public class LineStatusTracker { myRanges = new ArrayList(); myAnathemaThrown = false; myFileEditorManager = FileEditorManager.getInstance(myProject); + myReleased = false; } public void initialize(@NotNull final String upToDateContent, @NotNull RevisionPack baseRevisionNumber) { ApplicationManager.getApplication().assertIsDispatchThread(); + if (myReleased) return; synchronized (myLock) { try { @@ -166,6 +169,7 @@ public class LineStatusTracker { @SuppressWarnings({"AutoBoxing"}) private RangeHighlighter createHighlighter(final Range range) { + assert ! myReleased; int first = range.getOffset1() >= myDocument.getLineCount() ? myDocument.getTextLength() : myDocument.getLineStartOffset(range.getOffset1()); @@ -204,6 +208,7 @@ public class LineStatusTracker { removeHighlightersFromMarkupModel(); myRanges.clear(); } + myReleased = true; } public Document getDocument() { @@ -228,6 +233,7 @@ public class LineStatusTracker { } public void startBulkUpdate() { + if (myReleased) return; synchronized (myLock) { myBulkUpdate = true; removeAnathema(); @@ -247,6 +253,7 @@ public class LineStatusTracker { } public void finishBulkUpdate() { + if (myReleased) return; synchronized (myLock) { myBulkUpdate = false; reinstallRanges(); @@ -286,6 +293,7 @@ public class LineStatusTracker { private final VcsDirtyScopeManager myVcsDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject); public void beforeDocumentChange(DocumentEvent e) { + if (myReleased) return; myApplication.assertWriteAccessAllowed(); synchronized (myLock) { @@ -338,6 +346,11 @@ public class LineStatusTracker { } public void documentChanged(final DocumentEvent e) { + if (myReleased) { + return; + } + // TODO: remove assertion when cached document listeners will work ok + //assert ! myReleased; myApplication.assertWriteAccessAllowed(); synchronized (myLock) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.java index 37e2a0df0656..ccd8400d2534 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.java @@ -212,14 +212,9 @@ public class LineStatusTrackerManager implements ProjectComponent, LineStatusTra if (tracker == null && (! shouldBeInstalled)) return; if (tracker != null) { - if (! shouldBeInstalled) { - releaseTracker(document); - return; - } else { - tracker.resetForBaseRevisionLoad(); - startAlarm(document, virtualFile); - } - } else if (shouldBeInstalled) { + releaseTracker(document); + } + if (shouldBeInstalled) { installTracker(virtualFile, document); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java index d6522b4df6d0..45a1ce9622d3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java @@ -68,32 +68,32 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy */ GrStubElementType CLASS_DEFINITION = new GrTypeDefinitionElementType("class definition") { - public GrClassDefinition createPsi(GrTypeDefinitionStub stub) { + public GrClassDefinition createPsi(@NotNull GrTypeDefinitionStub stub) { return new GrClassDefinitionImpl(stub); } }; GrStubElementType INTERFACE_DEFINITION = new GrTypeDefinitionElementType("interface definition") { - public GrInterfaceDefinition createPsi(GrTypeDefinitionStub stub) { + public GrInterfaceDefinition createPsi(@NotNull GrTypeDefinitionStub stub) { return new GrInterfaceDefinitionImpl(stub); } }; GrStubElementType ENUM_DEFINITION = new GrTypeDefinitionElementType("enumeration definition") { - public GrEnumTypeDefinition createPsi(GrTypeDefinitionStub stub) { + public GrEnumTypeDefinition createPsi(@NotNull GrTypeDefinitionStub stub) { return new GrEnumTypeDefinitionImpl(stub); } }; GrStubElementType ANNOTATION_DEFINITION = new GrTypeDefinitionElementType("annotation definition") { - public GrAnnotationTypeDefinition createPsi(GrTypeDefinitionStub stub) { + public GrAnnotationTypeDefinition createPsi(@NotNull GrTypeDefinitionStub stub) { return new GrAnnotationTypeDefinitionImpl(stub); } }; GrStubElementType ANONYMOUS_CLASS_DEFINITION = new GrTypeDefinitionElementType("Anonymous class") { @Override - public GrAnonymousClassDefinition createPsi(GrTypeDefinitionStub stub) { + public GrAnonymousClassDefinition createPsi(@NotNull GrTypeDefinitionStub stub) { return new GrAnonymousClassDefinitionImpl(stub); } }; @@ -101,7 +101,7 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy GrStubElementType ENUM_CONSTANT_INITIALIZER = new GrTypeDefinitionElementType("Enum constant initializer") { @Override - public GrEnumConstantInitializer createPsi(GrTypeDefinitionStub stub) { + public GrEnumConstantInitializer createPsi(@NotNull GrTypeDefinitionStub stub) { return new GrEnumConstantInitializerImpl(stub); } }; @@ -112,13 +112,13 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy GrStubElementType FIELD = new GrFieldElementType(); GrMethodElementType METHOD_DEFINITION = new GrMethodElementType("method definition") { - public GrMethod createPsi(GrMethodStub stub) { + public GrMethod createPsi(@NotNull GrMethodStub stub) { return new GrMethodImpl(stub); } }; GrStubElementType ANNOTATION_METHOD = new GrMethodElementType("annotation method") { @Override - public GrMethod createPsi(GrMethodStub stub) { + public GrMethod createPsi(@NotNull GrMethodStub stub) { return new GrAnnotationMethodImpl(stub); } @@ -133,12 +133,12 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy }; GrReferenceListElementType IMPLEMENTS_CLAUSE = new GrReferenceListElementType("implements clause") { - public GrImplementsClause createPsi(GrReferenceListStub stub) { + public GrImplementsClause createPsi(@NotNull GrReferenceListStub stub) { return new GrImplementsClauseImpl(stub); } }; GrReferenceListElementType EXTENDS_CLAUSE = new GrReferenceListElementType("super class clause") { - public GrExtendsClause createPsi(GrReferenceListStub stub) { + public GrExtendsClause createPsi(@NotNull GrReferenceListStub stub) { return new GrExtendsClauseImpl(stub); } }; @@ -263,19 +263,19 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy GroovyElementType TYPE_ARGUMENT = new GroovyElementType("type argument"); EmptyStubElementType TYPE_PARAMETER_LIST = new EmptyStubElementType("type parameter list", GroovyFileType.GROOVY_LANGUAGE) { @Override - public GrTypeParameterList createPsi(EmptyStub stub) { + public GrTypeParameterList createPsi(@NotNull EmptyStub stub) { return new GrTypeParameterListImpl(stub); } }; GrStubElementType TYPE_PARAMETER = new GrStubElementType("type parameter") { @Override - public GrTypeParameter createPsi(GrTypeParameterStub stub) { + public GrTypeParameter createPsi(@NotNull GrTypeParameterStub stub) { return new GrTypeParameterImpl(stub); } @Override - public GrTypeParameterStub createStub(GrTypeParameter psi, StubElement parentStub) { + public GrTypeParameterStub createStub(@NotNull GrTypeParameter psi, StubElement parentStub) { return new GrTypeParameterStub(parentStub, StringRef.fromString(psi.getName())); } @@ -295,7 +295,7 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy GrMethodElementType CONSTRUCTOR_DEFINITION = new GrMethodElementType("constructor definition") { @Override - public GrMethod createPsi(GrMethodStub stub) { + public GrMethod createPsi(@NotNull GrMethodStub stub) { return new GrConstructorImpl(stub); } }; @@ -313,12 +313,12 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy GrStubElementType ANNOTATION = new GrStubElementType("annotation") { @Override - public GrAnnotation createPsi(GrAnnotationStub stub) { + public GrAnnotation createPsi(@NotNull GrAnnotationStub stub) { return new GrAnnotationImpl(stub); } @Override - public GrAnnotationStub createStub(GrAnnotation psi, StubElement parentStub) { + public GrAnnotationStub createStub(@NotNull GrAnnotation psi, StubElement parentStub) { return new GrAnnotationStub(parentStub, psi); } @@ -335,19 +335,19 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy //parameters EmptyStubElementType PARAMETERS_LIST = new EmptyStubElementType("parameters list", GroovyFileType.GROOVY_LANGUAGE) { @Override - public GrParameterList createPsi(EmptyStub stub) { + public GrParameterList createPsi(@NotNull EmptyStub stub) { return new GrParameterListImpl(stub); } }; GrStubElementType PARAMETER = new GrStubElementType("parameter") { @Override - public GrParameter createPsi(GrParameterStub stub) { + public GrParameter createPsi(@NotNull GrParameterStub stub) { return new GrParameterImpl(stub); } @Override - public GrParameterStub createStub(GrParameter psi, StubElement parentStub) { + public GrParameterStub createStub(@NotNull GrParameter psi, StubElement parentStub) { return new GrParameterStub(parentStub, StringRef.fromString(psi.getName()), GrStubUtils.getAnnotationNames(psi), GrStubUtils.getTypeText(psi)); } @@ -369,7 +369,7 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy EmptyStubElementType CLASS_BODY = new EmptyStubElementType("class block", GroovyFileType.GROOVY_LANGUAGE) { @Override - public GrTypeDefinitionBody createPsi(EmptyStub stub) { + public GrTypeDefinitionBody createPsi(@NotNull EmptyStub stub) { return new GrTypeDefinitionBodyBase.GrClassBody(stub); } }; @@ -402,14 +402,14 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy } @Override - public GrVariableDeclaration createPsi(EmptyStub stub) { + public GrVariableDeclaration createPsi(@NotNull EmptyStub stub) { throw new UnsupportedOperationException("Not implemented"); } }; EmptyStubElementType VARIABLE_DEFINITION = new EmptyStubElementType("variable definitions", GroovyFileType.GROOVY_LANGUAGE) { @Override - public GrVariableDeclaration createPsi(EmptyStub stub) { + public GrVariableDeclaration createPsi(@NotNull EmptyStub stub) { return new GrVariableDeclarationBase.GrVariables(stub); } }; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrEnumConstantElementType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrEnumConstantElementType.java index 6c6f306f6ff9..25be19fda232 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrEnumConstantElementType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrEnumConstantElementType.java @@ -21,6 +21,7 @@ import com.intellij.psi.stubs.StubInputStream; import com.intellij.psi.stubs.StubOutputStream; import com.intellij.util.ArrayUtil; import com.intellij.util.io.StringRef; +import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef.enumConstant.GrEnumConstantImpl; @@ -38,12 +39,12 @@ public class GrEnumConstantElementType extends GrStubElementType super("field"); } - public GrField createPsi(GrFieldStub stub) { + public GrField createPsi(@NotNull GrFieldStub stub) { return new GrFieldImpl(stub); } - public GrFieldStub createStub(GrField psi, StubElement parentStub) { + public GrFieldStub createStub(@NotNull GrField psi, StubElement parentStub) { String[] annNames = GrStubUtils.getAnnotationNames(psi); Set namedParameters = Collections.emptySet(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrMethodElementType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrMethodElementType.java index f5b746cbef1b..380a3a18e739 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrMethodElementType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrMethodElementType.java @@ -20,6 +20,7 @@ import com.intellij.psi.stubs.StubElement; import com.intellij.psi.stubs.StubInputStream; import com.intellij.psi.stubs.StubOutputStream; import com.intellij.util.io.StringRef; +import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.stubs.GrMethodStub; import org.jetbrains.plugins.groovy.lang.psi.stubs.GrStubUtils; @@ -38,7 +39,7 @@ public abstract class GrMethodElementType extends GrStubElementType namedParameters = psi.getNamedParameters().keySet(); return new GrMethodStub(parentStub, StringRef.fromString(psi.getName()), GrStubUtils.getAnnotationNames(psi), diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrModifierListElementType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrModifierListElementType.java index d9e342616506..c3eb8999161d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrModifierListElementType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrModifierListElementType.java @@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.lang.psi.stubs.elements; import com.intellij.psi.stubs.StubElement; import com.intellij.psi.stubs.StubInputStream; import com.intellij.psi.stubs.StubOutputStream; +import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList; import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.modifiers.GrModifierListImpl; @@ -34,12 +35,12 @@ public class GrModifierListElementType extends GrStubElementType exte super(debugName); } - public GrReferenceListStub createStub(T psi, StubElement parentStub) { + public GrReferenceListStub createStub(@NotNull T psi, StubElement parentStub) { List refNames = new ArrayList(); for (GrCodeReferenceElement element : psi.getReferenceElements()) { final String name = element.getText(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrTypeDefinitionElementType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrTypeDefinitionElementType.java index 3abdb54889ee..d6d468845d25 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrTypeDefinitionElementType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrTypeDefinitionElementType.java @@ -42,7 +42,7 @@ public abstract class GrTypeDefinitionElementType collector) { if (PsiImplUtil.getAnnotation(clazz, GroovyCommonClassNames.GROOVY_TRANSFORM_AUTO_CLONE) == null) return; - final LightMethodBuilder clone = new LightMethodBuilder(clazz.getManager(), "clone"); + final LightMethodBuilder clone = new LightMethodBuilder(clazz.getManager(), "clone").addModifier(PsiModifier.PUBLIC); clone.setContainingClass(clazz); clone.addException(CloneNotSupportedException.class.getName()); collector.add(clone); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethodsContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethodsContributor.java index 2fc202956d5f..78faf0301610 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethodsContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethodsContributor.java @@ -57,6 +57,7 @@ public class DelegatedMethodsContributor extends AstTransformContributor { for (PsiMethod method : methods) { if (method.isConstructor()) continue; if (!deprecated && PsiImplUtil.getAnnotation(method, "java.lang.Deprecated") != null) continue; + if (clazz.findCodeMethodsBySignature(method, false).length > 0) continue; collector.add(generateDelegateMethod(method, clazz, resolveResult.getSubstitutor())); } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java index 16c36945f9ca..f3ec84ab43fb 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java @@ -102,6 +102,10 @@ public class GeneratorTest extends LightGroovyTestCase { myFixture.addClass("package groovy.lang; public @interface Delegate {}"); doTest(); } + public void testAutoCloneAnno() throws Throwable { + myFixture.addClass("package groovy.transform; public @interface AutoClone {}"); + doTest(); + } public void doTest() { final String relTestPath = getTestName(true) + ".test"; diff --git a/plugins/groovy/testdata/groovy/stubGenerator/autoCloneAnno.test b/plugins/groovy/testdata/groovy/stubGenerator/autoCloneAnno.test new file mode 100644 index 000000000000..fa785119a386 --- /dev/null +++ b/plugins/groovy/testdata/groovy/stubGenerator/autoCloneAnno.test @@ -0,0 +1,30 @@ +@groovy.transform.AutoClone +class Foo {} +----- +public class Foo extends groovy.lang.GroovyObjectSupport implements groovy.lang.GroovyObject { +public java.lang.Object clone() throws java.lang.CloneNotSupportedException { +return null; +} + +public java.lang.Object getProperty(java.lang.String property) { +return null; +} + +public void setProperty(java.lang.String property, java.lang.Object newValue) { +return ; +} + +public java.lang.Object invokeMethod(java.lang.String name, java.lang.Object args) { +return null; +} + +public groovy.lang.MetaClass getMetaClass() { +return null; +} + +public void setMetaClass(groovy.lang.MetaClass metaClass) { +return ; +} + +} +--- \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/stubGenerator/delegateAnno.test b/plugins/groovy/testdata/groovy/stubGenerator/delegateAnno.test index 0a4eb4ce3447..2f202cdbdd9c 100644 --- a/plugins/groovy/testdata/groovy/stubGenerator/delegateAnno.test +++ b/plugins/groovy/testdata/groovy/stubGenerator/delegateAnno.test @@ -9,6 +9,10 @@ class DelegateBarImpl { private @Delegate(interfaces=false) Runnable zoo; private @Delegate Doo doo; } +class Del2 implements DelegateFoo { + @Delegate DelegateFoo foo; + def foo() {} +} ----- public interface DelegateFoo { public java.lang.Object foo() ; @@ -79,4 +83,40 @@ private DelegateFoo foo = null; private java.lang.Runnable zoo = null; private Doo doo = null; } +--- +public class Del2 extends groovy.lang.GroovyObjectSupport implements DelegateFoo, groovy.lang.GroovyObject { +public java.lang.Object foo() { +return null; +} + +public DelegateFoo getFoo() { +return null; +} + +public void setFoo(DelegateFoo foo) { +return ; +} + +public java.lang.Object getProperty(java.lang.String property) { +return null; +} + +public void setProperty(java.lang.String property, java.lang.Object newValue) { +return ; +} + +public java.lang.Object invokeMethod(java.lang.String name, java.lang.Object args) { +return null; +} + +public groovy.lang.MetaClass getMetaClass() { +return null; +} + +public void setMetaClass(groovy.lang.MetaClass metaClass) { +return ; +} + +private DelegateFoo foo = null; +} --- \ No newline at end of file diff --git a/plugins/properties/src/com/intellij/lang/properties/parsing/PropertyListStubElementType.java b/plugins/properties/src/com/intellij/lang/properties/parsing/PropertyListStubElementType.java index 776e052b57f6..d3e46b694be8 100644 --- a/plugins/properties/src/com/intellij/lang/properties/parsing/PropertyListStubElementType.java +++ b/plugins/properties/src/com/intellij/lang/properties/parsing/PropertyListStubElementType.java @@ -24,6 +24,7 @@ import com.intellij.lang.properties.psi.PropertiesListStub; import com.intellij.lang.properties.psi.impl.PropertiesListImpl; import com.intellij.lang.properties.psi.impl.PropertiesListStubImpl; import com.intellij.psi.stubs.*; +import org.jetbrains.annotations.NotNull; import java.io.IOException; @@ -32,11 +33,11 @@ public class PropertyListStubElementType extends IStubElementType