diff options
Diffstat (limited to 'plugins')
439 files changed, 6925 insertions, 2269 deletions
diff --git a/plugins/ByteCodeViewer/src/META-INF/plugin.xml b/plugins/ByteCodeViewer/src/META-INF/plugin.xml index e9c6e32b977d..23e7fcd3059b 100644 --- a/plugins/ByteCodeViewer/src/META-INF/plugin.xml +++ b/plugins/ByteCodeViewer/src/META-INF/plugin.xml @@ -8,11 +8,13 @@ <extensionPoints> <extensionPoint name="classSearcher" interface="com.intellij.byteCodeViewer.ClassSearcher"/> </extensionPoints> + <extensions defaultExtensionNs="com.intellij"> <errorHandler implementation="com.intellij.diagnostic.ITNReporter"/> <projectService serviceInterface="com.intellij.byteCodeViewer.ByteCodeViewerManager" serviceImplementation="com.intellij.byteCodeViewer.ByteCodeViewerManager"/> </extensions> + <actions> <group> <action id="ByteCodeViewer" class="com.intellij.byteCodeViewer.ShowByteCodeAction" text="Show Byte Code"/> diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerComponent.java b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerComponent.java index c0a742447c67..12d336d32139 100644 --- a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerComponent.java +++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerComponent.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.byteCodeViewer; import com.intellij.codeInsight.hint.EditorFragmentComponent; @@ -25,8 +40,8 @@ import javax.swing.*; import java.awt.*; /** - * User: anna - * Date: 5/7/12 + * @author anna + * @since 5/7/12 */ public class ByteCodeViewerComponent extends JPanel implements Disposable { @@ -66,7 +81,7 @@ public class ByteCodeViewerComponent extends JPanel implements Disposable { public void setText(final String bytecode) { setText(bytecode, 0); } - + public void setText(final String bytecode, PsiElement element) { int offset = 0; final Document document = PsiDocumentManager.getInstance(element.getProject()).getDocument(element.getContainingFile()); @@ -100,7 +115,7 @@ public class ByteCodeViewerComponent extends JPanel implements Disposable { public String getText() { return myEditor.getDocument().getText(); } - + @Override public void dispose() { EditorFactory.getInstance().releaseEditor(myEditor); diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java index 7d958bb61b32..db04a80a7862 100644 --- a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java +++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.byteCodeViewer; import com.intellij.codeInsight.documentation.DockablePopupManager; @@ -32,8 +47,8 @@ import java.io.PrintWriter; import java.io.StringWriter; /** - * User: anna - * Date: 5/7/12 + * @author anna + * @since 5/7/12 */ public class ByteCodeViewerManager extends DockablePopupManager<ByteCodeViewerComponent> { private static final ExtensionPointName<ClassSearcher> CLASS_SEARCHER_EP = ExtensionPointName.create("ByteCodeViewer.classSearcher"); @@ -43,7 +58,7 @@ public class ByteCodeViewerManager extends DockablePopupManager<ByteCodeViewerCo public static final String TOOLWINDOW_ID = "Byte Code Viewer"; private static final String SHOW_BYTECODE_IN_TOOL_WINDOW = "BYTE_CODE_TOOL_WINDOW"; private static final String BYTECODE_AUTO_UPDATE_ENABLED = "BYTE_CODE_AUTO_UPDATE_ENABLED"; - + public static ByteCodeViewerManager getInstance(Project project) { return ServiceManager.getService(project, ByteCodeViewerManager.class); } @@ -129,7 +144,7 @@ public class ByteCodeViewerManager extends DockablePopupManager<ByteCodeViewerCo } } - + @Override protected void doUpdateComponent(Editor editor, PsiFile psiFile) { final Content content = myToolWindow.getContentManager().getSelectedContent(); @@ -229,7 +244,7 @@ public class ByteCodeViewerManager extends DockablePopupManager<ByteCodeViewerCo @Nullable private static String getClassVMName(PsiClass containingClass) { if (containingClass instanceof PsiAnonymousClass) { - return getClassVMName(PsiTreeUtil.getParentOfType(containingClass, PsiClass.class)) + + return getClassVMName(PsiTreeUtil.getParentOfType(containingClass, PsiClass.class)) + JavaAnonymousClassesHelper.getName((PsiAnonymousClass)containingClass); } return ClassUtil.getJVMClassName(containingClass); diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ClassSearcher.java b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ClassSearcher.java index 9a778d1470c2..93fc876e551b 100644 --- a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ClassSearcher.java +++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ClassSearcher.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.byteCodeViewer; import com.intellij.psi.PsiClass; @@ -6,7 +21,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * Created by Max Medvedev on 8/23/13 + * @author Max Medvedev + * @since 8/23/13 */ public interface ClassSearcher { @Nullable diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java index 76cf133e7a33..6d455d30d661 100644 --- a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java +++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.byteCodeViewer; import com.intellij.codeInsight.documentation.DocumentationManager; @@ -29,17 +44,17 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * User: anna - * Date: 5/4/12 + * @author anna + * @since 5/4/12 */ public class ShowByteCodeAction extends AnAction { @Override public void update(AnActionEvent e) { e.getPresentation().setEnabled(false); e.getPresentation().setIcon(AllIcons.Toolwindows.Documentation); - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); if (project != null) { - final PsiElement psiElement = getPsiElement(e.getDataContext(), project, e.getData(PlatformDataKeys.EDITOR)); + final PsiElement psiElement = getPsiElement(e.getDataContext(), project, e.getData(CommonDataKeys.EDITOR)); if (psiElement != null) { if (psiElement.getContainingFile() instanceof PsiClassOwner && ByteCodeViewerManager.getContainingClass(psiElement) != null) { @@ -52,9 +67,9 @@ public class ShowByteCodeAction extends AnAction { @Override public void actionPerformed(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null) return; - final Editor editor = PlatformDataKeys.EDITOR.getData(dataContext); + final Editor editor = CommonDataKeys.EDITOR.getData(dataContext); final PsiElement psiElement = getPsiElement(dataContext, project, editor); if (psiElement == null) return; @@ -140,7 +155,7 @@ public class ShowByteCodeAction extends AnAction { private static PsiElement getPsiElement(DataContext dataContext, Project project, Editor editor) { PsiElement psiElement = null; if (editor == null) { - psiElement = LangDataKeys.PSI_ELEMENT.getData(dataContext); + psiElement = CommonDataKeys.PSI_ELEMENT.getData(dataContext); } else { final PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, project); final Editor injectedEditor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(editor, file); diff --git a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/NavigateToTestDataAction.java b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/NavigateToTestDataAction.java index 405b8c876614..23fbb4b6bfae 100644 --- a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/NavigateToTestDataAction.java +++ b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/NavigateToTestDataAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,10 @@ package com.intellij.testAssistant; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.psi.PsiElement; @@ -37,7 +40,7 @@ public class NavigateToTestDataAction extends AnAction { @Override public void actionPerformed(AnActionEvent e) { final PsiMethod method = findTargetMethod(e.getDataContext()); - final Editor editor = e.getData(PlatformDataKeys.EDITOR); + final Editor editor = e.getData(CommonDataKeys.EDITOR); if (method == null || editor == null) { return; } @@ -55,7 +58,7 @@ public class NavigateToTestDataAction extends AnAction { @Nullable public static List<String> findTestDataFiles(@NotNull DataContext context) { final PsiMethod method = findTargetMethod(context); - final Editor editor = PlatformDataKeys.EDITOR.getData(context); + final Editor editor = CommonDataKeys.EDITOR.getData(context); if (method == null || editor == null) { return null; } @@ -77,8 +80,8 @@ public class NavigateToTestDataAction extends AnAction { @Nullable private static PsiMethod findTargetMethod(@NotNull DataContext context) { - final Editor editor = PlatformDataKeys.EDITOR.getData(context); - final PsiFile file = LangDataKeys.PSI_FILE.getData(context); + final Editor editor = CommonDataKeys.EDITOR.getData(context); + final PsiFile file = CommonDataKeys.PSI_FILE.getData(context); if (file != null && editor != null) { PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); return PsiTreeUtil.getParentOfType(element, PsiMethod.class); diff --git a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataAsRelatedFileProvider.java b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataAsRelatedFileProvider.java index 672c7901e870..e8172b2d0198 100644 --- a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataAsRelatedFileProvider.java +++ b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataAsRelatedFileProvider.java @@ -1,10 +1,24 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.testAssistant; import com.intellij.navigation.GotoRelatedItem; import com.intellij.navigation.GotoRelatedProvider; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.LangDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; @@ -23,9 +37,9 @@ public class TestDataAsRelatedFileProvider extends GotoRelatedProvider { @NotNull @Override public List<? extends GotoRelatedItem> getItems(@NotNull DataContext context) { - final Editor editor = PlatformDataKeys.EDITOR.getData(context); - final Project project = PlatformDataKeys.PROJECT.getData(context); - final PsiElement element = LangDataKeys.PSI_ELEMENT.getData(context); + final Editor editor = CommonDataKeys.EDITOR.getData(context); + final Project project = CommonDataKeys.PROJECT.getData(context); + final PsiElement element = CommonDataKeys.PSI_ELEMENT.getData(context); if (editor == null || element == null || project == null) { return Collections.emptyList(); } diff --git a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataHighlightingPass.java b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataHighlightingPass.java index 2ee2be1876df..3f60acd2c2c0 100644 --- a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataHighlightingPass.java +++ b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataHighlightingPass.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,6 +54,9 @@ public class TestDataHighlightingPass extends TextEditorHighlightingPass { public void doApplyInformationToEditor() { removeHighlighters(); + if (myDocument == null) { + return; + } final MarkupModel model = DocumentMarkupModel.forDocument(myDocument, myProject, true); final String text = myDocument.getText(); @@ -72,6 +75,9 @@ public class TestDataHighlightingPass extends TextEditorHighlightingPass { } private void removeHighlighters() { + if (myDocument == null) { + return; + } final MarkupModel model = DocumentMarkupModel.forDocument(myDocument, myProject, true); for (RangeHighlighter highlighter : model.getAllHighlighters()) { if (highlighter.getUserData(KEY) == VALUE) { diff --git a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataNavigationHandler.java b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataNavigationHandler.java index d6913b21e1e8..08369634e84d 100644 --- a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataNavigationHandler.java +++ b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataNavigationHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -108,7 +108,11 @@ public class TestDataNavigationHandler implements GutterIconNavigationHandler<Ps List<String> listPaths = new ArrayList<String>(fileNames); final String CREATE_MISSING_OPTION = "Create Missing Files"; if (fileNames.size() == 2) { - listPaths.add(CREATE_MISSING_OPTION); + VirtualFile file1 = LocalFileSystem.getInstance().refreshAndFindFileByPath(fileNames.get(0)); + VirtualFile file2 = LocalFileSystem.getInstance().refreshAndFindFileByPath(fileNames.get(1)); + if (file1 == null || file2 == null) { + listPaths.add(CREATE_MISSING_OPTION); + } } final JList list = new JBList(ArrayUtil.toStringArray(listPaths)); list.setCellRenderer(new ColoredListCellRenderer() { diff --git a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceCollector.java b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceCollector.java index 3ee186402b83..743134ff2aa8 100644 --- a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceCollector.java +++ b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceCollector.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ public class TestDataReferenceCollector { private boolean myFoundTestDataParameters = false; public TestDataReferenceCollector(@Nullable String testDataPath, String testName) { - if (StringUtil.isNotEmpty(testDataPath) && StringUtil.endsWithChar(testDataPath, File.separatorChar)) { + if (StringUtil.isNotEmpty(testDataPath) && !StringUtil.endsWithChar(testDataPath, File.separatorChar)) { testDataPath += File.separatorChar; } myTestDataPath = testDataPath; diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml index 6abd21a87c21..e41060528212 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml @@ -1199,7 +1199,15 @@ key="html.tag.can.be.javadoc.tag.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.javadoc.issues" enabledByDefault="false" level="WARNING" implementationClass="com.siyeh.ig.javadoc.HtmlTagCanBeJavadocTagInspection"/> - <localInspection language="XML" shortName="PackageDotHtmlMayBePackageInfo" bundle="com.siyeh.InspectionGadgetsBundle" + <globalInspection language="JAVA" shortName="MissingPackageInfo" bundle="com.siyeh.InspectionGadgetsBundle" + key="missing.package.info.display.name" groupBundle="messages.InspectionsBundle" + groupKey="group.names.javadoc.issues" enabledByDefault="false" level="WARNING" + implementationClass="com.siyeh.ig.javadoc.MissingPackageInfoInspection"/> + <localInspection language="JAVA" shortName="PackageInfoWithoutPackage" bundle="com.siyeh.InspectionGadgetsBundle" + key="package.info.java.without.package.display.name" groupBundle="messages.InspectionsBundle" + groupKey="group.names.javadoc.issues" enabledByDefault="false" level="WARNING" + implementationClass="com.siyeh.ig.javadoc.PackageInfoWithoutPackageInspection"/> + <localInspection shortName="PackageDotHtmlMayBePackageInfo" bundle="com.siyeh.InspectionGadgetsBundle" key="package.dot.html.may.be.package.info.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.javadoc.issues" enabledByDefault="false" level="WARNING" implementationClass="com.siyeh.ig.javadoc.PackageDotHtmlMayBePackageInfoInspection"/> @@ -2003,6 +2011,10 @@ level="WARNING" implementationClass="com.siyeh.ig.redundancy.UnusedLabelInspection"/> <!--group.names.resource.management.issues--> + <localInspection language="JAVA" suppressId="resource" shortName="AutoCloseableResource" bundle="com.siyeh.InspectionGadgetsBundle" + key="auto.closeable.resource.display.name" groupBundle="messages.InspectionsBundle" + groupKey="group.names.resource.management.issues" enabledByDefault="false" level="WARNING" + implementationClass="com.siyeh.ig.resources.AutoCloseableResourceInspection"/> <localInspection language="JAVA" suppressId="ChannelOpenedButNotSafelyClosed" shortName="ChannelResource" bundle="com.siyeh.InspectionGadgetsBundle" key="channel.opened.not.closed.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.resource.management.issues" enabledByDefault="false" level="WARNING" diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index 6dc0cb80118d..ec62abb3e41c 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -662,7 +662,6 @@ thrown.exceptions.per.method.display.name=Method with too many exceptions declar public.static.array.field.display.name='public static' array field await.not.in.loop.display.name='await()' not in loop method.names.differ.only.by.case.display.name=Method names differing only by case -method.names.differ.only.by.case.ignore.override.option=Ignore if method is override of super method unsecure.random.number.generation.display.name=Insecure random number generation parameters.per.method.display.name=Method with too many parameters parameters.per.constructor.display.name=Constructor with too many parameters @@ -1250,10 +1249,7 @@ pointless.nullcheck.display.name=Unnecessary 'null' check before 'instanceof' ex pointless.nullcheck.problem.descriptor=Unnecessary 'null' check before 'instanceof' expression pointless.nullcheck.simplify.quickfix=Remove unnecessary ''{0}'' condition introduce.constant.quickfix=Introduce constant -make.class.cloneable.quickfix=Make class 'Cloneable' -make.interface.cloneable.quickfix=Make interface 'Cloneable' make.initialization.explicit.quickfix=Make initialization explicit -make.class.serializable.quickfix=Make class 'Serializable' move.anonymous.to.inner.quickfix=Convert to named inner class anonymous.inner.may.be.named.static.inner.class.quickfix=Convert to named 'static' inner class move.class.quickfix=Move class @@ -1794,7 +1790,7 @@ ignore.single.field.static.imports.option=Ignore single &field static imports ignore.single.method.static.imports.option=Ignore single &method static imports ignore.methods.with.boolean.return.type.option=Ignore methods with &Boolean return type ignore.boolean.methods.in.an.interface.option=Ignore boolean methods in an @&interface -ignore.methods.overriding.super.method=Ignore methods &overriding a super method +ignore.methods.overriding.super.method=Ignore methods &overriding/implementing a super method ignored.io.resource.types=Ignored I/O resource types choose.io.resource.type.to.ignore=Choose I/O resource type to ignore ignore.accesses.from.the.same.class=Ignore accesses from the same class @@ -1903,7 +1899,6 @@ arrays.hash.code.quickfix=Replace with 'Arrays.hashCode()' method.can.be.variable.arity.method.display.name=Method can be variable arity method method.can.be.variable.arity.method.problem.descriptor=<code>#ref()</code> can be converted to variable arity method #loc method.can.be.variable.arity.method.ignore.byte.short.option=<html>Ignore methods with a last parameter of type byte[] or short[]</html> -method.can.be.variable.arity.method.ignore.overriding.methods=Ignore methods overriding a super method convert.to.variable.arity.method.quickfix=Convert to variable arity method mismatched.string.builder.query.update.display.name=Mismatched query and update of StringBuilder mismatched.string.builder.updated.problem.descriptor=Contents of {0} <code>#ref</code> are updated, but never queried #loc @@ -2042,4 +2037,14 @@ boolean.parameter.constructor.problem.descriptor='public' constructor <code>#ref boolean.parameters.constructor.problem.descriptor='public' constructor <code>#ref</code> with 'boolean' parameters boolean.parameter.only.report.multiple.option=Only report methods with multiple boolean parameters unnecessary.unicode.escape.display.name=Unnecessary unicode escape sequence -unnecessary.unicode.escape.problem.descriptor=Unicode escape sequence <code>#ref</code> can be replaced with ''{0}''
\ No newline at end of file +unnecessary.unicode.escape.problem.descriptor=Unicode escape sequence <code>#ref</code> can be replaced with ''{0}'' +missing.package.info.display.name=Missing 'package-info.java' +missing.package.info.problem.descriptor=Package ''{0}'' is missing a <code>package-info.java</code> file +missing.package.html.problem.descriptor=Package ''{0}'' is missing a <code>package.html</code> file +package.info.java.without.package.display.name='package-info.java' without 'package' statement +package.info.without.package.problem.descriptor='package-info.java' does not have a package statement +package.info.without.package.quickfix=add ''package {0};'' +package.info.without.package.family.quickfix=add package statement +auto.closeable.resource.display.name=AutoCloseable used without 'try'-with-resources +auto.closeable.resource.problem.descriptor=''{0}'' used without ''try''-with-resources statement +auto.closeable.resource.returned.option=Ignore AutoCloseable instances returned from method calls
\ No newline at end of file diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspectionBase.java index 3a291bd6a75b..aa077a540e07 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspectionBase.java @@ -32,7 +32,7 @@ import org.jetbrains.annotations.Nullable; public class MismatchedCollectionQueryUpdateInspectionBase extends BaseInspection { @SuppressWarnings({"PublicField"}) public final ExternalizableStringSet queryNames = - new ExternalizableStringSet("copyInto", "drainTo", "propertyNames", "save", "store", "write"); + new ExternalizableStringSet("copyInto", "drainTo", "propertyNames", "save", "store", "write", "forEach", "replaceAll"); @SuppressWarnings({"PublicField"}) public final ExternalizableStringSet updateNames = new ExternalizableStringSet("add", "clear", "drainTo", "insert", "load", "offer", "poll", "push", "put", "remove", "replace", diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classmetrics/MethodCountInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classmetrics/MethodCountInspection.java index 53197503432e..9de4ae97e10c 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classmetrics/MethodCountInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classmetrics/MethodCountInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import com.intellij.util.ui.UIUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.psiutils.MethodUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -38,6 +39,9 @@ public class MethodCountInspection extends BaseInspection { @SuppressWarnings({"PublicField"}) public boolean ignoreGettersAndSetters = false; + @SuppressWarnings("PublicField") + public boolean ignoreOverridingMethods = false; + @Override @NotNull public String getID() { @@ -53,8 +57,7 @@ public class MethodCountInspection extends BaseInspection { @Override public JComponent createOptionsPanel() { final JComponent panel = new JPanel(new GridBagLayout()); - final Component label = new JLabel( - InspectionGadgetsBundle.message("method.count.limit.option")); + final Component label = new JLabel(InspectionGadgetsBundle.message("method.count.limit.option")); final JFormattedTextField valueField = prepareNumberEditor("m_limit"); final GridBagConstraints constraints = new GridBagConstraints(); @@ -68,18 +71,23 @@ public class MethodCountInspection extends BaseInspection { constraints.insets.right = 0; panel.add(valueField, constraints); - final CheckBox gettersSettersCheckBox = new CheckBox( - InspectionGadgetsBundle.message( - "method.count.ignore.getters.setters.option"), + final CheckBox gettersSettersCheckBox = new CheckBox(InspectionGadgetsBundle.message("method.count.ignore.getters.setters.option"), this, "ignoreGettersAndSetters"); constraints.gridx = 0; constraints.gridy = 1; - constraints.weighty = 1.0; constraints.gridwidth = 2; - constraints.anchor = GridBagConstraints.NORTHWEST; + constraints.anchor = GridBagConstraints.WEST; panel.add(gettersSettersCheckBox, constraints); + final CheckBox overridingMethodCheckBox = + new CheckBox(InspectionGadgetsBundle.message("ignore.methods.overriding.super.method"), this, "ignoreOverridingMethods"); + + constraints.weighty = 1.0; + constraints.gridy = 2; + constraints.anchor = GridBagConstraints.NORTHWEST; + panel.add(overridingMethodCheckBox, constraints); + return panel; } @@ -88,8 +96,7 @@ public class MethodCountInspection extends BaseInspection { @NotNull public String buildErrorString(Object... infos) { final Integer count = (Integer)infos[0]; - return InspectionGadgetsBundle.message( - "too.many.methods.problem.descriptor", count); + return InspectionGadgetsBundle.message("too.many.methods.problem.descriptor", count); } @Override @@ -101,7 +108,6 @@ public class MethodCountInspection extends BaseInspection { @Override public void visitClass(@NotNull PsiClass aClass) { - // note: no call to super final int methodCount = calculateTotalMethodCount(aClass); if (methodCount <= m_limit) { return; @@ -117,8 +123,12 @@ public class MethodCountInspection extends BaseInspection { continue; } if (ignoreGettersAndSetters) { - if (PropertyUtil.isSimpleGetter(method) || - PropertyUtil.isSimpleSetter(method)) { + if (PropertyUtil.isSimpleGetter(method) || PropertyUtil.isSimpleSetter(method)) { + continue; + } + } + if (ignoreOverridingMethods) { + if (MethodUtils.hasSuper(method)) { continue; } } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/cloneable/CloneInNonCloneableClassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/cloneable/CloneInNonCloneableClassInspection.java index 1995e24a497a..0d210bff4dd6 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/cloneable/CloneInNonCloneableClassInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/cloneable/CloneInNonCloneableClassInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.fixes.MakeCloneableFix; +import com.siyeh.ig.fixes.DelegatingFixFactory; import com.siyeh.ig.psiutils.CloneUtils; import org.jetbrains.annotations.NotNull; @@ -30,8 +30,7 @@ public class CloneInNonCloneableClassInspection extends BaseInspection { @Override @NotNull public String getDisplayName() { - return InspectionGadgetsBundle.message( - "clone.method.in.non.cloneable.class.display.name"); + return InspectionGadgetsBundle.message("clone.method.in.non.cloneable.class.display.name"); } @Override @@ -40,21 +39,16 @@ public class CloneInNonCloneableClassInspection extends BaseInspection { final PsiClass aClass = (PsiClass)infos[0]; final String className = aClass.getName(); if (aClass.isInterface()) { - return InspectionGadgetsBundle.message( - "clone.method.in.non.cloneable.interface.problem.descriptor", - className); + return InspectionGadgetsBundle.message("clone.method.in.non.cloneable.interface.problem.descriptor", className); } else { - return InspectionGadgetsBundle.message( - "clone.method.in.non.cloneable.class.problem.descriptor", - className); + return InspectionGadgetsBundle.message("clone.method.in.non.cloneable.class.problem.descriptor", className); } } @Override protected InspectionGadgetsFix buildFix(Object... infos) { - final PsiClass aClass = (PsiClass)infos[0]; - return new MakeCloneableFix(aClass.isInterface()); + return DelegatingFixFactory.createMakeCloneableFix((PsiClass)infos[0]); } @Override @@ -62,8 +56,7 @@ public class CloneInNonCloneableClassInspection extends BaseInspection { return new CloneInNonCloneableClassVisitor(); } - private static class CloneInNonCloneableClassVisitor - extends BaseInspectionVisitor { + private static class CloneInNonCloneableClassVisitor extends BaseInspectionVisitor { @Override public void visitMethod(@NotNull PsiMethod method) { @@ -71,8 +64,7 @@ public class CloneInNonCloneableClassInspection extends BaseInspection { return; } final PsiClass containingClass = method.getContainingClass(); - if (containingClass == null || - CloneUtils.isCloneable(containingClass)) { + if (CloneUtils.isCloneable(containingClass)) { return; } registerMethodError(method, containingClass); diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/DelegatingFixFactory.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/DelegatingFixFactory.java new file mode 100644 index 000000000000..f83ad5aeb486 --- /dev/null +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/DelegatingFixFactory.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.fixes; + +import com.intellij.codeInsight.intention.QuickFixFactory; +import com.intellij.psi.CommonClassNames; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiClassType; +import com.siyeh.ig.DelegatingFix; +import com.siyeh.ig.InspectionGadgetsFix; +import com.siyeh.ig.psiutils.TypeUtils; + +/** + * @author Bas Leijdekkers + */ +public class DelegatingFixFactory { + + public static InspectionGadgetsFix createMakeSerializableFix(PsiClass aClass) { + final PsiClassType type = TypeUtils.getType(CommonClassNames.JAVA_IO_SERIALIZABLE, aClass); + return new DelegatingFix(QuickFixFactory.getInstance().createExtendsListFix(aClass, type, true)); + } + + public static InspectionGadgetsFix createMakeCloneableFix(PsiClass aClass) { + final PsiClassType type = TypeUtils.getType(CommonClassNames.JAVA_LANG_CLONEABLE, aClass); + return new DelegatingFix(QuickFixFactory.getInstance().createExtendsListFix(aClass, type, true)); + } +}
\ No newline at end of file diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeCloneableFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeCloneableFix.java deleted file mode 100644 index d78a3cd982d2..000000000000 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeCloneableFix.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.siyeh.ig.fixes; - -import com.intellij.codeInspection.ProblemDescriptor; -import com.intellij.openapi.project.Project; -import com.intellij.psi.*; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.util.IncorrectOperationException; -import com.siyeh.InspectionGadgetsBundle; -import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.ClassUtils; -import org.jetbrains.annotations.NotNull; - -public class MakeCloneableFix extends InspectionGadgetsFix { - - private final boolean isInterface; - - public MakeCloneableFix(boolean isInterface) { - this.isInterface = isInterface; - } - - @Override - @NotNull - public String getName() { - if (isInterface) { - return InspectionGadgetsBundle.message( - "make.interface.cloneable.quickfix"); - } - else { - return InspectionGadgetsBundle.message( - "make.class.cloneable.quickfix"); - } - } - - @NotNull - @Override - public String getFamilyName() { - return "Make 'Cloneable'"; - } - - @Override - public void doFix(Project project, ProblemDescriptor descriptor) - throws IncorrectOperationException { - final PsiElement nameElement = descriptor.getPsiElement(); - final PsiClass containingClass = - ClassUtils.getContainingClass(nameElement); - if (containingClass == null) { - return; - } - final PsiElementFactory elementFactory = - JavaPsiFacade.getElementFactory(project); - final GlobalSearchScope scope = GlobalSearchScope.allScope(project); - final PsiJavaCodeReferenceElement ref = - elementFactory.createReferenceElementByFQClassName( - CommonClassNames.JAVA_LANG_CLONEABLE, scope); - final PsiReferenceList extendsImplementsList; - if (containingClass.isInterface()) { - extendsImplementsList = containingClass.getExtendsList(); - } - else { - extendsImplementsList = containingClass.getImplementsList(); - } - if (extendsImplementsList == null) { - return; - } - extendsImplementsList.add(ref); - } -} diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeSerializableFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeSerializableFix.java deleted file mode 100644 index b0065c4f7a18..000000000000 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeSerializableFix.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.siyeh.ig.fixes; - -import com.intellij.codeInspection.ProblemDescriptor; -import com.intellij.openapi.project.Project; -import com.intellij.psi.*; -import com.intellij.psi.search.GlobalSearchScope; -import com.siyeh.InspectionGadgetsBundle; -import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.ClassUtils; -import org.jetbrains.annotations.NotNull; - -public class MakeSerializableFix extends InspectionGadgetsFix { - - @Override - @NotNull - public String getName() { - return InspectionGadgetsBundle.message("make.class.serializable.quickfix"); - } - - @NotNull - @Override - public String getFamilyName() { - return getName(); - } - - @Override - public void doFix(Project project, ProblemDescriptor descriptor) { - final PsiElement nameElement = descriptor.getPsiElement(); - final PsiClass containingClass = ClassUtils.getContainingClass(nameElement); - if (containingClass == null) { - return; - } - final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); - final GlobalSearchScope scope = GlobalSearchScope.allScope(project); - final PsiJavaCodeReferenceElement referenceElement = - elementFactory.createReferenceElementByFQClassName(CommonClassNames.JAVA_IO_SERIALIZABLE, scope); - final PsiReferenceList referenceList; - if (containingClass.isInterface()) { - referenceList = containingClass.getExtendsList(); - } - else { - referenceList = containingClass.getImplementsList(); - } - if (referenceList == null) { - return; - } - referenceList.add(referenceElement); - } -}
\ No newline at end of file diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/FieldHasSetterButNoGetterInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/FieldHasSetterButNoGetterInspection.java index 93ea038b1e5d..8520823d8e57 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/FieldHasSetterButNoGetterInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/FieldHasSetterButNoGetterInspection.java @@ -52,8 +52,7 @@ public class FieldHasSetterButNoGetterInspection extends BaseInspection { @Override public void visitField(@NotNull PsiField field) { - final Project project = field.getProject(); - final String propertyName = PropertyUtil.suggestPropertyName(project, field); + final String propertyName = PropertyUtil.suggestPropertyName(field); final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC); final PsiClass containingClass = field.getContainingClass(); final PsiMethod setter = PropertyUtil.findPropertySetter(containingClass, propertyName, isStatic, false); diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/MissingPackageInfoInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/MissingPackageInfoInspection.java new file mode 100644 index 000000000000..92254308f431 --- /dev/null +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/MissingPackageInfoInspection.java @@ -0,0 +1,94 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.javadoc; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.CommonProblemDescriptor; +import com.intellij.codeInspection.GlobalInspectionContext; +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.reference.RefClass; +import com.intellij.codeInspection.reference.RefEntity; +import com.intellij.codeInspection.reference.RefPackage; +import com.intellij.openapi.project.Project; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.util.PsiUtil; +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.BaseGlobalInspection; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * @author Bas Leijdekkers + */ +public class MissingPackageInfoInspection extends BaseGlobalInspection { + + @Nls + @NotNull + @Override + public String getDisplayName() { + return InspectionGadgetsBundle.message("missing.package.info.display.name"); + } + + @Nullable + @Override + public CommonProblemDescriptor[] checkElement(@NotNull RefEntity refEntity, + @NotNull AnalysisScope scope, + @NotNull InspectionManager manager, + @NotNull GlobalInspectionContext globalContext) { + if (!(refEntity instanceof RefPackage)) { + return null; + } + final RefPackage refPackage = (RefPackage)refEntity; + final String packageName = refPackage.getQualifiedName(); + final Project project = globalContext.getProject(); + final PsiPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(packageName); + if (aPackage == null) { + return null; + } + final List<RefEntity> children = refPackage.getChildren(); + boolean hasClasses = false; + for (RefEntity child : children) { + if (child instanceof RefClass) { + hasClasses = true; + break; + } + } + if (!hasClasses) { + return null; + } + final PsiDirectory[] directories = aPackage.getDirectories(); + for (PsiDirectory directory : directories) { + final boolean packageInfoFound = directory.findFile(PsiPackage.PACKAGE_INFO_FILE) != null; + final boolean packageDotHtmlFound = directory.findFile("package.html") != null; + if (packageInfoFound || packageDotHtmlFound) { + return null; + } + } + if (PsiUtil.isLanguageLevel5OrHigher(aPackage)) { + return new CommonProblemDescriptor[] { + manager.createProblemDescriptor(InspectionGadgetsBundle.message("missing.package.info.problem.descriptor", packageName))}; + } + else { + return new CommonProblemDescriptor[] { + manager.createProblemDescriptor(InspectionGadgetsBundle.message("missing.package.html.problem.descriptor", packageName))}; + } + } +} diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/PackageInfoWithoutPackageInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/PackageInfoWithoutPackageInspection.java new file mode 100644 index 000000000000..b0a36b3a6b4d --- /dev/null +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/PackageInfoWithoutPackageInspection.java @@ -0,0 +1,116 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.javadoc; + +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.BaseInspection; +import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.InspectionGadgetsFix; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Bas Leijdekkers + */ +public class PackageInfoWithoutPackageInspection extends BaseInspection { + @Nls + @NotNull + @Override + public String getDisplayName() { + return InspectionGadgetsBundle.message("package.info.java.without.package.display.name"); + } + + @NotNull + @Override + protected String buildErrorString(Object... infos) { + return InspectionGadgetsBundle.message("package.info.without.package.problem.descriptor"); + } + + @Nullable + @Override + protected InspectionGadgetsFix buildFix(Object... infos) { + return new PackageInfoWithoutPackageFix((String)infos[0]); + } + + private static class PackageInfoWithoutPackageFix extends InspectionGadgetsFix { + + private final String myPackageName; + + public PackageInfoWithoutPackageFix(String packageName) { + myPackageName = packageName; + } + + @NotNull + @Override + public String getName() { + return InspectionGadgetsBundle.message("package.info.without.package.quickfix", myPackageName); + } + + @NotNull + @Override + public String getFamilyName() { + return InspectionGadgetsBundle.message("package.info.without.package.family.quickfix"); + } + + @Override + protected void doFix(Project project, ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + if (!(element instanceof PsiJavaFile)) { + return; + } + final PsiJavaFile file = (PsiJavaFile)element; + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); + final PsiPackageStatement packageStatement = factory.createPackageStatement(myPackageName); + file.add(packageStatement); + } + } + + @Override + public BaseInspectionVisitor buildVisitor() { + return new PackageInfoWithoutPackageVisitor(); + } + + private static class PackageInfoWithoutPackageVisitor extends BaseInspectionVisitor { + + @Override + public void visitJavaFile(PsiJavaFile file) { + @NonNls final String name = file.getName(); + if (!PsiPackage.PACKAGE_INFO_FILE.equals(name)) { + return; + } + final PsiPackageStatement packageStatement = file.getPackageStatement(); + if (packageStatement != null) { + return; + } + final JavaDirectoryService directoryService = JavaDirectoryService.getInstance(); + final PsiDirectory directory = file.getContainingDirectory(); + final PsiPackage aPackage = directoryService.getPackage(directory); + if (aPackage == null) { + return; + } + final String packageName = aPackage.getQualifiedName(); + if (packageName.isEmpty()) { + return; + } + registerError(file, packageName); + } + } +} diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/CloneUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/CloneUtils.java index 0ac461beead4..64558049bbec 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/CloneUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/CloneUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,14 +20,14 @@ import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiUtil; import com.siyeh.HardcodedMethodConstants; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class CloneUtils { private CloneUtils() {} - public static boolean isCloneable(@NotNull PsiClass aClass) { - return InheritanceUtil.isInheritor(aClass, - CommonClassNames.JAVA_LANG_CLONEABLE); + public static boolean isCloneable(@Nullable PsiClass aClass) { + return InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_CLONEABLE); } public static boolean isDirectlyCloneable(@NotNull PsiClass aClass) { diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/AutoCloseableResourceInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/AutoCloseableResourceInspection.java new file mode 100644 index 000000000000..420234af766a --- /dev/null +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/AutoCloseableResourceInspection.java @@ -0,0 +1,105 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.resources; + +import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.BaseInspection; +import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.psiutils.TypeUtils; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** + * @author Bas Leijdekkers + */ +public class AutoCloseableResourceInspection extends BaseInspection { + + @SuppressWarnings("PublicField") + public boolean ignoreFromMethodCall = false; + + @Nls + @NotNull + @Override + public String getDisplayName() { + return InspectionGadgetsBundle.message("auto.closeable.resource.display.name"); + } + + @NotNull + @Override + public String getID() { + return "resource"; // matches Eclipse inspection + } + + @NotNull + @Override + protected String buildErrorString(Object... infos) { + final PsiExpression expression = (PsiExpression)infos[0]; + final PsiType type = expression.getType(); + assert type != null; + final String text = type.getPresentableText(); + return InspectionGadgetsBundle.message("auto.closeable.resource.problem.descriptor", text); + } + + @Nullable + @Override + public JComponent createOptionsPanel() { + return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("auto.closeable.resource.returned.option"), + this, "ignoreFromMethodCall"); + } + + @Override + public BaseInspectionVisitor buildVisitor() { + return new AutoCloseableResourceVisitor(); + } + + private class AutoCloseableResourceVisitor extends BaseInspectionVisitor { + + @Override + public void visitNewExpression(PsiNewExpression expression) { + super.visitNewExpression(expression); + checkExpression(expression); + } + + @Override + public void visitMethodCallExpression(PsiMethodCallExpression expression) { + super.visitMethodCallExpression(expression); + if (ignoreFromMethodCall) { + return; + } + checkExpression(expression); + } + + private void checkExpression(PsiExpression expression) { + if (!PsiUtil.isLanguageLevel7OrHigher(expression) || !TypeUtils.expressionHasTypeOrSubtype(expression, "java.lang.AutoCloseable")) { + return; + } + final PsiVariable variable = ResourceInspection.getVariable(expression); + if (variable instanceof PsiResourceVariable) { + return; + } + if (ResourceInspection.isResourceEscapingFromMethod(variable, expression)) { + return; + } + registerError(expression, expression); + } + } +} diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/ResourceInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/ResourceInspection.java index 67f5c3373124..0271e4e5de13 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/ResourceInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/ResourceInspection.java @@ -74,6 +74,9 @@ public abstract class ResourceInspection extends BaseInspection { return; } final PsiVariable boundVariable = getVariable(expression); + if (boundVariable instanceof PsiResourceVariable) { + return; + } if (isSafelyClosed(boundVariable, expression, insideTryAllowed)) { return; } @@ -94,7 +97,7 @@ public abstract class ResourceInspection extends BaseInspection { } @Nullable - private static PsiVariable getVariable(@NotNull PsiExpression expression) { + public static PsiVariable getVariable(@NotNull PsiExpression expression) { final PsiElement parent = ParenthesesUtils.getParentSkipParentheses(expression); if (parent instanceof PsiAssignmentExpression) { final PsiAssignmentExpression assignment = (PsiAssignmentExpression)parent; @@ -261,9 +264,9 @@ public abstract class ResourceInspection extends BaseInspection { return referent != null && referent.equals(resource); } - private static boolean isResourceEscapingFromMethod(PsiVariable boundVariable, PsiExpression resourceCreationExpression) { + public static boolean isResourceEscapingFromMethod(PsiVariable boundVariable, PsiExpression resourceCreationExpression) { final PsiElement parent = ParenthesesUtils.getParentSkipParentheses(resourceCreationExpression); - if (parent instanceof PsiReturnStatement || parent instanceof PsiResourceVariable) { + if (parent instanceof PsiReturnStatement) { return true; } else if (parent instanceof PsiAssignmentExpression) { diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/ComparatorNotSerializableInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/ComparatorNotSerializableInspection.java index df29cc5e3af4..38973204972c 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/ComparatorNotSerializableInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/ComparatorNotSerializableInspection.java @@ -23,7 +23,7 @@ import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.fixes.MakeSerializableFix; +import com.siyeh.ig.fixes.DelegatingFixFactory; import com.siyeh.ig.psiutils.SerializationUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -45,7 +45,7 @@ public class ComparatorNotSerializableInspection extends BaseInspection { @Override @Nullable protected InspectionGadgetsFix buildFix(Object... infos) { - return new MakeSerializableFix(); + return DelegatingFixFactory.createMakeSerializableFix((PsiClass)infos[0]); } @Override @@ -61,7 +61,7 @@ public class ComparatorNotSerializableInspection extends BaseInspection { SerializationUtils.isSerializable(aClass)) { return; } - registerClassError(aClass); + registerClassError(aClass, aClass); } } }
\ No newline at end of file diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/NonSerializableWithSerialVersionUIDFieldInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/NonSerializableWithSerialVersionUIDFieldInspection.java index 9a1d7ca0a280..a9b44ac6cf47 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/NonSerializableWithSerialVersionUIDFieldInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/NonSerializableWithSerialVersionUIDFieldInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,18 +21,16 @@ import com.intellij.psi.PsiAnonymousClass; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiField; -import com.intellij.util.IncorrectOperationException; import com.siyeh.HardcodedMethodConstants; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.fixes.MakeSerializableFix; +import com.siyeh.ig.fixes.DelegatingFixFactory; import com.siyeh.ig.psiutils.SerializationUtils; import org.jetbrains.annotations.NotNull; -public class NonSerializableWithSerialVersionUIDFieldInspection - extends BaseInspection { +public class NonSerializableWithSerialVersionUIDFieldInspection extends BaseInspection { @Override @NotNull @@ -43,8 +41,7 @@ public class NonSerializableWithSerialVersionUIDFieldInspection @Override @NotNull public String getDisplayName() { - return InspectionGadgetsBundle.message( - "non.serializable.with.serialversionuid.display.name"); + return InspectionGadgetsBundle.message("non.serializable.with.serialversionuid.display.name"); } @Override @@ -73,20 +70,18 @@ public class NonSerializableWithSerialVersionUIDFieldInspection @NotNull protected InspectionGadgetsFix[] buildFixes(Object... infos) { final PsiClass aClass = (PsiClass)infos[0]; - if (aClass.isAnnotationType() || aClass.isInterface() || - aClass instanceof PsiAnonymousClass) { + if (aClass.isAnnotationType() || aClass.isInterface() || aClass instanceof PsiAnonymousClass) { return new InspectionGadgetsFix[]{new RemoveSerialVersionUIDFix()}; } - return new InspectionGadgetsFix[]{new MakeSerializableFix(), - new RemoveSerialVersionUIDFix()}; + return new InspectionGadgetsFix[]{DelegatingFixFactory.createMakeSerializableFix(aClass), new RemoveSerialVersionUIDFix()}; } private static class RemoveSerialVersionUIDFix extends InspectionGadgetsFix { - @Override - @NotNull - public String getFamilyName() { - return getName(); - } + @Override + @NotNull + public String getFamilyName() { + return getName(); + } @Override @NotNull @@ -96,12 +91,10 @@ public class NonSerializableWithSerialVersionUIDFieldInspection } @Override - public void doFix(Project project, ProblemDescriptor descriptor) - throws IncorrectOperationException { + public void doFix(Project project, ProblemDescriptor descriptor) { final PsiElement nameElement = descriptor.getPsiElement(); final PsiClass aClass = (PsiClass)nameElement.getParent(); - final PsiField field = aClass.findFieldByName( - HardcodedMethodConstants.SERIAL_VERSION_UID, false); + final PsiField field = aClass.findFieldByName(HardcodedMethodConstants.SERIAL_VERSION_UID, false); if (field == null) { return; } @@ -114,14 +107,11 @@ public class NonSerializableWithSerialVersionUIDFieldInspection return new NonSerializableWithSerialVersionUIDVisitor(); } - private static class NonSerializableWithSerialVersionUIDVisitor - extends BaseInspectionVisitor { + private static class NonSerializableWithSerialVersionUIDVisitor extends BaseInspectionVisitor { @Override public void visitClass(@NotNull PsiClass aClass) { - // no call to super, so it doesn't drill down - final PsiField field = aClass.findFieldByName( - HardcodedMethodConstants.SERIAL_VERSION_UID, false); + final PsiField field = aClass.findFieldByName(HardcodedMethodConstants.SERIAL_VERSION_UID, false); if (field == null) { return; } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/NonSerializableWithSerializationMethodsInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/NonSerializableWithSerializationMethodsInspection.java index bbadd7f5b65e..4a0750a6c8a4 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/NonSerializableWithSerializationMethodsInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/NonSerializableWithSerializationMethodsInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,18 +15,17 @@ */ package com.siyeh.ig.serialization; -import com.intellij.psi.PsiClass; import com.intellij.psi.PsiAnonymousClass; +import com.intellij.psi.PsiClass; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.fixes.MakeSerializableFix; +import com.siyeh.ig.fixes.DelegatingFixFactory; import com.siyeh.ig.psiutils.SerializationUtils; import org.jetbrains.annotations.NotNull; -public class NonSerializableWithSerializationMethodsInspection - extends BaseInspection { +public class NonSerializableWithSerializationMethodsInspection extends BaseInspection { @Override @NotNull @@ -37,16 +36,16 @@ public class NonSerializableWithSerializationMethodsInspection @Override @NotNull public String getDisplayName() { - return InspectionGadgetsBundle.message( - "non.serializable.class.with.readwriteobject.display.name"); + return InspectionGadgetsBundle.message("non.serializable.class.with.readwriteobject.display.name"); } @Override protected InspectionGadgetsFix buildFix(Object... infos) { - if (infos[2] instanceof PsiAnonymousClass) { + final PsiClass aClass = (PsiClass)infos[2]; + if (aClass instanceof PsiAnonymousClass) { return null; } - return new MakeSerializableFix(); + return DelegatingFixFactory.createMakeSerializableFix(aClass); } @Override @@ -87,30 +86,25 @@ public class NonSerializableWithSerializationMethodsInspection @Override public BaseInspectionVisitor buildVisitor() { - return new NonserializableDefinesSerializationMethodsVisitor(); + return new NonSerializableWithSerializationMethodsVisitor(); } - private static class NonserializableDefinesSerializationMethodsVisitor - extends BaseInspectionVisitor { + private static class NonSerializableWithSerializationMethodsVisitor extends BaseInspectionVisitor { @Override public void visitClass(@NotNull PsiClass aClass) { - // no call to super, so it doesn't drill down if (aClass.isInterface() || aClass.isAnnotationType()) { return; } - final boolean hasReadObject = - SerializationUtils.hasReadObject(aClass); - final boolean hasWriteObject = - SerializationUtils.hasWriteObject(aClass); + final boolean hasReadObject = SerializationUtils.hasReadObject(aClass); + final boolean hasWriteObject = SerializationUtils.hasWriteObject(aClass); if (!hasWriteObject && !hasReadObject) { return; } if (SerializationUtils.isSerializable(aClass)) { return; } - registerClassError(aClass, Boolean.valueOf(hasReadObject), - Boolean.valueOf(hasWriteObject), aClass); + registerClassError(aClass, Boolean.valueOf(hasReadObject), Boolean.valueOf(hasWriteObject), aClass); } } }
\ No newline at end of file diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java index 0d086823efc4..7e096d987ffa 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java @@ -222,7 +222,13 @@ public class StringBufferReplaceableByStringInspection extends BaseInspection { if (type instanceof PsiPrimitiveType) { if (argument instanceof PsiLiteralExpression) { final PsiLiteralExpression literalExpression = (PsiLiteralExpression)argument; - result.append('"').append(literalExpression.getValue()).append('"'); + if (PsiType.CHAR.equals(literalExpression.getType())) { + final String text = literalExpression.getText(); + result.append('"').append(text.substring(1, text.length() - 1)).append('"'); + } + else { + result.append('"').append(literalExpression.getValue()).append('"'); + } } else { result.append("String.valueOf(").append(argumentText).append(")"); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/javadoc/PackageDotHtmlMayBePackageInfoInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/javadoc/PackageDotHtmlMayBePackageInfoInspection.java index e7ac10a33609..c99aa3373dbd 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/javadoc/PackageDotHtmlMayBePackageInfoInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/javadoc/PackageDotHtmlMayBePackageInfoInspection.java @@ -154,7 +154,7 @@ public class PackageDotHtmlMayBePackageInfoInspection extends BaseInspection { final String[] lines = StringUtil.splitByLines(packageInfoText); boolean appended = false; for (String line : lines) { - if (!appended && line.length() == 0) { + if (!appended && line.isEmpty()) { // skip empty lines at the beginning continue; } @@ -163,7 +163,7 @@ public class PackageDotHtmlMayBePackageInfoInspection extends BaseInspection { } commentText.append("*/"); final PsiDocComment comment = elementFactory.createDocCommentFromText(commentText.toString()); - if (aPackage.length() > 0) { + if (!aPackage.isEmpty()) { final PsiPackageStatement packageStatement = elementFactory.createPackageStatement(aPackage); final PsiElement addedElement = file.add(packageStatement); file.addBefore(comment, addedElement); @@ -211,7 +211,7 @@ public class PackageDotHtmlMayBePackageInfoInspection extends BaseInspection { } final HtmlTag htmlTag = (HtmlTag)child; @NonNls final String name = htmlTag.getName(); - if ("body".equals(name)) { + if ("body".equalsIgnoreCase(name)) { final XmlTagValue value = htmlTag.getValue(); return value.getText(); } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java index 175b0efd09fa..ef1591864c0e 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java @@ -19,13 +19,13 @@ import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.openapi.project.Project; import com.intellij.psi.*; -import com.intellij.psi.search.searches.SuperMethodsSearch; import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.psiutils.LibraryUtil; +import com.siyeh.ig.psiutils.MethodUtils; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -57,7 +57,7 @@ public class MethodCanBeVariableArityMethodInspection extends BaseInspection { final MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this); panel.addCheckbox(InspectionGadgetsBundle.message("method.can.be.variable.arity.method.ignore.byte.short.option"), "ignoreByteAndShortArrayParameters"); - panel.addCheckbox(InspectionGadgetsBundle.message("method.can.be.variable.arity.method.ignore.overriding.methods"), + panel.addCheckbox(InspectionGadgetsBundle.message("ignore.methods.overriding.super.method"), "ignoreOverridingMethods"); return panel; } @@ -149,7 +149,7 @@ public class MethodCanBeVariableArityMethodInspection extends BaseInspection { if (LibraryUtil.isOverrideOfLibraryMethod(method)) { return; } - if (ignoreOverridingMethods && SuperMethodsSearch.search(method, null, true, false).findFirst() != null) { + if (ignoreOverridingMethods && MethodUtils.hasSuper(method)) { return; } registerMethodError(method); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/naming/MethodNamesDifferOnlyByCaseInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/naming/MethodNamesDifferOnlyByCaseInspection.java index b570d2149b11..2739510e3af1 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/naming/MethodNamesDifferOnlyByCaseInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/naming/MethodNamesDifferOnlyByCaseInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +54,7 @@ public class MethodNamesDifferOnlyByCaseInspection extends BaseInspection { @Override public JComponent createOptionsPanel() { - return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("method.names.differ.only.by.case.ignore.override.option"), + return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("ignore.methods.overriding.super.method"), this, "ignoreIfMethodIsOverride"); } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/ui/UiUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/ui/UiUtils.java index 0adb02b76f42..711df9f6be27 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/ui/UiUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/ui/UiUtils.java @@ -21,6 +21,7 @@ import com.intellij.ide.DataManager; import com.intellij.ide.util.ClassFilter; import com.intellij.ide.util.TreeClassChooser; import com.intellij.ide.util.TreeClassChooserFactory; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; @@ -80,7 +81,7 @@ public class UiUtils { @Override public void run(AnActionButton button) { final DataContext dataContext = DataManager.getInstance().getDataContext(table); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); final int rowIndex; final ListWrappingTableModel tableModel = table.getModel(); if (project == null) { @@ -150,7 +151,7 @@ public class UiUtils { @Override public void run(AnActionButton anActionButton) { final DataContext dataContext = DataManager.getInstance().getDataContext(list); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null) { return; } diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AutoCloseableResource.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AutoCloseableResource.html new file mode 100644 index 000000000000..213e8a7ee175 --- /dev/null +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AutoCloseableResource.html @@ -0,0 +1,9 @@ +<html> +<body> +Reports <b>AutoCloseable</b> instances which are not used in a <b>try</b>-with-resources statement, also known as <i>Automatic Resource Management</i>. +This means that the open resource before/in <b>try</b>, close in <b>finally</b> style which was used before <b>try</b>-with-resources was available is also reported. +This inspection is meant to replace all <i>opened but not safely closed</i> inspections when developing in Java 7. +<p> +<small>New in 13</small> +</body> +</html>
\ No newline at end of file diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCanBeVariableArityMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCanBeVariableArityMethod.html index 1c5b2557364c..0c97059e474b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCanBeVariableArityMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCanBeVariableArityMethod.html @@ -9,7 +9,7 @@ language level of 5.0 or higher. <p> Use the first checkbox below to not offer to convert byte[] or short[] parameters to vararg. <p> -Use the second checkbox below to ignore methods overriding a method in a super class. +Use the second checkbox below to ignore methods overriding or implementing a method from a superclass. <p> <small>New in 10.5</small> </body> diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCount.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCount.html index 9c7dfd43776f..084d5d6f1704 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCount.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCount.html @@ -7,7 +7,9 @@ refactored into multiple smaller classes. <p> Use the field below to specify the maximum number of methods a class is allowed to have. <p> -Use the checkbox below to specify that simple getters and setters should be ignored in the method count. +Use the first checkbox below to ignore simple getters and setters in the method count. +<p> +Use the second checkbox below to ignore methods overriding or implementing a method from a superclass <p> </body> diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNamesDifferOnlyByCase.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNamesDifferOnlyByCase.html index befcbf45c171..14bd87936549 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNamesDifferOnlyByCase.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNamesDifferOnlyByCase.html @@ -3,8 +3,7 @@ Reports on cases where multiple methods of a class have names which differ only by case. Such method names may be very confusing. <!-- tooltip end --> -<p>Use the checkbox below to have this inspection ignore methods which are overrides or implementations of -super methods. +<p>Use the checkbox below to ignore methods overriding or implementing a method from a superclass. <p> </body> diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MissingPackageInfo.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MissingPackageInfo.html new file mode 100644 index 000000000000..31cb1625ca88 --- /dev/null +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MissingPackageInfo.html @@ -0,0 +1,11 @@ +<html> +<body> +Reports packages that contain classes but do not contain a <b>package-info.java</b> or <b>package.html</b> file and thus are +missing package documentation. +Because this inspection requires global code analysis it is only available for <em>Analyze|Inspect Code</em> or +<em>Analyze|Run Inspection by Name</em> and it will not report in the editor. +<!-- tooltip end --> +<p> +<small>New in 13</small> +</body> +</html>
\ No newline at end of file diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageDotHtmlMayBePackageInfo.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageDotHtmlMayBePackageInfo.html index cbf1c7319eea..137c12f4c478 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageDotHtmlMayBePackageInfo.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageDotHtmlMayBePackageInfo.html @@ -1,15 +1,8 @@ <html> <body> -Reports any package.html files. These files are used for documenting -packages. Since J2SE 5 it is recommended to use package-info.java files instead, since such +Reports any <b>package.html</b> files. These files are used for documenting +packages. Since J2SE 5 it is recommended to use <b>package-info.java</b> files instead, since such files can also contain package annotations. In this way, package-info.java becomes the sole repository for package level annotations and documentation. -<p> -This inspection provides a quickfix to convert the package.html file to a package-info.java file. -If a package-info.java file is already present this inspection provides a quickfix to delete -the package.html file, since the Javadoc tool would ignore it then anyway. -<!-- tooltip end --> -<p> -<small>New in 10.0.3</small> </body> </html>
\ No newline at end of file diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageInfoWithoutPackage.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageInfoWithoutPackage.html new file mode 100644 index 000000000000..6290624778ee --- /dev/null +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageInfoWithoutPackage.html @@ -0,0 +1,9 @@ +<html> +<body> +Reports <b>package-info.java</b> files without a <b>package</b> statement. +The Javadoc tool considers such files documentation for the default package even when the file is located somewhere else. +<!-- tooltip end --> +<p> +<small>New in 13</small> +</body> +</html>
\ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/serialization/comparator/ExtendsInterface.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/serialization/comparator/ExtendsInterface.after.java index 69ae8d1968c6..d3c6797c69d7 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igfixes/serialization/comparator/ExtendsInterface.after.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/serialization/comparator/ExtendsInterface.after.java @@ -1,4 +1,4 @@ import java.io.Serializable; import java.util.Comparator; -interface ExtendsInterface extends Comparator<ExtendsInterface>,Serializable {}
\ No newline at end of file +interface ExtendsInterface extends Comparator<ExtendsInterface>, Serializable {}
\ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/serialization/comparator/ImplementsClass.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/serialization/comparator/ImplementsClass.after.java index d09ff0833a58..b2b004ac5235 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igfixes/serialization/comparator/ImplementsClass.after.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/serialization/comparator/ImplementsClass.after.java @@ -1,6 +1,6 @@ import java.io.Serializable; import java.util.Comparator; -abstract class ImplementsClass implements Comparator<ImplementsClass>,Serializable { +abstract class ImplementsClass implements Comparator<ImplementsClass>, Serializable { }
\ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/CharLiteral.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/CharLiteral.after.java new file mode 100644 index 000000000000..55ed9d63b1d2 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/CharLiteral.after.java @@ -0,0 +1,5 @@ +class CharLiteral { + void literal() { + System.out.println("\t"); + } +}
\ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/CharLiteral.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/CharLiteral.java new file mode 100644 index 000000000000..d0986c765e1c --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/CharLiteral.java @@ -0,0 +1,6 @@ +class CharLiteral { + void literal() { + StringBuilder <caret>sb = new StringBuilder().append('\t'); + System.out.println(sb.toString()); + } +}
\ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/classmetrics/ConstructorCountInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/classmetrics/ConstructorCountInspection.java deleted file mode 100644 index 5eb1247adc33..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/classmetrics/ConstructorCountInspection.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.siyeh.igtest.classmetrics; - -public class ConstructorCountInspection -{ - public ConstructorCountInspection(int i){} - - public ConstructorCountInspection(boolean ch){} - - public ConstructorCountInspection(char b){} - - public ConstructorCountInspection(float d){} - - public ConstructorCountInspection(double f){} - - public ConstructorCountInspection(long s){} -} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/classmetrics/MethodCountInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/classmetrics/MethodCountInspection.java deleted file mode 100644 index 51b2abeaf530..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/classmetrics/MethodCountInspection.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.siyeh.igtest.classmetrics; - -public class MethodCountInspection -{ - public void aaa(){} - - public void bbb(){} - - public void ccc(){} - - public void ddd(){} - - public void eee(){} - - public void fff(){} - - public void ggg(){} - - public void hhh(){} - - public void iii(){} - - public void jjj(){} - - public void kkk(){} - - public void lll(){} - - public void mmm(){} - - public void nnn(){} - - public void ooo(){} - - public void ppp(){} - - public void qqq(){} - - public void rrr(){} - - public void sss(){} - - public void ttt(){} - - public void aaa2(){} - - public void bbb2(){} - - public void ccc2(){} - - public void ddd2(){} - - public void eee2(){} - - public void fff2(){} - - public void ggg2(){} - - public void hhh2(){} - - public void iii2(){} - - public void jjj2(){} - - public void kkk2(){} - - public void lll2(){} - - public void mmm2(){} - - public void nnn2(){} - - public void ooo2(){} - - public void ppp2(){} - - public void qqq2(){} - - public void rrr2(){} - - public void sss2(){} - - public void ttt2(){} -} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/classmetrics/method_count/MethodCount.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/classmetrics/method_count/MethodCount.java new file mode 100644 index 000000000000..0eaea16eb0a4 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/classmetrics/method_count/MethodCount.java @@ -0,0 +1,48 @@ +package com.siyeh.igtest.classmetrics.method_count; + +public class MethodCount { + public void one() {} + public void two() {} + public void three() {} + public void four() {} + public void five() {} + public void six() {} +} +class NotTooMany { + public void one() {} + public void two() {} + public void three() {} + public void four() {} + public void five() {} +} +class SuperMethods { + + public void one() {} + public void two() {} + public void three() {} + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + protected Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public String toString() { + return super.toString(); + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + } +} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/classmetrics/method_count/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/classmetrics/method_count/expected.xml new file mode 100644 index 000000000000..37e0052fb31e --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/classmetrics/method_count/expected.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<problems> + <problem> + <file>MethodCount.java</file> + <line>3</line> + <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Class with too many methods</problem_class> + <description><code>MethodCount</code> has too many methods (method count = 6) #loc</description> + </problem> +</problems>
\ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/missing_package_info/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/missing_package_info/expected.xml new file mode 100644 index 000000000000..4862cd420e22 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/missing_package_info/expected.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<problems> + <problem> + <entry_point TYPE="package" FQNAME="one.two.three" /> + <problem_class>Missing 'package-info.java'</problem_class> + <hints /> + <description>Package 'one.two.three' is missing a <code>package-info.java</code> file</description> + </problem> +</problems>
\ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/missing_package_info/src/one/two/three/X.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/missing_package_info/src/one/two/three/X.java new file mode 100644 index 000000000000..9b9b6e511385 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/missing_package_info/src/one/two/three/X.java @@ -0,0 +1,4 @@ +package one.two.three; + +public class X { +} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/package_info_without_package/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/package_info_without_package/expected.xml new file mode 100644 index 000000000000..030404f0fdac --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/package_info_without_package/expected.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<problems> + <problem> + <file>package-info.java</file> + <line>1</line> + <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'package-info.java' without 'package' statement</problem_class> + <description>'package-info.java' does not have a package statement</description> + </problem> +</problems>
\ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/package_info_without_package/src/one/two/package-info.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/package_info_without_package/src/one/two/package-info.java new file mode 100644 index 000000000000..1a60ed728e5e --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/package_info_without_package/src/one/two/package-info.java @@ -0,0 +1 @@ +package one.two;
\ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/package_info_without_package/src/one/two/three/package-info.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/package_info_without_package/src/one/two/three/package-info.java new file mode 100644 index 000000000000..2af8f700b6a9 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/package_info_without_package/src/one/two/three/package-info.java @@ -0,0 +1,3 @@ +/** + * Some explanation for the existence of this package + */
\ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classmetrics/MethodCountInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classmetrics/MethodCountInspectionTest.java new file mode 100644 index 000000000000..a62ddc94002e --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classmetrics/MethodCountInspectionTest.java @@ -0,0 +1,13 @@ +package com.siyeh.ig.classmetrics; + +import com.siyeh.ig.IGInspectionTestCase; + +public class MethodCountInspectionTest extends IGInspectionTestCase { + + public void test() throws Exception { + final MethodCountInspection tool = new MethodCountInspection(); + tool.m_limit = 5; + tool.ignoreOverridingMethods = true; + doTest("com/siyeh/igtest/classmetrics/method_count", tool); + } +}
\ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/serialization/MakeSerializableFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/serialization/MakeSerializableFixTest.java index 31a902620342..cbb60b84f4c0 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/serialization/MakeSerializableFixTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/serialization/MakeSerializableFixTest.java @@ -13,14 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * (c) 2013 Desert Island BV - * created: 16 09 2013 - */ package com.siyeh.ig.fixes.serialization; -import com.siyeh.InspectionGadgetsBundle; +import com.intellij.codeInsight.daemon.QuickFixBundle; import com.siyeh.ig.IGQuickFixesTestCase; import com.siyeh.ig.serialization.ComparatorNotSerializableInspection; @@ -34,9 +29,8 @@ public class MakeSerializableFixTest extends IGQuickFixesTestCase { super.setUp(); myFixture.enableInspections(new ComparatorNotSerializableInspection()); myRelativePath = "serialization/comparator"; - myDefaultHint = InspectionGadgetsBundle.message("make.class.serializable.quickfix"); } - public void testExtendsInterface() { doTest(); } - public void testImplementsClass() { doTest(); } + public void testExtendsInterface() { doTest(QuickFixBundle.message("add.class.to.extends.list", "ExtendsInterface", "java.io.Serializable")); } + public void testImplementsClass() { doTest(QuickFixBundle.message("add.interface.to.implements.list", "ImplementsClass", "java.io.Serializable")); } } diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/style/StringBufferReplaceableWithStringFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/style/StringBufferReplaceableWithStringFixTest.java index bf86b3717d04..a84852135904 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/style/StringBufferReplaceableWithStringFixTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/style/StringBufferReplaceableWithStringFixTest.java @@ -29,4 +29,5 @@ public class StringBufferReplaceableWithStringFixTest extends IGQuickFixesTestCa public void testConstructorArgument() { doTest(InspectionGadgetsBundle.message("string.builder.replaceable.by.string.quickfix")); } public void testConstructorArgument2() { doTest(InspectionGadgetsBundle.message("string.builder.replaceable.by.string.quickfix")); } public void testNoConstructorArgument() { doTest(InspectionGadgetsBundle.message("string.builder.replaceable.by.string.quickfix")); } + public void testCharLiteral() { doTest(InspectionGadgetsBundle.message("string.builder.replaceable.by.string.quickfix")); } } diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/javadoc/MissingPackageInfoInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/javadoc/MissingPackageInfoInspectionTest.java new file mode 100644 index 000000000000..b2ce613c3a33 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/javadoc/MissingPackageInfoInspectionTest.java @@ -0,0 +1,17 @@ +/** + * (c) 2013 Desert Island BV + * created: 27 09 2013 + */ +package com.siyeh.ig.javadoc; + +import com.siyeh.ig.IGInspectionTestCase; + +/** + * @author Bas Leijdekkers + */ +public class MissingPackageInfoInspectionTest extends IGInspectionTestCase { + + public void test() { + doTest("com/siyeh/igtest/javadoc/missing_package_info", new MissingPackageInfoInspection()); + } +} diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/javadoc/PackageInfoWithoutPackageInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/javadoc/PackageInfoWithoutPackageInspectionTest.java new file mode 100644 index 000000000000..ed3862556c4a --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/javadoc/PackageInfoWithoutPackageInspectionTest.java @@ -0,0 +1,28 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.javadoc; + +import com.siyeh.ig.IGInspectionTestCase; + +/** + * @author Bas Leijdekkers + */ +public class PackageInfoWithoutPackageInspectionTest extends IGInspectionTestCase { + + public void test() { + doTest("com/siyeh/igtest/javadoc/package_info_without_package", new PackageInfoWithoutPackageInspection()); + } +} diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/AutoCloseableResourceInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/AutoCloseableResourceInspectionTest.java new file mode 100644 index 000000000000..a42941959741 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/AutoCloseableResourceInspectionTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.resources; + +import com.intellij.codeInspection.LocalInspectionTool; +import com.siyeh.ig.LightInspectionTestCase; + +/** + * @author Bas Leijdekkers + */ +public class AutoCloseableResourceInspectionTest extends LightInspectionTestCase { + + public void testCorrectClose() { + doTest("import java.io.*;" + + "class X {" + + " public void m() throws IOException {" + + " FileInputStream str;" + + " str = /*'FileInputStream' used without 'try'-with-resources statement*/new FileInputStream(\"bar\")/**/;" + + " try {" + + " } finally {" + + " str.close();" + + " }" + + " }" + + "}"); + } + + public void testARM() { + doTest("import java.sql.*;\n" + + "class X {\n" + + " void m(Driver driver) throws SQLException {\n" + + " try (Connection connection = driver.connect(\"jdbc\", null);\n" + + " PreparedStatement statement = connection.prepareStatement(\"SELECT *\");\n" + + " ResultSet resultSet = statement.executeQuery()) {\n" + + " while (resultSet.next()) { resultSet.getMetaData(); }\n" + + " }\n" + + " }\n" + + "}"); + } + + public void testSimple() { + doTest("import java.sql.*;" + + "class X {" + + " void m(Driver driver) throws SQLException {" + + " /*'Connection' used without 'try'-with-resources statement*/driver.connect(\"jdbc\", null)/**/;" + + " }" + + "}"); + } + + @Override + protected LocalInspectionTool getInspection() { + return new AutoCloseableResourceInspection(); + } +} diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.java index 6463242e8ba4..36da2a930603 100644 --- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.java +++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.java @@ -392,11 +392,11 @@ public class MethodParameterPanel extends AbstractInjectionPanel<MethodParameter } public void calcData(final DataKey key, final DataSink sink) { - if (LangDataKeys.PSI_ELEMENT.equals(key)) { + if (CommonDataKeys.PSI_ELEMENT.equals(key)) { final Collection selection = getSelection(); if (!selection.isEmpty()) { final Object o = ((DefaultMutableTreeNode)selection.iterator().next()).getUserObject(); - if (o instanceof PsiElement) sink.put(LangDataKeys.PSI_ELEMENT, (PsiElement)o); + if (o instanceof PsiElement) sink.put(CommonDataKeys.PSI_ELEMENT, (PsiElement)o); } } } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfIntention.java index ccdc0c3ee621..6d22d8e12eeb 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfIntention.java @@ -15,11 +15,14 @@ */ package com.siyeh.ipp.conditional; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.util.ArrayUtilRt; import com.intellij.util.IncorrectOperationException; import com.siyeh.ig.psiutils.ParenthesesUtils; import com.siyeh.ipp.base.Intention; @@ -29,6 +32,8 @@ import org.jetbrains.annotations.Nullable; public class ReplaceConditionalWithIfIntention extends Intention { + private static final Logger LOG = Logger.getInstance("#" + ReplaceConditionalWithIfIntention.class.getName()); + @Override @NotNull public PsiElementPredicate getElementPredicate() { @@ -53,8 +58,8 @@ public class ReplaceConditionalWithIfIntention extends Intention { else { variable = null; } - final PsiExpression thenExpression = expression.getThenExpression(); - final PsiExpression elseExpression = expression.getElseExpression(); + PsiExpression thenExpression = expression.getThenExpression(); + PsiExpression elseExpression = expression.getElseExpression(); final PsiExpression condition = expression.getCondition(); final PsiExpression strippedCondition = ParenthesesUtils.stripParentheses(condition); final StringBuilder newStatement = new StringBuilder(); @@ -67,10 +72,21 @@ public class ReplaceConditionalWithIfIntention extends Intention { final String name = variable.getName(); newStatement.append(name); newStatement.append('='); - final PsiExpression initializer = variable.getInitializer(); + PsiExpression initializer = variable.getInitializer(); if (initializer == null) { return; } + if (initializer instanceof PsiArrayInitializerExpression) { + final int conditionIdx = ArrayUtilRt.find(((PsiArrayInitializerExpression)initializer).getInitializers(), expression); + if (conditionIdx >= 0) { + initializer = (PsiExpression)initializer.replace(RefactoringUtil.convertInitializerToNormalExpression(initializer, variable.getType())); + final PsiArrayInitializerExpression arrayInitializer = ((PsiNewExpression)initializer).getArrayInitializer(); + LOG.assertTrue(arrayInitializer != null, initializer.getText()); + expression = (PsiConditionalExpression)arrayInitializer.getInitializers()[conditionIdx]; + thenExpression = expression.getThenExpression(); + elseExpression = expression.getElseExpression(); + } + } appendElementTextWithoutParentheses(initializer, expression, thenExpression, newStatement); newStatement.append("; else "); newStatement.append(name); diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java index b6eee7d1cdd5..e885764e6ecd 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java @@ -87,11 +87,7 @@ public class UnicodeUnescapeIntention extends Intention { /** * see JLS 3.3. Unicode Escapes */ - private static int indexOfUnicodeEscape(String text, int offset) { - if (text == null) { - // apparently an editor can have a selection, but still null for selected text. - return -1; - } + private static int indexOfUnicodeEscape(@NotNull String text, int offset) { final int length = text.length(); for (int i = 0; i < length; i++) { final char c = text.charAt(i); @@ -146,7 +142,8 @@ public class UnicodeUnescapeIntention extends Intention { final SelectionModel selectionModel = editor.getSelectionModel(); if (selectionModel.hasSelection()) { final String text = selectionModel.getSelectedText(); - return indexOfUnicodeEscape(text, 1) >= 0; + // an editor can have a selection, but still null for selected text (because of threading?). + return text != null && indexOfUnicodeEscape(text, 1) >= 0; } else { final CaretModel caretModel = editor.getCaretModel(); diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/varargs/MakeMethodVarargsIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/varargs/MakeMethodVarargsIntention.java index 016d4bd396f5..2b0617c673a6 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/varargs/MakeMethodVarargsIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/varargs/MakeMethodVarargsIntention.java @@ -15,6 +15,7 @@ */ package com.siyeh.ipp.varargs; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.util.IncorrectOperationException; @@ -25,6 +26,8 @@ import org.jetbrains.annotations.NotNull; public class MakeMethodVarargsIntention extends Intention { + private static final Logger LOG = Logger.getInstance("#" + MakeMethodVarargsIntention.class.getName()); + @NotNull protected PsiElementPredicate getElementPredicate() { return new MakeMethodVarargsPredicate(); @@ -42,14 +45,11 @@ public class MakeMethodVarargsIntention extends Intention { final PsiParameter[] parameters = parameterList.getParameters(); final PsiParameter lastParameter = parameters[parameters.length - 1]; final PsiType type = lastParameter.getType(); - final PsiType componentType = type.getDeepComponentType(); - final String text = componentType.getCanonicalText(); - final PsiManager manager = element.getManager(); - final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); - final PsiParameter newParameter = - factory.createParameterFromText(text + "... " + - lastParameter.getName(), element); - lastParameter.replace(newParameter); + final PsiElementFactory factory = JavaPsiFacade.getInstance(element.getProject()).getElementFactory(); + final PsiTypeElement typeElement = lastParameter.getTypeElement(); + LOG.assertTrue(typeElement != null); + final PsiType ellipsisType = PsiEllipsisType.createEllipsis(((PsiArrayType)type).getComponentType(), type.getAnnotations()); + typeElement.replace(factory.createTypeElement(ellipsisType)); } private static void makeMethodCallsVarargs(PsiElement element) diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/conditional/withIf/ArrayInitializer.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/conditional/withIf/ArrayInitializer.java new file mode 100644 index 000000000000..68f0375e149c --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/conditional/withIf/ArrayInitializer.java @@ -0,0 +1,5 @@ +class Test { + void f(boolean b){ + String [] s = {b <caret>? "a" : "c"}; + } +}
\ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/conditional/withIf/ArrayInitializer_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/conditional/withIf/ArrayInitializer_after.java new file mode 100644 index 000000000000..022085f0a048 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/conditional/withIf/ArrayInitializer_after.java @@ -0,0 +1,7 @@ +class Test { + void f(boolean b){ + String [] s; + if (b) s = new String[]{"a"}; + else s = new String[]{"c"}; + } +}
\ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/varargs/make_method_varargs/DeepArray.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/varargs/make_method_varargs/DeepArray.java new file mode 100644 index 000000000000..eb62e9ad9d91 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/varargs/make_method_varargs/DeepArray.java @@ -0,0 +1,8 @@ +class Test { + public void foo(final String[][] a<caret>rg) { + } + + { + foo(new String[][]{}); + } +}
\ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/varargs/make_method_varargs/DeepArray_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/varargs/make_method_varargs/DeepArray_after.java new file mode 100644 index 000000000000..971148ca2481 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/varargs/make_method_varargs/DeepArray_after.java @@ -0,0 +1,8 @@ +class Test { + public void foo(final String[]... arg) { + } + + { + foo(); + } +}
\ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/varargs/make_method_varargs/Final.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/varargs/make_method_varargs/Final.java new file mode 100644 index 000000000000..1a36d0462efd --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/varargs/make_method_varargs/Final.java @@ -0,0 +1,8 @@ +class Test { + public void foo(final String[] a<caret>rg) { + } + + { + foo(new String[]{}); + } +}
\ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/varargs/make_method_varargs/Final_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/varargs/make_method_varargs/Final_after.java new file mode 100644 index 000000000000..412fd976d26d --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/varargs/make_method_varargs/Final_after.java @@ -0,0 +1,8 @@ +class Test { + public void foo(final String... arg) { + } + + { + foo(); + } +}
\ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/conditional/ReplaceConditionalWithIfTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/conditional/ReplaceConditionalWithIfTest.java index f2e32bb56f59..8ba24fdec63d 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/conditional/ReplaceConditionalWithIfTest.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/conditional/ReplaceConditionalWithIfTest.java @@ -28,6 +28,7 @@ public class ReplaceConditionalWithIfTest extends IPPTestCase { public void testParentheses() { doTest(); } public void testConditionalInIf() { doTest(); } public void testConditionalInBinaryExpression() { doTest(); } + public void testArrayInitializer() { doTest(); } @Override protected String getIntentionName() { diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/varargs/MakeMethodVarargsIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/varargs/MakeMethodVarargsIntentionTest.java new file mode 100644 index 000000000000..d034b2cc02f1 --- /dev/null +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/varargs/MakeMethodVarargsIntentionTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ipp.varargs; + +import com.siyeh.IntentionPowerPackBundle; +import com.siyeh.ipp.IPPTestCase; + +public class MakeMethodVarargsIntentionTest extends IPPTestCase { + + public void testFinal() { doTest(); } + public void testDeepArray() { doTest(); } + + @Override + protected String getRelativePath() { + return "varargs/make_method_varargs"; + } + + @Override + protected String getIntentionName() { + return IntentionPowerPackBundle.message("make.method.varargs.intention.name"); + } +}
\ No newline at end of file diff --git a/plugins/ant/src/com/intellij/lang/ant/config/actions/AddAntBuildFile.java b/plugins/ant/src/com/intellij/lang/ant/config/actions/AddAntBuildFile.java index f0082239a5e9..5248251c66ef 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/actions/AddAntBuildFile.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/actions/AddAntBuildFile.java @@ -34,8 +34,8 @@ import com.intellij.psi.xml.XmlTag; public class AddAntBuildFile extends AnAction { public void actionPerformed(AnActionEvent event) { DataContext dataContext = event.getDataContext(); - Project project = PlatformDataKeys.PROJECT.getData(dataContext); - VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + Project project = CommonDataKeys.PROJECT.getData(dataContext); + VirtualFile file = CommonDataKeys.VIRTUAL_FILE.getData(dataContext); AntConfiguration antConfiguration = AntConfiguration.getInstance(project); try { antConfiguration.addBuildFile(file); @@ -54,13 +54,13 @@ public class AddAntBuildFile extends AnAction { public void update(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); final Presentation presentation = e.getPresentation(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null) { disable(presentation); return; } - final VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + final VirtualFile file = CommonDataKeys.VIRTUAL_FILE.getData(dataContext); if (file == null) { disable(presentation); return; diff --git a/plugins/ant/src/com/intellij/lang/ant/config/actions/RunTargetAction.java b/plugins/ant/src/com/intellij/lang/ant/config/actions/RunTargetAction.java index bbfede6ff6e2..c7819826fd68 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/actions/RunTargetAction.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/actions/RunTargetAction.java @@ -83,13 +83,13 @@ public class RunTargetAction extends AnAction { private static Pair<AntBuildFileBase, AntDomTarget> findAntTarget(@NotNull AnActionEvent e) { final DataContext dataContext = e.getDataContext(); - final Editor editor = PlatformDataKeys.EDITOR.getData(dataContext); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Editor editor = CommonDataKeys.EDITOR.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null || editor == null) { return null; } - final VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + final VirtualFile file = CommonDataKeys.VIRTUAL_FILE.getData(dataContext); if (file == null) { return null; } diff --git a/plugins/ant/src/com/intellij/lang/ant/config/actions/TargetAction.java b/plugins/ant/src/com/intellij/lang/ant/config/actions/TargetAction.java index a30e1eb583e8..73358f639313 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/actions/TargetAction.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/actions/TargetAction.java @@ -53,7 +53,7 @@ public final class TargetAction extends DumbAwareAction { public void actionPerformed(AnActionEvent e) { DataContext dataContext = e.getDataContext(); - Project project = PlatformDataKeys.PROJECT.getData(dataContext); + Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null) return; for (final AntBuildFile buildFile : AntConfiguration.getInstance(project).getBuildFiles()) { diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/TreeView.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/TreeView.java index b0e2527c2e1a..3a03688d200d 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/execution/TreeView.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/TreeView.java @@ -365,7 +365,7 @@ public final class TreeView implements AntOutputView, OccurenceNavigator { final TreePath path = myTree.getLeadSelectionPath(); if (path == null) return; if (!(path.getLastPathComponent()instanceof MessageNode)) return; - if (getData(PlatformDataKeys.NAVIGATABLE_ARRAY.getName()) == null) return; + if (getData(CommonDataKeys.NAVIGATABLE_ARRAY.getName()) == null) return; DefaultActionGroup group = new DefaultActionGroup(); group.add(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE)); ActionPopupMenu menu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.ANT_MESSAGES_POPUP, group); @@ -382,7 +382,7 @@ public final class TreeView implements AntOutputView, OccurenceNavigator { @Nullable public Object getData(String dataId) { - if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { + if (CommonDataKeys.NAVIGATABLE.is(dataId)) { MessageNode item = getSelectedItem(); if (item == null) return null; if (isValid(item.getFile())) { diff --git a/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java b/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java index 48ae6110d03d..f058ce9f1f36 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java @@ -421,7 +421,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, @Nullable public Object getData(@NonNls String dataId) { - if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { + if (CommonDataKeys.NAVIGATABLE.is(dataId)) { final AntBuildFile buildFile = getCurrentBuildFile(); if (buildFile == null) { return null; @@ -459,7 +459,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, else if (PlatformDataKeys.TREE_EXPANDER.is(dataId)) { return myProject != null? myTreeExpander : null; } - else if (PlatformDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) { + else if (CommonDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) { final TreePath[] paths = myTree.getSelectionPaths(); if (paths == null) { return null; diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java index 1534e16bd7cf..5cf28c8f42f8 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java @@ -27,6 +27,7 @@ import com.intellij.lang.ant.config.*; import com.intellij.lang.ant.config.actions.TargetAction; import com.intellij.lang.ant.dom.AntDomFileDescription; import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; @@ -649,7 +650,7 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis ApplicationManager.getApplication().invokeAndWait(new Runnable() { public void run() { - Project project = PlatformDataKeys.PROJECT.getData(dataContext); + Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null || project.isDisposed()) { result[0] = false; return; diff --git a/plugins/ant/src/com/intellij/lang/ant/refactoring/AntRenameHandler.java b/plugins/ant/src/com/intellij/lang/ant/refactoring/AntRenameHandler.java index 15f5e31e4fd9..2a75301422c6 100644 --- a/plugins/ant/src/com/intellij/lang/ant/refactoring/AntRenameHandler.java +++ b/plugins/ant/src/com/intellij/lang/ant/refactoring/AntRenameHandler.java @@ -17,6 +17,7 @@ package com.intellij.lang.ant.refactoring; import com.intellij.codeInsight.TargetElementUtilBase; import com.intellij.lang.ant.dom.AntDomFileDescription; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.editor.Editor; @@ -57,7 +58,7 @@ public final class AntRenameHandler extends PsiElementRenameHandler { @Nullable private static PsiElement[] getElements(DataContext dataContext) { - final PsiFile psiFile = LangDataKeys.PSI_FILE.getData(dataContext); + final PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(dataContext); if (!(psiFile instanceof XmlFile && AntDomFileDescription.isAntFile((XmlFile)psiFile))) { return null; } diff --git a/plugins/commander/src/META-INF/plugin.xml b/plugins/commander/src/META-INF/plugin.xml index 933fd487d073..7eb576f5cc1e 100644 --- a/plugins/commander/src/META-INF/plugin.xml +++ b/plugins/commander/src/META-INF/plugin.xml @@ -26,7 +26,7 @@ </action> <group id="ImagesCommanderActions1" text="Images Commander Actions (1)"> - <reference id="Images.EditExternaly"/> + <reference id="Images.EditExternally"/> <add-to-group anchor="after" group-id="CommanderPopupMenu" relative-to-action="EditSource"/> </group> diff --git a/plugins/commander/src/com/intellij/ide/actions/CommanderViewActionGroup.java b/plugins/commander/src/com/intellij/ide/actions/CommanderViewActionGroup.java index 3d3af0ef4c93..76785d068c39 100644 --- a/plugins/commander/src/com/intellij/ide/actions/CommanderViewActionGroup.java +++ b/plugins/commander/src/com/intellij/ide/actions/CommanderViewActionGroup.java @@ -16,6 +16,7 @@ package com.intellij.ide.actions; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; @@ -31,7 +32,7 @@ public class CommanderViewActionGroup extends DefaultActionGroup implements Dum public void update(AnActionEvent event){ Presentation presentation = event.getPresentation(); - Project project = PlatformDataKeys.PROJECT.getData(event.getDataContext()); + Project project = CommonDataKeys.PROJECT.getData(event.getDataContext()); if (project == null) { presentation.setVisible(false); return; diff --git a/plugins/commander/src/com/intellij/ide/actions/SwapPanelsAction.java b/plugins/commander/src/com/intellij/ide/actions/SwapPanelsAction.java index b6eb908b64f2..97eed35f7071 100644 --- a/plugins/commander/src/com/intellij/ide/actions/SwapPanelsAction.java +++ b/plugins/commander/src/com/intellij/ide/actions/SwapPanelsAction.java @@ -19,6 +19,7 @@ package com.intellij.ide.actions; import com.intellij.ide.commander.Commander; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.project.Project; @@ -27,7 +28,7 @@ import com.intellij.openapi.wm.ToolWindowManager; public class SwapPanelsAction extends AnAction { public void actionPerformed(AnActionEvent e) { - Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); if (project == null) { return; } @@ -36,7 +37,7 @@ public class SwapPanelsAction extends AnAction { public void update(AnActionEvent event){ Presentation presentation = event.getPresentation(); - Project project = PlatformDataKeys.PROJECT.getData(event.getDataContext()); + Project project = CommonDataKeys.PROJECT.getData(event.getDataContext()); if (project == null) { presentation.setEnabled(false); return; diff --git a/plugins/commander/src/com/intellij/ide/commander/Commander.java b/plugins/commander/src/com/intellij/ide/commander/Commander.java index f0badf4c49a5..b46300dd3611 100644 --- a/plugins/commander/src/com/intellij/ide/commander/Commander.java +++ b/plugins/commander/src/com/intellij/ide/commander/Commander.java @@ -484,7 +484,7 @@ public class Commander extends JPanel implements PersistentStateComponent<Elemen if (PlatformDataKeys.HELP_ID.is(dataId)) { return HelpID.COMMANDER; } - else if (PlatformDataKeys.PROJECT.is(dataId)) { + else if (CommonDataKeys.PROJECT.is(dataId)) { return myProject; } else if (LangDataKeys.TARGET_PSI_ELEMENT.is(dataId)) { diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/actions/GenerateCopyrightAction.java b/plugins/copyright/src/com/maddyhome/idea/copyright/actions/GenerateCopyrightAction.java index 9e58609dca9f..1c7c6ce94a06 100644 --- a/plugins/copyright/src/com/maddyhome/idea/copyright/actions/GenerateCopyrightAction.java +++ b/plugins/copyright/src/com/maddyhome/idea/copyright/actions/GenerateCopyrightAction.java @@ -36,7 +36,7 @@ public class GenerateCopyrightAction extends AnAction { Presentation presentation = event.getPresentation(); DataContext context = event.getDataContext(); - Project project = PlatformDataKeys.PROJECT.getData(context); + Project project = CommonDataKeys.PROJECT.getData(context); if (project == null) { presentation.setEnabled(false); @@ -51,9 +51,9 @@ public class GenerateCopyrightAction extends AnAction @Nullable private static PsiFile getFile(DataContext context, Project project) { - PsiFile file = LangDataKeys.PSI_FILE.getData(context); + PsiFile file = CommonDataKeys.PSI_FILE.getData(context); if (file == null) { - Editor editor = PlatformDataKeys.EDITOR.getData(context); + Editor editor = CommonDataKeys.EDITOR.getData(context); if (editor != null) { file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); } @@ -64,7 +64,7 @@ public class GenerateCopyrightAction extends AnAction public void actionPerformed(AnActionEvent event) { DataContext context = event.getDataContext(); - Project project = PlatformDataKeys.PROJECT.getData(context); + Project project = CommonDataKeys.PROJECT.getData(context); assert project != null; Module module = LangDataKeys.MODULE.getData(context); PsiDocumentManager.getInstance(project).commitAllDocuments(); diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/actions/UpdateCopyrightAction.java b/plugins/copyright/src/com/maddyhome/idea/copyright/actions/UpdateCopyrightAction.java index 2d51d43c22c3..03c256722490 100644 --- a/plugins/copyright/src/com/maddyhome/idea/copyright/actions/UpdateCopyrightAction.java +++ b/plugins/copyright/src/com/maddyhome/idea/copyright/actions/UpdateCopyrightAction.java @@ -49,8 +49,8 @@ public class UpdateCopyrightAction extends AnAction { if (!CopyrightManager.getInstance(project).hasAnyCopyrights()) { return false; } - final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(context); - final Editor editor = PlatformDataKeys.EDITOR.getData(context); + final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(context); + final Editor editor = CommonDataKeys.EDITOR.getData(context); if (editor != null) { final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); if (file == null || !FileTypeUtil.isSupportedFile(file)) { @@ -102,8 +102,8 @@ public class UpdateCopyrightAction extends AnAction { final Module module = LangDataKeys.MODULE.getData(context); PsiDocumentManager.getInstance(project).commitAllDocuments(); - final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(context); - final Editor editor = PlatformDataKeys.EDITOR.getData(context); + final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(context); + final Editor editor = CommonDataKeys.EDITOR.getData(context); PsiFile file = null; PsiDirectory dir; @@ -135,7 +135,7 @@ public class UpdateCopyrightAction extends AnAction { return; } - final PsiElement psielement = LangDataKeys.PSI_ELEMENT.getData(context); + final PsiElement psielement = CommonDataKeys.PSI_ELEMENT.getData(context); if (psielement == null) { return; } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/BrowseCvsRepositoryAction.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/BrowseCvsRepositoryAction.java index cce3926f3240..9a8a300b4711 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/BrowseCvsRepositoryAction.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/BrowseCvsRepositoryAction.java @@ -26,6 +26,7 @@ import com.intellij.cvsSupport2.cvshandlers.FileSetToBeUpdated; import com.intellij.cvsSupport2.cvsoperations.common.LoginPerformer; import com.intellij.cvsSupport2.ui.CvsTabbedWindow; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.project.DumbAware; @@ -52,7 +53,7 @@ public class BrowseCvsRepositoryAction extends AbstractAction implements DumbAwa @Override public void update(AnActionEvent e) { final Presentation presentation = e.getPresentation(); - final boolean projectExists = e.getData(PlatformDataKeys.PROJECT) != null; + final boolean projectExists = e.getData(CommonDataKeys.PROJECT) != null; presentation.setVisible(projectExists); presentation.setEnabled(projectExists); } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/ui/BrowserPanel.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/ui/BrowserPanel.java index 4fb2207fbc24..8c5a5dc7e3bc 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/ui/BrowserPanel.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/ui/BrowserPanel.java @@ -102,14 +102,14 @@ public class BrowserPanel extends JPanel implements DataProvider, CvsTabbedWindo } public void actionPerformed(AnActionEvent e) { - final Navigatable[] navigatableArray = e.getData(PlatformDataKeys.NAVIGATABLE_ARRAY); + final Navigatable[] navigatableArray = e.getData(CommonDataKeys.NAVIGATABLE_ARRAY); if (navigatableArray != null && navigatableArray.length > 0) { OpenSourceUtil.navigate(navigatableArray); } } public void update(final AnActionEvent e) { - final Navigatable[] navigatableArray = e.getData(PlatformDataKeys.NAVIGATABLE_ARRAY); + final Navigatable[] navigatableArray = e.getData(CommonDataKeys.NAVIGATABLE_ARRAY); e.getPresentation().setEnabled(navigatableArray != null && navigatableArray.length > 0); } } @@ -206,12 +206,12 @@ public class BrowserPanel extends JPanel implements DataProvider, CvsTabbedWindo } public Object getData(String dataId) { - if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { + if (CommonDataKeys.NAVIGATABLE.is(dataId)) { VirtualFile cvsVirtualFile = getCvsVirtualFile(); if (cvsVirtualFile == null || !cvsVirtualFile.isValid()) return null; return new OpenFileDescriptor(myProject, cvsVirtualFile); } - else if (PlatformDataKeys.PROJECT.is(dataId)) { + else if (CommonDataKeys.PROJECT.is(dataId)) { return myProject; } else { diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsEdit/ui/EditorsPanel.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsEdit/ui/EditorsPanel.java index 5afe44d9897d..1dffcc2c609b 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsEdit/ui/EditorsPanel.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsEdit/ui/EditorsPanel.java @@ -17,6 +17,7 @@ package com.intellij.cvsSupport2.cvsoperations.cvsEdit.ui; import com.intellij.CvsBundle; import com.intellij.cvsSupport2.cvsoperations.cvsEdit.EditorInfo; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.actionSystem.DataSink; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -133,10 +134,10 @@ public class EditorsPanel extends JPanel implements TypeSafeDataProvider { } public void calcData(DataKey key, DataSink sink) { - if (key.equals(PlatformDataKeys.PROJECT)) { - sink.put(PlatformDataKeys.PROJECT, myProject); + if (key.equals(CommonDataKeys.PROJECT)) { + sink.put(CommonDataKeys.PROJECT, myProject); } - else if (key.equals(PlatformDataKeys.NAVIGATABLE)) { + else if (key.equals(CommonDataKeys.NAVIGATABLE)) { final EditorInfo editorInfo = myTable.getSelectedObject(); if (editorInfo == null) { return; @@ -149,7 +150,7 @@ public class EditorsPanel extends JPanel implements TypeSafeDataProvider { final File file = new File(editorInfo.getPath(), filePath); final VirtualFile vf = LocalFileSystem.getInstance().findFileByIoFile(file); if (vf != null) { - sink.put(PlatformDataKeys.NAVIGATABLE, new OpenFileDescriptor(myProject, vf)); + sink.put(CommonDataKeys.NAVIGATABLE, new OpenFileDescriptor(myProject, vf)); } } } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/SelectLocationStep.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/SelectLocationStep.java index 3cb19b6200db..cd49d6bff01e 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/SelectLocationStep.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/SelectLocationStep.java @@ -279,8 +279,8 @@ public abstract class SelectLocationStep extends WizardStep { } public void calcData(final DataKey key, final DataSink sink) { - if (key == PlatformDataKeys.VIRTUAL_FILE_ARRAY) { - sink.put(PlatformDataKeys.VIRTUAL_FILE_ARRAY, myFileSystemTree.getSelectedFiles()); + if (key == CommonDataKeys.VIRTUAL_FILE_ARRAY) { + sink.put(CommonDataKeys.VIRTUAL_FILE_ARRAY, myFileSystemTree.getSelectedFiles()); } else if (key == FileSystemTree.DATA_KEY) { sink.put(FileSystemTree.DATA_KEY, myFileSystemTree); diff --git a/plugins/devkit/src/actions/GenerateComponentExternalizationAction.java b/plugins/devkit/src/actions/GenerateComponentExternalizationAction.java index 9b5bee491d3a..f1affb01da18 100644 --- a/plugins/devkit/src/actions/GenerateComponentExternalizationAction.java +++ b/plugins/devkit/src/actions/GenerateComponentExternalizationAction.java @@ -102,13 +102,13 @@ public class GenerateComponentExternalizationAction extends AnAction { @Nullable private PsiClass getComponentInContext(DataContext context) { - Editor editor = PlatformDataKeys.EDITOR.getData(context); - Project project = PlatformDataKeys.PROJECT.getData(context); + Editor editor = CommonDataKeys.EDITOR.getData(context); + Project project = CommonDataKeys.PROJECT.getData(context); if (editor == null || project == null) return null; PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); - PsiFile file = LangDataKeys.PSI_FILE.getData(context); + PsiFile file = CommonDataKeys.PSI_FILE.getData(context); if (file == null) return null; PsiClass contextClass = PsiTreeUtil.findElementOfClassAtOffset(file, editor.getCaretModel().getOffset(), PsiClass.class, false); diff --git a/plugins/devkit/src/actions/GeneratePluginClassAction.java b/plugins/devkit/src/actions/GeneratePluginClassAction.java index b0451c1f098f..0853cc300bde 100644 --- a/plugins/devkit/src/actions/GeneratePluginClassAction.java +++ b/plugins/devkit/src/actions/GeneratePluginClassAction.java @@ -85,7 +85,7 @@ public abstract class GeneratePluginClassAction extends CreateElementActionBase presentation.setVisible(false); } final IdeView view = LangDataKeys.IDE_VIEW.getData(e.getDataContext()); - final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); if (view != null && project != null) { // from com.intellij.ide.actions.CreateClassAction.update() ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); diff --git a/plugins/devkit/src/actions/ShowSerializedXmlAction.java b/plugins/devkit/src/actions/ShowSerializedXmlAction.java index 9de4276ddefb..9c53cacdf104 100644 --- a/plugins/devkit/src/actions/ShowSerializedXmlAction.java +++ b/plugins/devkit/src/actions/ShowSerializedXmlAction.java @@ -18,6 +18,7 @@ package org.jetbrains.idea.devkit.actions; import com.intellij.CommonBundle; import com.intellij.compiler.impl.FileSetCompileScope; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.compiler.CompileContext; @@ -63,8 +64,8 @@ public class ShowSerializedXmlAction extends DumbAwareAction { @Override public void update(AnActionEvent e) { - e.getPresentation().setEnabled(getEventProject(e) != null && e.getData(LangDataKeys.PSI_FILE) != null - && e.getData(PlatformDataKeys.EDITOR) != null); + e.getPresentation().setEnabled(getEventProject(e) != null && e.getData(CommonDataKeys.PSI_FILE) != null + && e.getData(CommonDataKeys.EDITOR) != null); } @Override @@ -130,8 +131,8 @@ public class ShowSerializedXmlAction extends DumbAwareAction { @Nullable private static PsiClass getPsiClass(AnActionEvent e) { - final PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE); - final Editor editor = e.getData(PlatformDataKeys.EDITOR); + final PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE); + final Editor editor = e.getData(CommonDataKeys.EDITOR); if (editor == null || psiFile == null) return null; final PsiElement element = psiFile.findElementAt(editor.getCaretModel().getOffset()); return PsiTreeUtil.getParentOfType(element, PsiClass.class); diff --git a/plugins/devkit/src/actions/ShuffleNamesAction.java b/plugins/devkit/src/actions/ShuffleNamesAction.java index 5cf7dde89b25..eac093207b03 100644 --- a/plugins/devkit/src/actions/ShuffleNamesAction.java +++ b/plugins/devkit/src/actions/ShuffleNamesAction.java @@ -17,6 +17,7 @@ package org.jetbrains.idea.devkit.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.AccessToken; @@ -40,15 +41,15 @@ import java.util.*; public class ShuffleNamesAction extends AnAction { @Override public void update(AnActionEvent e) { - Editor editor = PlatformDataKeys.EDITOR.getData(e.getDataContext()); - PsiFile file = LangDataKeys.PSI_FILE.getData(e.getDataContext()); + Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); + PsiFile file = CommonDataKeys.PSI_FILE.getData(e.getDataContext()); e.getPresentation().setEnabled(editor != null && file != null); } @Override public void actionPerformed(AnActionEvent e) { - final Editor editor = PlatformDataKeys.EDITOR.getData(e.getDataContext()); - PsiFile file = LangDataKeys.PSI_FILE.getData(e.getDataContext()); + final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); + PsiFile file = CommonDataKeys.PSI_FILE.getData(e.getDataContext()); if (editor == null || file == null) return; final Project project = file.getProject(); CommandProcessorEx commandProcessor = (CommandProcessorEx)CommandProcessorEx.getInstance(); diff --git a/plugins/devkit/src/actions/ToggleHighlightingMarkupAction.java b/plugins/devkit/src/actions/ToggleHighlightingMarkupAction.java index b3142ba1b1b1..71f605ca6843 100644 --- a/plugins/devkit/src/actions/ToggleHighlightingMarkupAction.java +++ b/plugins/devkit/src/actions/ToggleHighlightingMarkupAction.java @@ -21,6 +21,7 @@ import com.intellij.codeInsight.daemon.impl.IndentsPass; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.AccessToken; @@ -49,15 +50,15 @@ import java.util.regex.Pattern; public class ToggleHighlightingMarkupAction extends AnAction { @Override public void update(AnActionEvent e) { - Editor editor = PlatformDataKeys.EDITOR.getData(e.getDataContext()); - PsiFile file = LangDataKeys.PSI_FILE.getData(e.getDataContext()); + Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); + PsiFile file = CommonDataKeys.PSI_FILE.getData(e.getDataContext()); e.getPresentation().setEnabled(editor != null && file != null); } @Override public void actionPerformed(AnActionEvent e) { - final Editor editor = PlatformDataKeys.EDITOR.getData(e.getDataContext()); - PsiFile file = LangDataKeys.PSI_FILE.getData(e.getDataContext()); + final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); + PsiFile file = CommonDataKeys.PSI_FILE.getData(e.getDataContext()); if (editor == null || file == null) return; final Project project = file.getProject(); CommandProcessorEx commandProcessor = (CommandProcessorEx)CommandProcessorEx.getInstance(); diff --git a/plugins/devkit/src/build/PrepareAllToDeployAction.java b/plugins/devkit/src/build/PrepareAllToDeployAction.java index da57a7d1fbd3..051a891aefca 100644 --- a/plugins/devkit/src/build/PrepareAllToDeployAction.java +++ b/plugins/devkit/src/build/PrepareAllToDeployAction.java @@ -16,6 +16,7 @@ package org.jetbrains.idea.devkit.build; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.module.Module; @@ -32,7 +33,7 @@ import java.util.List; public class PrepareAllToDeployAction extends PrepareToDeployAction { public void actionPerformed(final AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); if ( project == null ) return; List<Module> pluginModules = new ArrayList<Module>(); @@ -53,7 +54,7 @@ public class PrepareAllToDeployAction extends PrepareToDeployAction { public void update(AnActionEvent e) { int moduleCount = 0; - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); if (project != null) { for (Module aModule : (ModuleManager.getInstance(project).getModules())) { if (ModuleType.get(aModule) instanceof PluginModuleType) { diff --git a/plugins/devkit/src/build/PrepareToDeployAction.java b/plugins/devkit/src/build/PrepareToDeployAction.java index 3fc828e1565a..19399fdc3a62 100644 --- a/plugins/devkit/src/build/PrepareToDeployAction.java +++ b/plugins/devkit/src/build/PrepareToDeployAction.java @@ -18,6 +18,7 @@ package org.jetbrains.idea.devkit.build; import com.intellij.compiler.server.CompileServerPlugin; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; @@ -77,7 +78,7 @@ public class PrepareToDeployAction extends AnAction { public void actionPerformed(final AnActionEvent e) { final Module module = LangDataKeys.MODULE.getData(e.getDataContext()); if (module != null && ModuleType.get(module) instanceof PluginModuleType) { - doPrepare(Arrays.asList(module), PlatformDataKeys.PROJECT.getData(e.getDataContext())); + doPrepare(Arrays.asList(module), CommonDataKeys.PROJECT.getData(e.getDataContext())); } } diff --git a/plugins/devkit/src/dom/generator/GenerateDomModelAction.java b/plugins/devkit/src/dom/generator/GenerateDomModelAction.java index fb8efd87244c..2819b56f6cff 100644 --- a/plugins/devkit/src/dom/generator/GenerateDomModelAction.java +++ b/plugins/devkit/src/dom/generator/GenerateDomModelAction.java @@ -17,6 +17,7 @@ package org.jetbrains.idea.devkit.dom.generator; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; @@ -26,7 +27,7 @@ import com.intellij.openapi.project.Project; public class GenerateDomModelAction extends AnAction { @Override public void actionPerformed(AnActionEvent e) { - final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); if (project != null) { new DomGenDialog(project).show(); } diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/export/ExportEclipseProjectsAction.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/export/ExportEclipseProjectsAction.java index a577d6719ec9..f0c6750f8997 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/export/ExportEclipseProjectsAction.java +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/export/ExportEclipseProjectsAction.java @@ -17,6 +17,7 @@ package org.jetbrains.idea.eclipse.export; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; @@ -54,12 +55,12 @@ public class ExportEclipseProjectsAction extends AnAction implements DumbAware { private static final Logger LOG = Logger.getInstance("#" + ExportEclipseProjectsAction.class.getName()); public void update(final AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); e.getPresentation().setEnabled(project != null); } public void actionPerformed(AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) return; project.save(); // to flush iml files diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.properties b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.properties index e4ac52c48126..a963714660d1 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.properties +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.properties @@ -11,6 +11,8 @@ #org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation= #org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters= #org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration= +org.eclipse.jdt.core.formatter.disabling_tag=FORMATTER_OFF_TAG +org.eclipse.jdt.core.formatter.enabling_tag=FORMATTER_ON_TAG org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=Java:SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS #org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration= #org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case= @@ -21,7 +23,7 @@ org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_ini org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=Java:SPACE_WITHIN_ANNOTATION_PARENTHESES org.eclipse.jdt.core.formatter.blank_lines_before_field=Java:BLANK_LINES_AROUND_FIELD org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=Java:SPACE_WITHIN_WHILE_PARENTHESES -#org.eclipse.jdt.core.formatter.use_on_off_tags= +org.eclipse.jdt.core.formatter.use_on_off_tags=FORMATTER_TAGS_ENABLED #org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration= org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=Java:ELSE_ON_NEW_LINE #org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator= @@ -88,7 +90,6 @@ org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized #org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method= org.eclipse.jdt.core.formatter.indentation.size=Java:IndentOptions:INDENT_SIZE org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=Java:SPACE_WITHIN_EMPTY_METHOD_PARENTHESES -#org.eclipse.jdt.core.formatter.enabling_tag= #org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant= org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=Java:ALIGN_MULTILINE_EXTENDS_LIST org.eclipse.jdt.core.formatter.alignment_for_assignment=Java:ALIGN_MULTILINE_ASSIGNMENT diff --git a/plugins/eclipse/testData/import/settings/eclipse_exported.xml b/plugins/eclipse/testData/import/settings/eclipse_exported.xml index 813c43bd86ca..37dd465540a1 100644 --- a/plugins/eclipse/testData/import/settings/eclipse_exported.xml +++ b/plugins/eclipse/testData/import/settings/eclipse_exported.xml @@ -2,7 +2,7 @@ <profiles version="12"> <profile kind="CodeFormatterProfile" name="MyOwn" version="12"> <setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/> +<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@off_tag"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/> @@ -16,7 +16,7 @@ <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/> @@ -84,7 +84,7 @@ <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/> +<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@on_tag"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/> diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseSettingsImportTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseSettingsImportTest.java index 30c309e7ea81..200aed671c69 100644 --- a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseSettingsImportTest.java +++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseSettingsImportTest.java @@ -93,6 +93,7 @@ public class EclipseSettingsImportTest extends PlatformTestCase { javaSettings.KEEP_CONTROL_STATEMENT_IN_ONE_LINE = true; indentOptions.USE_TAB_CHARACTER = false; indentOptions.SMART_TABS = false; + settings.FORMATTER_TAGS_ENABLED = false; InputStream inputStream = new FileInputStream(input); try { @@ -158,6 +159,9 @@ public class EclipseSettingsImportTest extends PlatformTestCase { assertFalse(javaSettings.KEEP_CONTROL_STATEMENT_IN_ONE_LINE); assertTrue(indentOptions.USE_TAB_CHARACTER); assertTrue(indentOptions.SMART_TABS); + assertTrue(settings.FORMATTER_TAGS_ENABLED); + assertEquals("@off_tag", settings.FORMATTER_OFF_TAG); + assertEquals("@on_tag", settings.FORMATTER_ON_TAG); } finally { inputStream.close(); diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java index 1fc2b7c4940b..d5e3c8aaf5c7 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java @@ -20,6 +20,7 @@ import com.intellij.codeInsight.hint.HintManager; import com.intellij.ide.util.MemberChooser; import com.intellij.ide.util.MemberChooserBuilder; import com.intellij.openapi.Disposable; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -59,7 +60,7 @@ public class GenerateToStringActionHandlerImpl extends EditorWriteActionHandler private static final Logger logger = Logger.getInstance("#org.jetbrains.generate.tostring.GenerateToStringActionHandlerImpl"); public void executeWriteAction(Editor editor, DataContext dataContext) { - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); assert project != null; PsiClass clazz = getSubjectClass(editor, dataContext); @@ -156,7 +157,7 @@ public class GenerateToStringActionHandlerImpl extends EditorWriteActionHandler @Nullable private static PsiClass getSubjectClass(Editor editor, DataContext dataContext) { - PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext); + PsiFile file = CommonDataKeys.PSI_FILE.getData(dataContext); if (file == null) return null; int offset = editor.getCaretModel().getOffset(); diff --git a/plugins/git4idea/git4idea.iml b/plugins/git4idea/git4idea.iml index 94a499bb7686..76fdf85125d1 100644 --- a/plugins/git4idea/git4idea.iml +++ b/plugins/git4idea/git4idea.iml @@ -9,7 +9,7 @@ <sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/testFramework" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/test-stepdefs" isTestSource="true" /> - <sourceFolder url="file://$MODULE_DIR$/test-features" isTestSource="true" /> + <sourceFolder url="file://$MODULE_DIR$/gitlog" isTestSource="false" /> </content> <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> @@ -67,6 +67,9 @@ <orderEntry type="library" name="JSch" level="project" /> <orderEntry type="module" module-name="spellchecker" /> <orderEntry type="module" module-name="cucumber-test-runner" scope="RUNTIME" /> + <orderEntry type="module" module-name="vcs-log-api" /> + <orderEntry type="module" module-name="vcs-log-impl" /> + <orderEntry type="module" module-name="vcs-log-graph" /> </component> </module> diff --git a/plugins/git4idea/src/META-INF/plugin.xml b/plugins/git4idea/src/META-INF/plugin.xml index 3167d87b077c..10ff8467d0da 100644 --- a/plugins/git4idea/src/META-INF/plugin.xml +++ b/plugins/git4idea/src/META-INF/plugin.xml @@ -92,7 +92,7 @@ <vcsPopupProvider implementation="git4idea.actions.GitQuickListContentProvider"/> <vcsCheckinHandlerFactory implementation="git4idea.checkin.GitCheckinHandlerFactory"/> <checkinHandlerFactory implementation="git4idea.checkin.UnresolvedMergeCheckFactory"/> - + <logProvider implementation="git4idea.log.GitLogProvider"/> <vcsChangesViewRefresher implementation="git4idea.changes.GitChangesViewRefresher" /> <vcs.rootFinder implementation="git4idea.roots.GitRootFinder"/> diff --git a/plugins/git4idea/src/git4idea/GitBranch.java b/plugins/git4idea/src/git4idea/GitBranch.java index 8128462faca2..0c7d394befda 100644 --- a/plugins/git4idea/src/git4idea/GitBranch.java +++ b/plugins/git4idea/src/git4idea/GitBranch.java @@ -16,6 +16,8 @@ package git4idea; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.vcs.log.Hash; +import com.intellij.vcs.log.impl.HashImpl; import git4idea.branch.GitBranchUtil; import git4idea.repo.GitRepository; import org.jetbrains.annotations.NonNls; @@ -46,7 +48,7 @@ public abstract class GitBranch extends GitReference { * @deprecated All usages should be reviewed and substituted with actual GitBranch objects with Hashes retrieved from the GitRepository. */ @Deprecated - public static final Hash DUMMY_HASH = Hash.create(""); + public static final Hash DUMMY_HASH = HashImpl.build(""); private static final Logger LOG = Logger.getInstance(GitBranch.class); diff --git a/plugins/git4idea/src/git4idea/GitCommit.java b/plugins/git4idea/src/git4idea/GitCommit.java index be3483f3e5fa..fef4cb739e1c 100644 --- a/plugins/git4idea/src/git4idea/GitCommit.java +++ b/plugins/git4idea/src/git4idea/GitCommit.java @@ -16,6 +16,8 @@ package git4idea; import com.intellij.openapi.vcs.changes.Change; +import com.intellij.vcs.log.Hash; +import com.intellij.vcs.log.impl.VcsFullCommitDetailsImpl; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -25,109 +27,11 @@ import java.util.List; * * @author Kirill Likhodedov */ -public final class GitCommit { +public final class GitCommit extends VcsFullCommitDetailsImpl { - @NotNull private final Hash myHash; // full (long) hash - - @NotNull private final String myAuthorName; - @NotNull private final String myAuthorEmail; - private final long myAuthorTime; - - @NotNull private final String myCommitterName; - @NotNull private final String myCommitterEmail; - private final long myCommitTime; - - @NotNull private final String mySubject; - @NotNull private final String myFullMessage; - - @NotNull private final List<Hash> myParents; - @NotNull private final List<Change> myChanges; - - public GitCommit(@NotNull Hash hash, @NotNull String authorName, @NotNull String authorEmail, long authorTime, - @NotNull String committerName, @NotNull String committerEmail, long commitTime, - @NotNull String subject, @NotNull String message, @NotNull List<Hash> parents, @NotNull List<Change> changes) { - myHash = hash; - myAuthorName = authorName; - myAuthorEmail = authorEmail; - myAuthorTime = authorTime; - myCommitterName = committerName; - myCommitterEmail = committerEmail; - myCommitTime = commitTime; - mySubject = subject; - myFullMessage = message; - myParents = parents; - myChanges = changes; - } - - @NotNull - public Hash getHash() { - return myHash; - } - - @NotNull - public String getAuthorName() { - return myAuthorName; + public GitCommit(@NotNull Hash hash, @NotNull List<Hash> parents, long authorTime, @NotNull String subject, @NotNull String authorName, + @NotNull String authorEmail, @NotNull String message, @NotNull String committerName, @NotNull String committerEmail, + long commitTime, @NotNull List<Change> changes) { + super(hash, parents, authorTime, subject, authorName, authorEmail, message, committerName, committerEmail, commitTime, changes); } - - @NotNull - public String getAuthorEmail() { - return myAuthorEmail; - } - - public long getAuthorTime() { - return myAuthorTime; - } - - @NotNull - public String getCommitterName() { - return myCommitterName; - } - - @NotNull - public String getCommitterEmail() { - return myCommitterEmail; - } - - public long getCommitTime() { - return myCommitTime; - } - - @NotNull - public String getSubject() { - return mySubject; - } - - @NotNull - public String getFullMessage() { - return myFullMessage; - } - - @NotNull - public List<Hash> getParents() { - return myParents; - } - - @NotNull - public List<Change> getChanges() { - return myChanges; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - GitCommit commit = (GitCommit)o; - - // a commit is fully identified by its hash - if (!myHash.equals(commit.myHash)) return false; - - return true; - } - - @Override - public int hashCode() { - return myHash.hashCode(); - } - } diff --git a/plugins/git4idea/src/git4idea/GitLocalBranch.java b/plugins/git4idea/src/git4idea/GitLocalBranch.java index 7624f877ebed..6996971c22c7 100644 --- a/plugins/git4idea/src/git4idea/GitLocalBranch.java +++ b/plugins/git4idea/src/git4idea/GitLocalBranch.java @@ -15,6 +15,7 @@ */ package git4idea; +import com.intellij.vcs.log.Hash; import git4idea.repo.GitBranchTrackInfo; import git4idea.repo.GitRepository; import org.jetbrains.annotations.NotNull; diff --git a/plugins/git4idea/src/git4idea/GitRemoteBranch.java b/plugins/git4idea/src/git4idea/GitRemoteBranch.java index ef700493bc61..e57f1f4f448a 100644 --- a/plugins/git4idea/src/git4idea/GitRemoteBranch.java +++ b/plugins/git4idea/src/git4idea/GitRemoteBranch.java @@ -15,6 +15,7 @@ */ package git4idea; +import com.intellij.vcs.log.Hash; import git4idea.repo.GitRemote; import org.jetbrains.annotations.NotNull; diff --git a/plugins/git4idea/src/git4idea/GitStandardRemoteBranch.java b/plugins/git4idea/src/git4idea/GitStandardRemoteBranch.java index 15dbcbd6385b..1e3467dbaf3e 100644 --- a/plugins/git4idea/src/git4idea/GitStandardRemoteBranch.java +++ b/plugins/git4idea/src/git4idea/GitStandardRemoteBranch.java @@ -15,6 +15,7 @@ */ package git4idea; +import com.intellij.vcs.log.Hash; import git4idea.branch.GitBranchUtil; import git4idea.repo.GitRemote; import org.jetbrains.annotations.NotNull; diff --git a/plugins/git4idea/src/git4idea/GitSvnRemoteBranch.java b/plugins/git4idea/src/git4idea/GitSvnRemoteBranch.java index 0ebb9828f68e..7c01f43f49a2 100644 --- a/plugins/git4idea/src/git4idea/GitSvnRemoteBranch.java +++ b/plugins/git4idea/src/git4idea/GitSvnRemoteBranch.java @@ -15,6 +15,7 @@ */ package git4idea; +import com.intellij.vcs.log.Hash; import git4idea.repo.GitRemote; import org.jetbrains.annotations.NotNull; diff --git a/plugins/git4idea/src/git4idea/GitVcs.java b/plugins/git4idea/src/git4idea/GitVcs.java index 6248a6a091c8..a28025dfeef8 100644 --- a/plugins/git4idea/src/git4idea/GitVcs.java +++ b/plugins/git4idea/src/git4idea/GitVcs.java @@ -33,6 +33,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ChangeProvider; @@ -335,7 +336,9 @@ public class GitVcs extends AbstractVcs<CommittedChangeList> { myVFSListener = new GitVFSListener(myProject, this, myGit); } NewGitUsersComponent.getInstance(myProject).activate(); - GitProjectLogManager.getInstance(myProject).activate(); + if (!Registry.is("git.new.log")) { + GitProjectLogManager.getInstance(myProject).activate(); + } if (!ApplicationManager.getApplication().isHeadlessEnvironment()) { myBranchWidget = new GitBranchWidget(myProject); diff --git a/plugins/git4idea/src/git4idea/Hash.java b/plugins/git4idea/src/git4idea/Hash.java deleted file mode 100644 index fd22a24638d7..000000000000 --- a/plugins/git4idea/src/git4idea/Hash.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2000-2012 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 git4idea; - -import org.jetbrains.annotations.NotNull; - -/** - * Encapsulation of the hash representing an object in Git. - * - * @author Kirill Likhodedov - */ -public class Hash { - - @NotNull private final String myHash; - - private Hash(@NotNull String hash) { - myHash = hash; - } - - @NotNull - public static Hash create(@NotNull String hash) { - return new Hash(hash); - } - - @NotNull - public String asString() { - return myHash; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Hash hash = (Hash)o; - - if (!myHash.equals(hash.myHash)) return false; - - return true; - } - - @Override - public int hashCode() { - return myHash.hashCode(); - } - - @Override - public String toString() { - return myHash; - } - -} diff --git a/plugins/git4idea/src/git4idea/actions/BasicAction.java b/plugins/git4idea/src/git4idea/actions/BasicAction.java index f979de3c2098..874685334f1c 100644 --- a/plugins/git4idea/src/git4idea/actions/BasicAction.java +++ b/plugins/git4idea/src/git4idea/actions/BasicAction.java @@ -17,6 +17,7 @@ package git4idea.actions; import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.application.ApplicationManager; @@ -53,13 +54,13 @@ public abstract class BasicAction extends DumbAwareAction { */ @Override public void actionPerformed(@NotNull AnActionEvent event) { - final Project project = event.getData(PlatformDataKeys.PROJECT); + final Project project = event.getData(CommonDataKeys.PROJECT); ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { FileDocumentManager.getInstance().saveAllDocuments(); } }); - final VirtualFile[] vFiles = event.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); + final VirtualFile[] vFiles = event.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY); assert vFiles != null : "The action is only available when files are selected"; assert project != null; @@ -212,14 +213,14 @@ public abstract class BasicAction extends DumbAwareAction { public void update(@NotNull AnActionEvent e) { super.update(e); Presentation presentation = e.getPresentation(); - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) { presentation.setEnabled(false); presentation.setVisible(false); return; } - VirtualFile[] vFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); + VirtualFile[] vFiles = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY); if (vFiles == null || vFiles.length == 0) { presentation.setEnabled(false); presentation.setVisible(true); diff --git a/plugins/git4idea/src/git4idea/actions/GitAction.java b/plugins/git4idea/src/git4idea/actions/GitAction.java index 17db5ac4ef99..10f852821f4f 100644 --- a/plugins/git4idea/src/git4idea/actions/GitAction.java +++ b/plugins/git4idea/src/git4idea/actions/GitAction.java @@ -16,6 +16,7 @@ package git4idea.actions; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.project.DumbAwareAction; @@ -31,7 +32,7 @@ public abstract class GitAction extends DumbAwareAction { @Override public void update(@NotNull AnActionEvent e) { Presentation presentation = e.getPresentation(); - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); if (project == null || project.isDisposed()) { presentation.setEnabled(false); presentation.setVisible(false); diff --git a/plugins/git4idea/src/git4idea/actions/GitCompareWithBranchAction.java b/plugins/git4idea/src/git4idea/actions/GitCompareWithBranchAction.java index 30b21a1acfbc..231fd8e6d5d1 100644 --- a/plugins/git4idea/src/git4idea/actions/GitCompareWithBranchAction.java +++ b/plugins/git4idea/src/git4idea/actions/GitCompareWithBranchAction.java @@ -17,6 +17,7 @@ package git4idea.actions; import com.intellij.notification.NotificationType; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.diagnostic.Logger; @@ -111,7 +112,7 @@ public class GitCompareWithBranchAction extends DumbAwareAction { } private static VirtualFile getAffectedFile(AnActionEvent event) { - final VirtualFile[] vFiles = event.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); + final VirtualFile[] vFiles = event.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY); assert vFiles != null && vFiles.length == 1 && vFiles[0] != null : "Illegal virtual files selected: " + Arrays.toString(vFiles); return vFiles[0]; } @@ -127,7 +128,7 @@ public class GitCompareWithBranchAction extends DumbAwareAction { return; } - VirtualFile[] vFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); + VirtualFile[] vFiles = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY); if (vFiles == null || vFiles.length != 1 || vFiles[0] == null) { // only 1 file for now presentation.setEnabled(false); presentation.setVisible(true); diff --git a/plugins/git4idea/src/git4idea/actions/GitInit.java b/plugins/git4idea/src/git4idea/actions/GitInit.java index 76fc9004f281..04d3ff77ca2e 100644 --- a/plugins/git4idea/src/git4idea/actions/GitInit.java +++ b/plugins/git4idea/src/git4idea/actions/GitInit.java @@ -17,6 +17,7 @@ package git4idea.actions; import com.intellij.notification.NotificationType; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.fileChooser.FileChooser; @@ -51,7 +52,7 @@ import java.util.List; public class GitInit extends DumbAwareAction { public void actionPerformed(final AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) { project = ProjectManager.getInstance().getDefaultProject(); } @@ -60,7 +61,7 @@ public class GitInit extends DumbAwareAction { fcd.setTitle(GitBundle.getString("init.destination.directory.title")); fcd.setDescription(GitBundle.getString("init.destination.directory.description")); fcd.setHideIgnored(false); - VirtualFile baseDir = e.getData(PlatformDataKeys.VIRTUAL_FILE); + VirtualFile baseDir = e.getData(CommonDataKeys.VIRTUAL_FILE); if (baseDir == null) { baseDir = project.getBaseDir(); } diff --git a/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java b/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java index 15523cc1f65a..7ee419e6ae9d 100644 --- a/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java +++ b/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java @@ -17,6 +17,7 @@ package git4idea.actions; import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; @@ -63,7 +64,7 @@ public abstract class GitRepositoryAction extends DumbAwareAction { } }); DataContext dataContext = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null) { return; } @@ -71,7 +72,7 @@ public abstract class GitRepositoryAction extends DumbAwareAction { final List<VirtualFile> roots = getGitRoots(project, vcs); if (roots == null) return; // get default root - final VirtualFile[] vFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); + final VirtualFile[] vFiles = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY); VirtualFile defaultRootVar = null; if (vFiles != null) { for (VirtualFile file : vFiles) { @@ -120,9 +121,9 @@ public abstract class GitRepositoryAction extends DumbAwareAction { } protected static boolean isRebasing(AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); if (project != null) { - final VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); + final VirtualFile[] files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY); if (files != null) { for (VirtualFile file : files) { GitRepositoryManager manager = GitUtil.getRepositoryManager(project); @@ -212,7 +213,7 @@ public abstract class GitRepositoryAction extends DumbAwareAction { } protected boolean isEnabled(AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) { return false; } diff --git a/plugins/git4idea/src/git4idea/branch/GitBranchUiHandler.java b/plugins/git4idea/src/git4idea/branch/GitBranchUiHandler.java index 32eaa457c430..aa644146e5b0 100644 --- a/plugins/git4idea/src/git4idea/branch/GitBranchUiHandler.java +++ b/plugins/git4idea/src/git4idea/branch/GitBranchUiHandler.java @@ -36,7 +36,7 @@ import java.util.Map; * * @author Kirill Likhodedov */ -interface GitBranchUiHandler { +public interface GitBranchUiHandler { @NotNull ProgressIndicator getProgressIndicator(); diff --git a/plugins/git4idea/src/git4idea/branch/GitBranchUiHandlerImpl.java b/plugins/git4idea/src/git4idea/branch/GitBranchUiHandlerImpl.java index 0e545d152143..7c74823a5ac0 100644 --- a/plugins/git4idea/src/git4idea/branch/GitBranchUiHandlerImpl.java +++ b/plugins/git4idea/src/git4idea/branch/GitBranchUiHandlerImpl.java @@ -49,14 +49,14 @@ import java.util.concurrent.atomic.AtomicBoolean; /** * @author Kirill Likhodedov */ -class GitBranchUiHandlerImpl implements GitBranchUiHandler { +public class GitBranchUiHandlerImpl implements GitBranchUiHandler { @NotNull private final Project myProject; @NotNull private final Git myGit; @NotNull private final GitPlatformFacade myFacade; @NotNull private final ProgressIndicator myProgressIndicator; - GitBranchUiHandlerImpl(@NotNull Project project, @NotNull GitPlatformFacade facade, @NotNull Git git, @NotNull ProgressIndicator indicator) { + public GitBranchUiHandlerImpl(@NotNull Project project, @NotNull GitPlatformFacade facade, @NotNull Git git, @NotNull ProgressIndicator indicator) { myProject = project; myGit = git; myFacade = facade; diff --git a/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java b/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java index a9dcb401852a..6b4def565499 100644 --- a/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java +++ b/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java @@ -38,6 +38,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.impl.status.StatusBarUtil; +import com.intellij.vcs.log.Hash; import com.intellij.vcsUtil.VcsUtil; import git4idea.*; import git4idea.commands.GitCommand; diff --git a/plugins/git4idea/src/git4idea/branch/GitBranchWorker.java b/plugins/git4idea/src/git4idea/branch/GitBranchWorker.java index ac053aceb383..a6c4d3880153 100644 --- a/plugins/git4idea/src/git4idea/branch/GitBranchWorker.java +++ b/plugins/git4idea/src/git4idea/branch/GitBranchWorker.java @@ -45,7 +45,7 @@ import java.util.Map; * * @author Kirill Likhodedov */ -final class GitBranchWorker { +public final class GitBranchWorker { private static final Logger LOG = Logger.getInstance(GitBranchWorker.class); @@ -54,7 +54,7 @@ final class GitBranchWorker { @NotNull private final Git myGit; @NotNull private final GitBranchUiHandler myUiHandler; - GitBranchWorker(@NotNull Project project, @NotNull GitPlatformFacade facade, @NotNull Git git, @NotNull GitBranchUiHandler uiHandler) { + public GitBranchWorker(@NotNull Project project, @NotNull GitPlatformFacade facade, @NotNull Git git, @NotNull GitBranchUiHandler uiHandler) { myProject = project; myFacade = facade; myGit = git; diff --git a/plugins/git4idea/src/git4idea/branch/GitSmartOperationDialog.java b/plugins/git4idea/src/git4idea/branch/GitSmartOperationDialog.java index 1c37e2f7bb5f..c7f7f9ab476e 100644 --- a/plugins/git4idea/src/git4idea/branch/GitSmartOperationDialog.java +++ b/plugins/git4idea/src/git4idea/branch/GitSmartOperationDialog.java @@ -42,7 +42,7 @@ import static com.intellij.openapi.util.text.StringUtil.capitalize; * * @author Kirill Likhodedov */ -class GitSmartOperationDialog extends DialogWrapper { +public class GitSmartOperationDialog extends DialogWrapper { public static final int SMART_EXIT_CODE = OK_EXIT_CODE; public static final int FORCE_EXIT_CODE = NEXT_USER_EXIT_CODE; diff --git a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java index 032e487dd46c..a6018f3f367e 100644 --- a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java +++ b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java @@ -16,6 +16,7 @@ package git4idea.history; import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressManager; @@ -36,8 +37,15 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.AsynchConsumer; import com.intellij.util.Consumer; import com.intellij.util.Function; +import com.intellij.util.SmartList; import com.intellij.util.concurrency.Semaphore; import com.intellij.util.containers.ContainerUtil; +import com.intellij.vcs.log.Hash; +import com.intellij.vcs.log.TimedVcsCommit; +import com.intellij.vcs.log.VcsLogObjectsFactory; +import com.intellij.vcs.log.VcsShortCommitDetails; +import com.intellij.vcs.log.impl.HashImpl; +import com.intellij.vcs.log.impl.VcsShortCommitDetailsImpl; import git4idea.*; import git4idea.branch.GitBranchUtil; import git4idea.commands.*; @@ -69,23 +77,9 @@ public class GitHistoryUtils { private GitHistoryUtils() { } - /** - * Get current revision for the file under git in the current or specified branch. - * - * @param project a project - * @param filePath file path to the file which revision is to be retrieved. - * @param branch name of branch or null if current branch wanted. - * @return revision number or null if the file is unversioned or new. - * @throws VcsException if there is a problem with running git. - */ - @Nullable - public static VcsRevisionNumber getCurrentRevision(final Project project, FilePath filePath, @Nullable String branch) throws VcsException { - return getCurrentRevision(project, filePath, branch, false); - } - public static long getHeadTs(final Project project, FilePath filePath) throws VcsException { GitSimpleHandler h = new GitSimpleHandler(project, GitUtil.getGitRoot(filePath), GitCommand.LOG); - GitLogParser parser = new GitLogParser(project, SHORT_HASH, COMMIT_TIME); + GitLogParser parser = new GitLogParser(project, HASH, COMMIT_TIME); h.setSilent(true); h.addParameters("-n1", parser.getPretty()); h.addParameters("HEAD"); @@ -102,12 +96,21 @@ public class GitHistoryUtils { return record.getDate().getTime(); } + /** + * Get current revision for the file under git in the current or specified branch. + * + * @param project a project + * @param filePath file path to the file which revision is to be retrieved. + * @param branch name of branch or null if current branch wanted. + * @return revision number or null if the file is unversioned or new. + * @throws VcsException if there is a problem with running git. + */ @Nullable - public static VcsRevisionNumber getCurrentRevision(@NotNull Project project, @NotNull FilePath filePath, @Nullable String branch, - final boolean shortHash) throws VcsException { + public static VcsRevisionNumber getCurrentRevision(@NotNull Project project, @NotNull FilePath filePath, + @Nullable String branch) throws VcsException { filePath = getLastCommitName(project, filePath); GitSimpleHandler h = new GitSimpleHandler(project, GitUtil.getGitRoot(filePath), GitCommand.LOG); - GitLogParser parser = shortHash ? new GitLogParser(project, SHORT_HASH, COMMIT_TIME) : new GitLogParser(project, HASH, COMMIT_TIME); + GitLogParser parser = new GitLogParser(project, HASH, COMMIT_TIME); h.setSilent(true); h.addParameters("-n1", parser.getPretty()); h.addParameters(!StringUtil.isEmpty(branch) ? branch : "--all"); @@ -122,7 +125,7 @@ public class GitHistoryUtils { return null; } record.setUsedHandler(h); - return shortHash ? new GitRevisionNumber(record.getShortHash(), record.getDate()) : new GitRevisionNumber(record.getHash(), record.getDate()); + return new GitRevisionNumber(record.getHash(), record.getDate()); } @Nullable @@ -173,7 +176,7 @@ public class GitHistoryUtils { } filePath = getLastCommitName(project, filePath); GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.LOG); - GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.STATUS, HASH, COMMIT_TIME, SHORT_PARENTS); + GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.STATUS, HASH, COMMIT_TIME, PARENTS); h.setSilent(true); h.addParameters("-n1", parser.getPretty(), "--name-status", t.getFullName()); h.endOptions(); @@ -356,7 +359,7 @@ public class GitHistoryUtils { record.getCommitterName() == null ? null : Pair.create(record.getCommitterName(), record.getCommitterEmail()); Collection<String> parents = parentHashes == null ? Collections.<String>emptyList() : Arrays.asList(parentHashes); consumer.consume(new GitFileRevision(project, revisionPath, revision, Pair.create(authorPair, committerPair), message, null, - new Date(record.getAuthorTimeStamp() * 1000), parents)); + new Date(record.getAuthorTimeStamp()), parents)); List<GitLogStatusInfo> statusInfos = record.getStatusInfos(); if (statusInfos.isEmpty()) { // can safely be empty, for example, for simple merge commits that don't change anything. @@ -461,7 +464,7 @@ public class GitHistoryUtils { // 'git show -M --name-status <commit hash>' returns the information about commit and detects renames. // NB: we can't specify the filepath, because then rename detection will work only with the '--follow' option, which we don't wanna use. final GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.SHOW); - final GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.STATUS, HASH, COMMIT_TIME, SHORT_PARENTS); + final GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.STATUS, HASH, COMMIT_TIME, PARENTS); h.setStdoutSuppressed(true); h.addParameters("-M", "--name-status", parser.getPretty(), "--encoding=UTF-8", commit); h.endOptions(); @@ -479,6 +482,85 @@ public class GitHistoryUtils { return null; } + public static List<? extends VcsShortCommitDetails> readAllMiniDetails(Project project, VirtualFile root) throws VcsException { + GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.LOG); + GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.NONE, HASH, PARENTS, AUTHOR_NAME, AUTHOR_TIME, SUBJECT); + h.setStdoutSuppressed(true); + h.addParameters(parser.getPretty(), "--encoding=UTF-8"); + h.addParameters("HEAD", "--branches", "--remotes", "--tags"); + h.addParameters("--full-history", "--sparse"); + h.endOptions(); + + String output = h.run(); + + List<GitLogRecord> records = parser.parse(output); + + return ContainerUtil.mapNotNull(records, new Function<GitLogRecord, VcsShortCommitDetails>() { + @Override + public VcsShortCommitDetails fun(GitLogRecord record) { + List<Hash> parents = new SmartList<Hash>(); + for (String parent : record.getParentsHashes()) { + parents.add(HashImpl.build(parent)); + } + return new VcsShortCommitDetailsImpl(HashImpl.build(record.getHash()), parents, record.getAuthorTimeStamp(), + record.getSubject(), record.getAuthorName()); + } + }); + } + + public static List<? extends VcsShortCommitDetails> readMiniDetails(Project project, VirtualFile root, List<String> hashes) throws VcsException { + GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.LOG); + GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.NONE, HASH, PARENTS, AUTHOR_NAME, AUTHOR_TIME, SUBJECT); + h.setStdoutSuppressed(true); + // git show can show either -p, or --name-status, or --name-only, but we need nothing, just details => using git log --no-walk + h.addParameters("--no-walk"); + h.addParameters(parser.getPretty(), "--encoding=UTF-8"); + h.addParameters(new ArrayList<String>(hashes)); + + String output = h.run(); + List<GitLogRecord> records = parser.parse(output); + + return ContainerUtil.map(records, new Function<GitLogRecord, VcsShortCommitDetails>() { + @Override + public VcsShortCommitDetails fun(GitLogRecord record) { + List<Hash> parents = new SmartList<Hash>(); + for (String parent : record.getParentsHashes()) { + parents.add(HashImpl.build(parent)); + } + return new VcsShortCommitDetailsImpl(HashImpl.build(record.getHash()), parents, record.getAuthorTimeStamp(), + record.getSubject(), record.getAuthorName()); + } + }); + } + + @NotNull + public static List<TimedVcsCommit> readAllHashes(@NotNull Project project, @NotNull VirtualFile root) throws VcsException { + GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.LOG); + GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.NONE, HASH, PARENTS, AUTHOR_TIME); + h.setStdoutSuppressed(true); + h.addParameters(parser.getPretty(), "--encoding=UTF-8"); + h.addParameters("HEAD", "--branches", "--remotes", "--tags"); + h.addParameters("--full-history", "--sparse"); + h.addParameters("--date-order"); + h.endOptions(); + + String output = h.run(); + + List<GitLogRecord> records = parser.parse(output); + + return ContainerUtil.map(records, new Function<GitLogRecord, TimedVcsCommit>() { + @Override + public TimedVcsCommit fun(GitLogRecord record) { + List<Hash> parents = new SmartList<Hash>(); + for (String parent : record.getParentsHashes()) { + parents.add(HashImpl.build(parent)); + } + return ServiceManager.getService(VcsLogObjectsFactory.class).createTimedCommit(HashImpl.build(record.getHash()), + parents, record.getAuthorTimeStamp()); + } + }); + } + private static class MyTokenAccumulator { private final StringBuilder myBuffer = new StringBuilder(); @@ -611,15 +693,7 @@ public class GitHistoryUtils { @Override public GitCommit fun(GitLogRecord record) { try { - List<Hash> parents = ContainerUtil.map(record.getParentsHashes(), new Function<String, Hash>() { - @Override - public Hash fun(String hash) { - return Hash.create(hash); - } - }); - return new GitCommit(Hash.create(record.getHash()), record.getAuthorName(), record.getAuthorEmail(), record.getAuthorTimeStamp(), - record.getCommitterName(), record.getCommitterEmail(), record.getLongTimeStamp(), - record.getSubject(), record.getFullMessage(), parents, record.parseChanges(project, root)); + return createCommit(project, root, record); } catch (VcsException e) { LOG.error(e); @@ -629,6 +703,20 @@ public class GitHistoryUtils { }); } + private static GitCommit createCommit(@NotNull Project project, @NotNull VirtualFile root, @NotNull GitLogRecord record) + throws VcsException { + List<Hash> parents = ContainerUtil.map(record.getParentsHashes(), new Function<String, Hash>() { + @Override + public Hash fun(String hash) { + return HashImpl.build(hash); + } + }); + return new GitCommit(HashImpl.build(record.getHash()), parents, record.getAuthorTimeStamp(), record.getSubject(), record.getAuthorName(), + record.getAuthorEmail(), record.getFullMessage(), + record.getCommitterName(), record.getCommitterEmail(), record.getLongTimeStamp(), + record.parseChanges(project, root)); + } + /** * <p>Returns the history queried by {@code git log}} command with a possibility to asynchronously process each log record * returned by Git.</p> @@ -647,8 +735,8 @@ public class GitHistoryUtils { path = getLastCommitName(project, path); final VirtualFile root = GitUtil.getGitRoot(path); final GitLineHandler h = new GitLineHandler(project, root, GitCommand.LOG); - final GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.STATUS, SHORT_HASH, HASH, COMMIT_TIME, AUTHOR_NAME, AUTHOR_TIME, AUTHOR_EMAIL, - COMMITTER_NAME, COMMITTER_EMAIL, SHORT_PARENTS, REF_NAMES, SUBJECT, BODY, RAW_BODY); + final GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.STATUS, HASH, HASH, COMMIT_TIME, AUTHOR_NAME, AUTHOR_TIME, AUTHOR_EMAIL, + COMMITTER_NAME, COMMITTER_EMAIL, PARENTS, REF_NAMES, SUBJECT, BODY, RAW_BODY); h.setStdoutSuppressed(true); h.addParameters(parameters); h.addParameters("--name-status", parser.getPretty(), "--encoding=UTF-8"); @@ -748,13 +836,13 @@ public class GitHistoryUtils { final String s = parseRefs(refs, currentRefs, locals, remotes, tags); GitHeavyCommit - gitCommit = new GitHeavyCommit(root, AbstractHash.create(record.getShortHash()), new SHAHash(record.getHash()), record.getAuthorName(), + gitCommit = new GitHeavyCommit(root, AbstractHash.create(record.getHash()), new SHAHash(record.getHash()), record.getAuthorName(), record.getCommitterName(), record.getDate(), record.getSubject(), record.getFullMessage(), - new HashSet<String>(Arrays.asList(record.getParentsShortHashes())), record.getFilePaths(root), + new HashSet<String>(Arrays.asList(record.getParentsHashes())), record.getFilePaths(root), record.getAuthorEmail(), record.getCommitterEmail(), tags, locals, remotes, - record.parseChanges(project, root), record.getAuthorTimeStamp() * 1000); + record.parseChanges(project, root), record.getAuthorTimeStamp()); gitCommit.setCurrentBranch(s); return gitCommit; } @@ -784,7 +872,7 @@ public class GitHistoryUtils { @Nullable public static Pair<AbstractHash, AbstractHash> getStashTop(@NotNull Project project, @NotNull VirtualFile root) throws VcsException { GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.STASH.readLockingCommand()); - GitLogParser parser = new GitLogParser(project, SHORT_HASH, SHORT_PARENTS); + GitLogParser parser = new GitLogParser(project, HASH, PARENTS); h.setSilent(true); h.addParameters("list"); h.addParameters("-n1"); @@ -798,12 +886,12 @@ public class GitHistoryUtils { ProgressManager.checkCanceled(); GitSimpleHandler h1 = new GitSimpleHandler(project, root, GitCommand.LOG); - GitLogParser parser1 = new GitLogParser(project, SHORT_HASH, SHORT_PARENTS, SUBJECT); + GitLogParser parser1 = new GitLogParser(project, HASH, PARENTS, SUBJECT); h1.setSilent(true); h1.addParameters("-n1"); h1.addParameters(parser1.getPretty()); //h1.endOptions(); - h1.addParameters(gitLogRecord.getShortHash()); + h1.addParameters(gitLogRecord.getHash()); String out1; out1 = h1.run(); @@ -811,7 +899,7 @@ public class GitHistoryUtils { LOG.assertTrue(gitLogRecords1.size() == 1, String.format("gitLogRecords size is incorrect. size: %s, records: %s, output: %s", gitLogRecords1.size(), gitLogRecords1, out1)); final GitLogRecord logRecord = gitLogRecords1.get(0); - final String[] parentsShortHashes = logRecord.getParentsShortHashes(); + final String[] parentsShortHashes = logRecord.getParentsHashes(); String indexCommit = null; // heuristics if (parentsShortHashes.length == 2) { @@ -822,7 +910,7 @@ public class GitHistoryUtils { indexCommit = parentsShortHashes[0]; } } - return new Pair<AbstractHash, AbstractHash>(AbstractHash.create(gitLogRecord.getShortHash()), indexCommit == null ? null : AbstractHash.create(indexCommit)); + return new Pair<AbstractHash, AbstractHash>(AbstractHash.create(gitLogRecord.getHash()), indexCommit == null ? null : AbstractHash.create(indexCommit)); } return null; } @@ -831,8 +919,8 @@ public class GitHistoryUtils { public static List<Pair<String, GitHeavyCommit>> loadStashStackAsCommits(@NotNull Project project, @NotNull VirtualFile root, SymbolicRefsI refs, final String... parameters) throws VcsException { GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.STASH.readLockingCommand()); - GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.STATUS, SHORT_HASH, HASH, COMMIT_TIME, AUTHOR_NAME, AUTHOR_TIME, AUTHOR_EMAIL, COMMITTER_NAME, - COMMITTER_EMAIL, SHORT_PARENTS, REF_NAMES, SHORT_REF_LOG_SELECTOR, SUBJECT, BODY, RAW_BODY); + GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.STATUS, HASH, HASH, COMMIT_TIME, AUTHOR_NAME, AUTHOR_TIME, AUTHOR_EMAIL, COMMITTER_NAME, + COMMITTER_EMAIL, PARENTS, REF_NAMES, SHORT_REF_LOG_SELECTOR, SUBJECT, BODY, RAW_BODY); h.setSilent(true); h.addParameters("list"); h.addParameters(parameters); @@ -851,6 +939,7 @@ public class GitHistoryUtils { return result; } + @Deprecated @NotNull public static List<GitHeavyCommit> commitsDetails(@NotNull Project project, @NotNull FilePath path, @Nullable SymbolicRefsI refs, @NotNull final Collection<String> commitsIds) throws VcsException { @@ -858,8 +947,8 @@ public class GitHistoryUtils { VirtualFile root = GitUtil.getGitRoot(path); GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.SHOW); GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.STATUS, - SHORT_HASH, HASH, COMMIT_TIME, AUTHOR_NAME, AUTHOR_TIME, AUTHOR_EMAIL, COMMITTER_NAME, - COMMITTER_EMAIL, SHORT_PARENTS, REF_NAMES, SUBJECT, BODY, RAW_BODY); + HASH, HASH, COMMIT_TIME, AUTHOR_NAME, AUTHOR_TIME, AUTHOR_EMAIL, COMMITTER_NAME, + COMMITTER_EMAIL, PARENTS, REF_NAMES, SUBJECT, BODY, RAW_BODY); h.setStdoutSuppressed(true); h.addParameters("--name-status", "-M", parser.getPretty(), "--encoding=UTF-8"); h.addParameters(new ArrayList<String>(commitsIds)); @@ -873,6 +962,25 @@ public class GitHistoryUtils { return rc; } + @NotNull + public static List<GitCommit> commitsDetails(@NotNull Project project, @NotNull VirtualFile root, + @NotNull final Collection<String> hashes) throws VcsException { + GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.SHOW); + GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.STATUS, + HASH, HASH, COMMIT_TIME, AUTHOR_NAME, AUTHOR_TIME, AUTHOR_EMAIL, COMMITTER_NAME, + COMMITTER_EMAIL, PARENTS, REF_NAMES, SUBJECT, BODY, RAW_BODY); + h.setStdoutSuppressed(true); + h.addParameters("--name-status", "-M", parser.getPretty(), "--encoding=UTF-8"); + h.addParameters(new ArrayList<String>(hashes)); + + String output = h.run(); + final List<GitCommit> rc = new ArrayList<GitCommit>(); + for (GitLogRecord record : parser.parse(output)) { + rc.add(createCommit(project, root, record)); + } + return rc; + } + public static long getAuthorTime(Project project, FilePath path, final String commitsId) throws VcsException { // adjust path using change manager path = getLastCommitName(project, path); @@ -885,7 +993,7 @@ public class GitHistoryUtils { String output = h.run(); GitLogRecord logRecord = parser.parseOneRecord(output); - return logRecord.getAuthorTimeStamp() * 1000; + return logRecord.getAuthorTimeStamp(); } public static void hashesWithParents(Project project, FilePath path, final AsynchConsumer<CommitHashPlusParents> consumer, @@ -895,7 +1003,7 @@ public class GitHistoryUtils { path = getLastCommitName(project, path); final VirtualFile root = GitUtil.getGitRoot(path); final GitLineHandler h = new GitLineHandler(project, root, GitCommand.LOG); - final GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.NAME, SHORT_HASH, COMMIT_TIME, SHORT_PARENTS, AUTHOR_NAME); + final GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.NAME, HASH, COMMIT_TIME, PARENTS, AUTHOR_NAME); h.setStdoutSuppressed(true); h.addParameters(parameters); h.addParameters(parser.getPretty(), "--encoding=UTF-8", "--full-history"); @@ -920,8 +1028,8 @@ public class GitHistoryUtils { return; } GitLogRecord record = parser.parseOneRecord(line); - consumer.consume(new CommitHashPlusParents(record.getShortHash(), - record.getParentsShortHashes(), record.getLongTimeStamp() * 1000, + consumer.consume(new CommitHashPlusParents(record.getHash(), + record.getParentsHashes(), record.getLongTimeStamp(), record.getAuthorName())); } } catch (ProcessCanceledException e) { diff --git a/plugins/git4idea/src/git4idea/history/GitLogParser.java b/plugins/git4idea/src/git4idea/history/GitLogParser.java index e274e1ec5e43..93a62c346a17 100644 --- a/plugins/git4idea/src/git4idea/history/GitLogParser.java +++ b/plugins/git4idea/src/git4idea/history/GitLogParser.java @@ -56,13 +56,13 @@ import java.util.regex.Pattern; * * @see git4idea.history.GitLogRecord */ -class GitLogParser { +public class GitLogParser { // Single records begin with %x01, end with %03. Items of commit information (hash, committer, subject, etc.) are separated by %x02. // each character is declared twice - for Git pattern format and for actual character in the output. public static final String RECORD_START = "\u0001"; public static final String ITEMS_SEPARATOR = "\u0002"; public static final String RECORD_END = "\u0003"; - private static final String RECORD_START_GIT = "%x01"; + public static final String RECORD_START_GIT = "%x01"; private static final String ITEMS_SEPARATOR_GIT = "%x02"; private static final String RECORD_END_GIT = "%x03"; @@ -110,8 +110,8 @@ class GitLogParser { * These are the pieces of information about a commit which we want to get from 'git log'. */ enum GitLogOption { - SHORT_HASH("h"), HASH("H"), COMMIT_TIME("ct"), AUTHOR_NAME("an"), AUTHOR_TIME("at"), AUTHOR_EMAIL("ae"), COMMITTER_NAME("cn"), - COMMITTER_EMAIL("ce"), SUBJECT("s"), BODY("b"), SHORT_PARENTS("p"), PARENTS("P"), REF_NAMES("d"), SHORT_REF_LOG_SELECTOR("gd"), + HASH("H"), COMMIT_TIME("ct"), AUTHOR_NAME("an"), AUTHOR_TIME("at"), AUTHOR_EMAIL("ae"), COMMITTER_NAME("cn"), + COMMITTER_EMAIL("ce"), SUBJECT("s"), BODY("b"), PARENTS("P"), REF_NAMES("d"), SHORT_REF_LOG_SELECTOR("gd"), RAW_BODY("B"); private String myPlaceholder; diff --git a/plugins/git4idea/src/git4idea/history/GitLogRecord.java b/plugins/git4idea/src/git4idea/history/GitLogRecord.java index 8fde7c18b079..520256509596 100644 --- a/plugins/git4idea/src/git4idea/history/GitLogRecord.java +++ b/plugins/git4idea/src/git4idea/history/GitLogRecord.java @@ -86,7 +86,6 @@ class GitLogRecord { // trivial access methods String getHash() { return lookup(HASH); } - String getShortHash() { return lookup(SHORT_HASH); } String getAuthorName() { return lookup(AUTHOR_NAME); } String getAuthorEmail() { return lookup(AUTHOR_EMAIL); } String getCommitterName() { return lookup(COMMITTER_NAME); } @@ -103,11 +102,11 @@ class GitLogRecord { } long getLongTimeStamp() { - return Long.parseLong(myOptions.get(COMMIT_TIME).trim()); + return Long.parseLong(myOptions.get(COMMIT_TIME).trim()) * 1000; } long getAuthorTimeStamp() { - return Long.parseLong(myOptions.get(AUTHOR_TIME).trim()); + return Long.parseLong(myOptions.get(AUTHOR_TIME).trim()) * 1000; } String getAuthorAndCommitter() { @@ -120,12 +119,6 @@ class GitLogRecord { return mySupportsRawBody ? getRawBody().trim() : ((getSubject() + "\n\n" + getBody()).trim()); } - String[] getParentsShortHashes() { - final String parents = lookup(SHORT_PARENTS); - if (parents.trim().length() == 0) return ArrayUtil.EMPTY_STRING_ARRAY; - return parents.split(" "); - } - String[] getParentsHashes() { final String parents = lookup(PARENTS); if (parents.trim().length() == 0) return ArrayUtil.EMPTY_STRING_ARRAY; @@ -191,9 +184,9 @@ class GitLogRecord { } private List<GitRevisionNumber> prepareParentRevisions() { - final String[] parentHashes = myOptions.containsKey(SHORT_PARENTS) ? getParentsShortHashes() : getParentsHashes(); - final List<AbstractHash> parents = new ArrayList<AbstractHash>(parentHashes.length); - for (String parentsShortHash : parentHashes) { + final String[] parentsHashes = getParentsHashes(); + final List<AbstractHash> parents = new ArrayList<AbstractHash>(parentsHashes.length); + for (String parentsShortHash : parentsHashes) { parents.add(AbstractHash.create(parentsShortHash)); } diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/AbstractHash.java b/plugins/git4idea/src/git4idea/history/wholeTree/AbstractHash.java index 5290f9dbb7fe..9d94f9303a52 100644 --- a/plugins/git4idea/src/git4idea/history/wholeTree/AbstractHash.java +++ b/plugins/git4idea/src/git4idea/history/wholeTree/AbstractHash.java @@ -12,156 +12,51 @@ */ package git4idea.history.wholeTree; +import com.intellij.vcs.log.Hash; +import com.intellij.vcs.log.impl.HashImpl; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Arrays; /** * @author irengrig */ -public abstract class AbstractHash { - @Nullable - public static AbstractHash createStrict(final String hash) { - return createImpl(hash, true); +@Deprecated +public class AbstractHash { + + @NotNull private final Hash myHash; + + private AbstractHash(@NotNull Hash hash) { + myHash = hash; } @NotNull public static AbstractHash create(final String hash) { - return createImpl(hash, false); + return new AbstractHash(HashImpl.build(hash)); } - private static AbstractHash createImpl(final String hash, final boolean strict) { - final String trimmed = hash.trim(); - final int len = trimmed.length(); - try { - if (len <= 8 && trimmed.charAt(0) != '0') { - return new One(trimmed); - } else { - return new Many(trimmed); - } - } catch (NumberFormatException e) { - if (strict) return null; - return new StringPresentation(trimmed); - } + public String getString() { + return myHash.asString(); } - public abstract String getString(); - @Override public String toString() { return getString(); } - private static class One extends AbstractHash { - private long myLong; - - private One(final String shortForm) { - assert shortForm.length() <= 8; - myLong = Long.parseLong(shortForm, 16); - } - - @Override - public String getString() { - return Long.toHexString(myLong); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - One one = (One)o; - - if (myLong != one.myLong) return false; - - return true; - } - - @Override - public int hashCode() { - return (int)(myLong ^ (myLong >>> 32)); - } - } - - private static class Many extends AbstractHash { - private final long[] myData; - - private Many(final String shortForm) { - int nullsSize = 0; - for (; nullsSize < shortForm.length(); nullsSize++) { - if (shortForm.charAt(nullsSize) != '0') break; - } - final String withoutNulls = shortForm.substring(nullsSize); - final int length = withoutNulls.length(); - final int size = (length >> 3) + 1 + nullsSize; - myData = new long[size]; - for (int i = 0; i < nullsSize; i++) { - myData[i] = 0; - } - for (int i = 0; i < (size - nullsSize); i++) { - final int idx = i << 3; - final int end = Math.min(idx + 8, length); - myData[i + nullsSize] = Long.parseLong(withoutNulls.substring(idx, end), 16); - } - } - - // todo? - @Override - public String getString() { - final StringBuilder sb = new StringBuilder(myData.length << 3); - for (long l : myData) { - sb.append(Long.toHexString(l)); - } - return sb.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Many many = (Many)o; + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; - if (!Arrays.equals(myData, many.myData)) return false; + AbstractHash hash = (AbstractHash)o; - return true; - } + if (!myHash.equals(hash.myHash)) return false; - @Override - public int hashCode() { - return Arrays.hashCode(myData); - } + return true; } - private static class StringPresentation extends AbstractHash { - private final String myVal; - - public StringPresentation(String val) { - myVal = val; - } - - @Override - public String getString() { - return myVal; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - StringPresentation that = (StringPresentation)o; - - if (myVal != null ? !myVal.equals(that.myVal) : that.myVal != null) return false; - - return true; - } - - @Override - public int hashCode() { - return myVal != null ? myVal.hashCode() : 0; - } + @Override + public int hashCode() { + return myHash.hashCode(); } public static boolean hashesEqual(@NotNull final AbstractHash hash1, @NotNull final AbstractHash hash2) { diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/BasePopupAction.java b/plugins/git4idea/src/git4idea/history/wholeTree/BasePopupAction.java index 1f5e937d21e3..f4f505413c6a 100644 --- a/plugins/git4idea/src/git4idea/history/wholeTree/BasePopupAction.java +++ b/plugins/git4idea/src/git4idea/history/wholeTree/BasePopupAction.java @@ -93,7 +93,7 @@ public abstract class BasePopupAction extends DumbAwareAction implements CustomC protected void doAction(MouseEvent e) { final DefaultActionGroup group = createActionGroup(); final DataContext parent = DataManager.getInstance().getDataContext(myPanel.getParent()); - final DataContext dataContext = SimpleDataContext.getSimpleContext(PlatformDataKeys.PROJECT.getName(), myProject, parent); + final DataContext dataContext = SimpleDataContext.getSimpleContext(CommonDataKeys.PROJECT.getName(), myProject, parent); final JBPopup popup = JBPopupFactory.getInstance() .createActionGroupPopup(null, group, dataContext, JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, true, new Runnable() { diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/GitLogUI.java b/plugins/git4idea/src/git4idea/history/wholeTree/GitLogUI.java index e738e5c7614b..02b2445d21c3 100644 --- a/plugins/git4idea/src/git4idea/history/wholeTree/GitLogUI.java +++ b/plugins/git4idea/src/git4idea/history/wholeTree/GitLogUI.java @@ -2069,7 +2069,7 @@ public class GitLogUI implements Disposable { public void execute(final MouseEvent e) { final DefaultActionGroup group = createActionGroup(); final DataContext parent = DataManager.getInstance().getDataContext(myEqualToHeadr); - final DataContext dataContext = SimpleDataContext.getSimpleContext(PlatformDataKeys.PROJECT.getName(), myProject, parent); + final DataContext dataContext = SimpleDataContext.getSimpleContext(CommonDataKeys.PROJECT.getName(), myProject, parent); final JBPopup popup = JBPopupFactory.getInstance() .createActionGroupPopup(null, group, dataContext, JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, true, new Runnable() { diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/LoadController.java b/plugins/git4idea/src/git4idea/history/wholeTree/LoadController.java index 222a37b9c8af..91fc1d7aafc6 100644 --- a/plugins/git4idea/src/git4idea/history/wholeTree/LoadController.java +++ b/plugins/git4idea/src/git4idea/history/wholeTree/LoadController.java @@ -202,14 +202,4 @@ public class LoadController implements Loader { } }); } - - private List<String> filterNumbers(final String[] s) { - final List<String> result = new ArrayList<String>(); - for (String part : s) { - if (s.length > 40) continue; - final AbstractHash abstractHash = AbstractHash.createStrict(part); - if (abstractHash != null) result.add(part); - } - return result; - } } diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/SelectRepositoryAndShowLogAction.java b/plugins/git4idea/src/git4idea/history/wholeTree/SelectRepositoryAndShowLogAction.java index 9d268670e12f..802940842887 100644 --- a/plugins/git4idea/src/git4idea/history/wholeTree/SelectRepositoryAndShowLogAction.java +++ b/plugins/git4idea/src/git4idea/history/wholeTree/SelectRepositoryAndShowLogAction.java @@ -17,6 +17,7 @@ package git4idea.history.wholeTree; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.components.ServiceManager; @@ -71,7 +72,7 @@ public class SelectRepositoryAndShowLogAction extends AnAction { @Override public void actionPerformed(AnActionEvent e) { - Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); project = project == null ? ProjectManager.getInstance().getDefaultProject() : project; final Project finalProject = project; diff --git a/plugins/git4idea/src/git4idea/log/GitLogProvider.java b/plugins/git4idea/src/git4idea/log/GitLogProvider.java new file mode 100644 index 000000000000..8d3eebdc2530 --- /dev/null +++ b/plugins/git4idea/src/git4idea/log/GitLogProvider.java @@ -0,0 +1,156 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package git4idea.log; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.VcsKey; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ArrayUtil; +import com.intellij.vcs.log.*; +import com.intellij.vcs.log.impl.HashImpl; +import com.intellij.vcs.log.impl.VcsRefImpl; +import git4idea.GitLocalBranch; +import git4idea.GitRemoteBranch; +import git4idea.GitVcs; +import git4idea.commands.GitCommand; +import git4idea.commands.GitSimpleHandler; +import git4idea.history.GitHistoryUtils; +import git4idea.history.GitLogParser; +import git4idea.repo.GitRepository; +import git4idea.repo.GitRepositoryChangeListener; +import git4idea.repo.GitRepositoryManager; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * @author Kirill Likhodedov + */ +public class GitLogProvider implements VcsLogProvider { + + private static final Logger LOG = Logger.getInstance(GitLogProvider.class); + + @NotNull private final Project myProject; + @NotNull private final GitRepositoryManager myRepositoryManager; + @NotNull private final VcsLogRefManager myRefSorter; + + public GitLogProvider(@NotNull Project project, @NotNull GitRepositoryManager repositoryManager) { + myProject = project; + myRepositoryManager = repositoryManager; + myRefSorter = new GitRefManager(myRepositoryManager); + } + + @NotNull + @Override + public List<? extends VcsFullCommitDetails> readFirstBlock(@NotNull VirtualFile root, boolean ordered) throws VcsException { + String[] params = { "HEAD", "--branches", "--remotes", "--tags", "--encoding=UTF-8", "--full-history", "--sparse", + "--max-count=" + VcsLogProvider.COMMIT_BLOCK_SIZE}; + if (ordered) { + params = ArrayUtil.append(params, "--date-order"); + } + return GitHistoryUtils.history(myProject, root, params); + } + + @NotNull + @Override + public List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root) throws VcsException { + return GitHistoryUtils.readAllHashes(myProject, root); + } + + @NotNull + @Override + public List<? extends VcsShortCommitDetails> readShortDetails(@NotNull VirtualFile root, @NotNull List<String> hashes) throws VcsException { + return GitHistoryUtils.readMiniDetails(myProject, root, hashes); + } + + @NotNull + @Override + public List<? extends VcsFullCommitDetails> readFullDetails(@NotNull VirtualFile root, @NotNull List<String> hashes) throws VcsException { + return GitHistoryUtils.commitsDetails(myProject, root, hashes); + } + + @NotNull + @Override + public Collection<VcsRef> readAllRefs(@NotNull VirtualFile root) throws VcsException { + myRepositoryManager.waitUntilInitialized(); + GitRepository repository = myRepositoryManager.getRepositoryForRoot(root); + if (repository == null) { + LOG.error("Repository not found for root " + root); + return Collections.emptyList(); + } + + repository.update(); + Collection<GitLocalBranch> localBranches = repository.getBranches().getLocalBranches(); + Collection<GitRemoteBranch> remoteBranches = repository.getBranches().getRemoteBranches(); + Collection<VcsRef> refs = new ArrayList<VcsRef>(localBranches.size() + remoteBranches.size()); + for (GitLocalBranch localBranch : localBranches) { + refs.add(new VcsRefImpl(HashImpl.build(localBranch.getHash()), localBranch.getName(), GitRefManager.LOCAL_BRANCH, root)); + } + for (GitRemoteBranch remoteBranch : remoteBranches) { + refs.add(new VcsRefImpl(HashImpl.build(remoteBranch.getHash()), remoteBranch.getNameForLocalOperations(), + GitRefManager.REMOTE_BRANCH, root)); + } + String currentRevision = repository.getCurrentRevision(); + if (currentRevision != null) { // null => fresh repository + refs.add(new VcsRefImpl(HashImpl.build(currentRevision), "HEAD", GitRefManager.HEAD, root)); + } + + refs.addAll(readTags(root)); + return refs; + } + + // TODO this is to be removed when tags will be supported by the GitRepositoryReader + private Collection<? extends VcsRef> readTags(@NotNull VirtualFile root) throws VcsException { + GitSimpleHandler tagHandler = new GitSimpleHandler(myProject, root, GitCommand.LOG); + tagHandler.addParameters("--tags", "--no-walk", "--format=%H%d" + GitLogParser.RECORD_START_GIT, "--decorate=full"); + String out = tagHandler.run(); + Collection<VcsRef> refs = new ArrayList<VcsRef>(); + for (String record : out.split(GitLogParser.RECORD_START)) { + if (!StringUtil.isEmptyOrSpaces(record)) { + refs.addAll(RefParser.parseCommitRefs(record.trim(), root)); + } + } + return refs; + } + + @NotNull + @Override + public VcsKey getSupportedVcs() { + return GitVcs.getKey(); + } + + @NotNull + @Override + public VcsLogRefManager getReferenceManager() { + return myRefSorter; + } + + @Override + public void subscribeToRootRefreshEvents(@NotNull final Collection<VirtualFile> roots, @NotNull final VcsLogRefresher refresher) { + myProject.getMessageBus().connect(myProject).subscribe(GitRepository.GIT_REPO_CHANGE, new GitRepositoryChangeListener() { + @Override + public void repositoryChanged(@NotNull GitRepository repository) { + VirtualFile root = repository.getRoot(); + if (roots.contains(root)) { + refresher.refresh(root); + } + } + }); + } +}
\ No newline at end of file diff --git a/plugins/git4idea/src/git4idea/log/GitRefManager.java b/plugins/git4idea/src/git4idea/log/GitRefManager.java new file mode 100644 index 000000000000..e27f4d25ce69 --- /dev/null +++ b/plugins/git4idea/src/git4idea/log/GitRefManager.java @@ -0,0 +1,169 @@ +package git4idea.log; + +import com.intellij.dvcs.repo.RepositoryManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Condition; +import com.intellij.ui.JBColor; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.vcs.log.RefGroup; +import com.intellij.vcs.log.VcsLogRefManager; +import com.intellij.vcs.log.VcsRef; +import com.intellij.vcs.log.VcsRefType; +import git4idea.repo.GitBranchTrackInfo; +import git4idea.repo.GitRepository; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.util.*; +import java.util.List; + +/** + * @author Kirill Likhodedov + */ +public class GitRefManager implements VcsLogRefManager { + + private static final Color HEAD_COLOR = new JBColor(new Color(0xf1ef9e), new Color(113, 111, 64)); + private static final Color LOCAL_BRANCH_COLOR = new JBColor(new Color(0x75eec7), new Color(0x0D6D4F)); + private static final Color REMOTE_BRANCH_COLOR = new JBColor(new Color(0xbcbcfc), new Color(0xbcbcfc).darker().darker()); + private static final Color TAG_COLOR = JBColor.WHITE; + + public static final VcsRefType HEAD = new SimpleRefType(true, HEAD_COLOR); + public static final VcsRefType LOCAL_BRANCH = new SimpleRefType(true, LOCAL_BRANCH_COLOR); + public static final VcsRefType REMOTE_BRANCH = new SimpleRefType(true, REMOTE_BRANCH_COLOR); + public static final VcsRefType TAG = new SimpleRefType(false, TAG_COLOR); + + // first has the highest priority + private static final List<VcsRefType> REF_TYPE_PRIORITIES = Arrays.asList(HEAD, LOCAL_BRANCH, REMOTE_BRANCH, TAG); + + // -1 => higher priority + public static final Comparator<VcsRefType> REF_TYPE_COMPARATOR = new Comparator<VcsRefType>() { + @Override + public int compare(VcsRefType type1, VcsRefType type2) { + int p1 = REF_TYPE_PRIORITIES.indexOf(type1); + int p2 = REF_TYPE_PRIORITIES.indexOf(type2); + return p1 - p2; + } + }; + + private static final String MASTER = "master"; + private static final String ORIGIN_MASTER = "origin/master"; + private static final Logger LOG = Logger.getInstance(GitRefManager.class); + + @NotNull private final RepositoryManager<GitRepository> myRepositoryManager; + + // -1 => higher priority, i. e. the ref will be displayed at the left + private final Comparator<VcsRef> REF_COMPARATOR = new Comparator<VcsRef>() { + public int compare(VcsRef ref1, VcsRef ref2) { + VcsRefType type1 = ref1.getType(); + VcsRefType type2 = ref2.getType(); + + int typeComparison = REF_TYPE_COMPARATOR.compare(type1, type2); + if (typeComparison != 0) { + return typeComparison; + } + + //noinspection UnnecessaryLocalVariable + VcsRefType type = type1; // common type + if (type == LOCAL_BRANCH) { + if (ref1.getName().equals(MASTER)) { + return -1; + } + if (ref2.getName().equals(MASTER)) { + return 1; + } + return ref1.getName().compareTo(ref2.getName()); + } + + if (type == REMOTE_BRANCH) { + if (ref1.getName().equals(ORIGIN_MASTER)) { + return -1; + } + if (ref2.getName().equals(ORIGIN_MASTER)) { + return 1; + } + if (hasTrackingBranch(ref1) && !hasTrackingBranch(ref2)) { + return -1; + } + if (!hasTrackingBranch(ref1) && hasTrackingBranch(ref2)) { + return 1; + } + return ref1.getName().compareTo(ref2.getName()); + } + + return ref1.getName().compareTo(ref2.getName()); + } + }; + + private boolean hasTrackingBranch(@NotNull final VcsRef ref) { + GitRepository repo = myRepositoryManager.getRepositoryForRoot(ref.getRoot()); + if (repo == null) { + LOG.error("Undefined root " + ref.getRoot()); + return false; + } + return ContainerUtil.find(repo.getBranchTrackInfos(), new Condition<GitBranchTrackInfo>() { + @Override + public boolean value(GitBranchTrackInfo info) { + return info.getRemoteBranch().getNameForLocalOperations().equals(ref.getName()); + } + }) != null; + } + + public GitRefManager(@NotNull RepositoryManager<GitRepository> repositoryManager) { + myRepositoryManager = repositoryManager; + } + + @NotNull + @Override + public List<VcsRef> sort(Collection<VcsRef> refs) { + ArrayList<VcsRef> list = new ArrayList<VcsRef>(refs); + Collections.sort(list, REF_COMPARATOR); + return list; + } + + @NotNull + @Override + public List<RefGroup> group(Collection<VcsRef> refs) { + // TODO group non-tracking refs into remotes + return ContainerUtil.map(sort(refs), new Function<VcsRef, RefGroup>() { + @Override + public RefGroup fun(final VcsRef ref) { + return new RefGroup() { + @NotNull + @Override + public String getName() { + return ref.getName(); + } + + @NotNull + @Override + public List<VcsRef> getRefs() { + return Collections.singletonList(ref); + } + }; + } + }); + } + + private static class SimpleRefType implements VcsRefType { + private final boolean myIsBranch; + @NotNull private final Color myColor; + + public SimpleRefType(boolean isBranch, @NotNull Color color) { + myIsBranch = isBranch; + myColor = color; + } + + @Override + public boolean isBranch() { + return myIsBranch; + } + + @NotNull + @Override + public Color getBackgroundColor() { + return myColor; + } + } + +} diff --git a/plugins/git4idea/src/git4idea/log/RefParser.java b/plugins/git4idea/src/git4idea/log/RefParser.java new file mode 100644 index 000000000000..018dab319dba --- /dev/null +++ b/plugins/git4idea/src/git4idea/log/RefParser.java @@ -0,0 +1,63 @@ +package git4idea.log; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.vcs.log.Hash; +import com.intellij.vcs.log.VcsRef; +import com.intellij.vcs.log.impl.VcsRefImpl; +import com.intellij.vcs.log.impl.HashImpl; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + + +/** + * TODO: remove when tags are supported by the {@link git4idea.repo.GitRepositoryReader}. + * + * @author erokhins + */ +class RefParser { + + // e25b7d8f (HEAD, refs/remotes/origin/master, refs/remotes/origin/HEAD, refs/heads/master) + public static List<VcsRef> parseCommitRefs(@NotNull String input, @NotNull VirtualFile root) { + int firstSpaceIndex = input.indexOf(' '); + String strHash = input.substring(0, firstSpaceIndex); + Hash hash = HashImpl.build(strHash); + String refPaths = input.substring(firstSpaceIndex + 2, input.length() - 1); + String[] longRefPaths = refPaths.split(", "); + List<VcsRef> refs = new ArrayList<VcsRef>(); + for (String longRefPatch : longRefPaths) { + VcsRef ref = createRef(hash, longRefPatch, root); + if (ref != null) { + refs.add(ref); + } + } + return refs; + } + + @Nullable + private static String getRefName(@NotNull String longRefPath, @NotNull String startPatch) { + String tagPrefix = "tag: "; + if (longRefPath.startsWith(tagPrefix)) { + longRefPath = longRefPath.substring(tagPrefix.length()); + } + if (longRefPath.startsWith(startPatch)) { + return longRefPath.substring(startPatch.length()); + } + else { + return null; + } + } + + // example input: fb29c80 refs/tags/92.29 + @Nullable + private static VcsRef createRef(@NotNull Hash hash, @NotNull String longRefPath, @NotNull VirtualFile root) { + String name = getRefName(longRefPath, "refs/tags/"); + if (name != null) { + return new VcsRefImpl(hash, name, GitRefManager.TAG, root); + } + + return null; + } +} diff --git a/plugins/git4idea/src/git4idea/push/GitPushLog.java b/plugins/git4idea/src/git4idea/push/GitPushLog.java index 3bfbec605672..335665f1c77a 100644 --- a/plugins/git4idea/src/git4idea/push/GitPushLog.java +++ b/plugins/git4idea/src/git4idea/push/GitPushLog.java @@ -114,7 +114,7 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider { Object nodeInfo = node.getUserObject(); if (nodeInfo instanceof GitCommit) { myChangesBrowser.getViewer().setEmptyText("No differences"); - myChangesBrowser.setChangesToDisplay(((GitCommit)nodeInfo).getChanges()); + myChangesBrowser.setChangesToDisplay(new ArrayList<Change>(((GitCommit)nodeInfo).getChanges())); return; } } diff --git a/plugins/git4idea/src/git4idea/rebase/GitRebaseProblemDetector.java b/plugins/git4idea/src/git4idea/rebase/GitRebaseProblemDetector.java index d039dc41d17b..6f16f65086d9 100644 --- a/plugins/git4idea/src/git4idea/rebase/GitRebaseProblemDetector.java +++ b/plugins/git4idea/src/git4idea/rebase/GitRebaseProblemDetector.java @@ -35,7 +35,8 @@ public class GitRebaseProblemDetector extends GitLineHandlerAdapter { private final static String[] REBASE_CONFLICT_INDICATORS = { "Merge conflict in", "hint: after resolving the conflicts, mark the corrected paths", - "Failed to merge in the changes"}; + "Failed to merge in the changes", + "could not apply"}; private static final String REBASE_NO_CHANGE_INDICATOR = "No changes - did you forget to use 'git add'?"; private AtomicBoolean mergeConflict = new AtomicBoolean(false); diff --git a/plugins/git4idea/src/git4idea/rebase/GitRebaser.java b/plugins/git4idea/src/git4idea/rebase/GitRebaser.java index c42e5b27c69a..d9869b2c0504 100644 --- a/plugins/git4idea/src/git4idea/rebase/GitRebaser.java +++ b/plugins/git4idea/src/git4idea/rebase/GitRebaser.java @@ -41,6 +41,7 @@ import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; /** * @author Kirill Likhodedov @@ -52,9 +53,9 @@ public class GitRebaser { private List<GitRebaseUtils.CommitInfo> mySkippedCommits; private static final Logger LOG = Logger.getInstance(GitRebaser.class); @NotNull private final Git myGit; - private final @Nullable ProgressIndicator myProgressIndicator; + private @Nullable ProgressIndicator myProgressIndicator; - public GitRebaser(Project project, @NotNull Git git, ProgressIndicator progressIndicator) { + public GitRebaser(Project project, @NotNull Git git, @Nullable ProgressIndicator progressIndicator) { myProject = project; myGit = git; myProgressIndicator = progressIndicator; @@ -62,6 +63,81 @@ public class GitRebaser { mySkippedCommits = new ArrayList<GitRebaseUtils.CommitInfo>(); } + public void setProgressIndicator(@Nullable ProgressIndicator progressIndicator) { + myProgressIndicator = progressIndicator; + } + + public GitUpdateResult rebase(@NotNull VirtualFile root, + @NotNull List<String> parameters, + @Nullable final Runnable onCancel, + @Nullable GitLineHandlerListener lineListener) { + final GitLineHandler rebaseHandler = createHandler(root); + rebaseHandler.addParameters(parameters); + if (lineListener != null) { + rebaseHandler.addLineListener(lineListener); + } + + final GitRebaseProblemDetector rebaseConflictDetector = new GitRebaseProblemDetector(); + rebaseHandler.addLineListener(rebaseConflictDetector); + GitUntrackedFilesOverwrittenByOperationDetector untrackedFilesDetector = new GitUntrackedFilesOverwrittenByOperationDetector(root); + rebaseHandler.addLineListener(untrackedFilesDetector); + + String progressTitle = "Rebasing"; + GitTask rebaseTask = new GitTask(myProject, rebaseHandler, progressTitle); + rebaseTask.setProgressIndicator(myProgressIndicator); + rebaseTask.setProgressAnalyzer(new GitStandardProgressAnalyzer()); + final AtomicReference<GitUpdateResult> updateResult = new AtomicReference<GitUpdateResult>(); + final AtomicBoolean failure = new AtomicBoolean(); + rebaseTask.executeInBackground(true, new GitTaskResultHandlerAdapter() { + @Override + protected void onSuccess() { + updateResult.set(GitUpdateResult.SUCCESS); + } + + @Override + protected void onCancel() { + if (onCancel != null) { + onCancel.run(); + } + updateResult.set(GitUpdateResult.CANCEL); + } + + @Override + protected void onFailure() { + failure.set(true); + } + }); + + if (failure.get()) { + updateResult.set(handleRebaseFailure(root, rebaseHandler, rebaseConflictDetector, untrackedFilesDetector)); + } + return updateResult.get(); + } + + protected GitLineHandler createHandler(VirtualFile root) { + return new GitLineHandler(myProject, root, GitCommand.REBASE); + } + + public GitUpdateResult handleRebaseFailure(VirtualFile root, GitLineHandler pullHandler, + GitRebaseProblemDetector rebaseConflictDetector, + GitMessageWithFilesDetector untrackedWouldBeOverwrittenDetector) { + if (rebaseConflictDetector.isMergeConflict()) { + LOG.info("handleRebaseFailure merge conflict"); + final boolean allMerged = new MyConflictResolver(myProject, myGit, root, this).merge(); + return allMerged ? GitUpdateResult.SUCCESS_WITH_RESOLVED_CONFLICTS : GitUpdateResult.INCOMPLETE; + } else if (untrackedWouldBeOverwrittenDetector.wasMessageDetected()) { + LOG.info("handleRebaseFailure: untracked files would be overwritten by checkout"); + UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject, ServiceManager.getService(myProject, GitPlatformFacade.class), + untrackedWouldBeOverwrittenDetector.getFiles(), "rebase", null); + return GitUpdateResult.ERROR; + } else { + LOG.info("handleRebaseFailure error " + pullHandler.errors()); + GitUIUtil.notifyImportantError(myProject, "Rebase error", GitUIUtil.stringifyErrors(pullHandler.errors())); + return GitUpdateResult.ERROR; + } + } + + public void abortRebase(@NotNull VirtualFile root) { LOG.info("abortRebase " + root); final GitLineHandler rh = new GitLineHandler(myProject, root, GitCommand.REBASE); @@ -95,12 +171,22 @@ public class GitRebaser { final GitRebaseProblemDetector rebaseConflictDetector = new GitRebaseProblemDetector(); rh.addLineListener(rebaseConflictDetector); + makeContinueRebaseInteractiveEditor(root, rh); + final GitTask rebaseTask = new GitTask(myProject, rh, "git rebase " + startOperation); rebaseTask.setProgressAnalyzer(new GitStandardProgressAnalyzer()); rebaseTask.setProgressIndicator(myProgressIndicator); return executeRebaseTaskInBackground(root, rh, rebaseConflictDetector, rebaseTask); } + protected void makeContinueRebaseInteractiveEditor(VirtualFile root, GitLineHandler rh) { + GitRebaseEditorService rebaseEditorService = GitRebaseEditorService.getInstance(); + // TODO If interactive rebase with commit rewording was invoked, this should take the reworded message + GitRebaser.TrivialEditor editor = new GitRebaser.TrivialEditor(rebaseEditorService, myProject, root, rh); + Integer rebaseEditorNo = editor.getHandlerNo(); + rebaseEditorService.configureHandler(rh, rebaseEditorNo); + } + /** * @return Roots which have unfinished rebase process. May be empty. */ @@ -240,6 +326,48 @@ public class GitRebaser { "You also may <b>abort rebase</b> to restore the original branch and stop rebasing."); } + private static class MyConflictResolver extends GitConflictResolver { + private final GitRebaser myRebaser; + private final VirtualFile myRoot; + + public MyConflictResolver(Project project, @NotNull Git git, VirtualFile root, GitRebaser rebaser) { + super(project, git, ServiceManager.getService(GitPlatformFacade.class), Collections.singleton(root), makeParams()); + myRebaser = rebaser; + myRoot = root; + } + + private static Params makeParams() { + Params params = new Params(); + params.setReverse(true); + params.setMergeDescription("Merge conflicts detected. Resolve them before continuing rebase."); + params.setErrorNotificationTitle("Can't continue rebase"); + params.setErrorNotificationAdditionalDescription("Then you may <b>continue rebase</b>. <br/> You also may <b>abort rebase</b> to restore the original branch and stop rebasing."); + return params; + } + + @Override protected boolean proceedIfNothingToMerge() throws VcsException { + return myRebaser.continueRebase(myRoot); + } + + @Override protected boolean proceedAfterAllMerged() throws VcsException { + return myRebaser.continueRebase(myRoot); + } + } + + public static class TrivialEditor extends GitInteractiveRebaseEditorHandler{ + public TrivialEditor(@NotNull GitRebaseEditorService service, + @NotNull Project project, + @NotNull VirtualFile root, + @NotNull GitHandler handler) { + super(service, project, root, handler); + } + + @Override + public int editCommits(String path) { + return 0; + } + } + @NotNull public GitUpdateResult handleRebaseFailure(@NotNull GitLineHandler handler, @NotNull VirtualFile root, @NotNull GitRebaseProblemDetector rebaseConflictDetector, diff --git a/plugins/git4idea/src/git4idea/repo/GitBranchTrackInfo.java b/plugins/git4idea/src/git4idea/repo/GitBranchTrackInfo.java index af5820d97ba9..0691206e2cf7 100644 --- a/plugins/git4idea/src/git4idea/repo/GitBranchTrackInfo.java +++ b/plugins/git4idea/src/git4idea/repo/GitBranchTrackInfo.java @@ -28,7 +28,7 @@ public class GitBranchTrackInfo { @NotNull private final GitRemoteBranch myRemoteBranch; private final boolean myMerge; - GitBranchTrackInfo(@NotNull GitLocalBranch localBranch, @NotNull GitRemoteBranch remoteBranch, boolean merge) { + public GitBranchTrackInfo(@NotNull GitLocalBranch localBranch, @NotNull GitRemoteBranch remoteBranch, boolean merge) { myLocalBranch = localBranch; myRemoteBranch = remoteBranch; myMerge = merge; diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java index 298a7d513ab6..d779dab856f3 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java @@ -16,7 +16,6 @@ package git4idea.repo; import com.intellij.dvcs.repo.AbstractRepositoryManager; -import com.intellij.dvcs.repo.RepositoryManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.ProjectLevelVcsManager; @@ -29,11 +28,12 @@ import org.jetbrains.annotations.NotNull; /** * @author Kirill Likhodedov */ -public class GitRepositoryManager extends AbstractRepositoryManager<GitRepository> implements RepositoryManager<GitRepository> { +public class GitRepositoryManager extends AbstractRepositoryManager<GitRepository> { @NotNull private final GitPlatformFacade myPlatformFacade; - public GitRepositoryManager(@NotNull Project project, @NotNull GitPlatformFacade platformFacade, + public GitRepositoryManager(@NotNull Project project, + @NotNull GitPlatformFacade platformFacade, @NotNull ProjectLevelVcsManager vcsManager) { super(project, vcsManager, platformFacade.getVcs(project), GitUtil.DOT_GIT); myPlatformFacade = platformFacade; @@ -52,4 +52,5 @@ public class GitRepositoryManager extends AbstractRepositoryManager<GitRepositor protected GitRepository createRepository(@NotNull VirtualFile root) { return GitRepositoryImpl.getFullInstance(root, myProject, myPlatformFacade, this); } + } diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java index 8c789f88b113..1cf13563884c 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java @@ -21,10 +21,11 @@ import com.intellij.dvcs.repo.RepositoryUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.Processor; +import com.intellij.vcs.log.Hash; +import com.intellij.vcs.log.impl.HashImpl; import git4idea.GitBranch; import git4idea.GitLocalBranch; import git4idea.GitRemoteBranch; -import git4idea.Hash; import git4idea.branch.GitBranchUtil; import git4idea.branch.GitBranchesCollection; import org.jetbrains.annotations.NonNls; @@ -77,7 +78,7 @@ class GitRepositoryReader { @NotNull private static Hash createHash(@Nullable String hash) { - return hash == null ? GitBranch.DUMMY_HASH : Hash.create(hash); + return hash == null ? GitBranch.DUMMY_HASH : HashImpl.build(hash); } @NotNull @@ -163,7 +164,7 @@ class GitRepositoryReader { if (!branchFile.exists()) { // can happen when rebasing from detached HEAD: IDEA-93806 return null; } - Hash hash = Hash.create(readBranchFile(branchFile)); + Hash hash = HashImpl.build(readBranchFile(branchFile)); if (branchName.startsWith(REFS_HEADS_PREFIX)) { branchName = branchName.substring(REFS_HEADS_PREFIX.length()); } @@ -321,7 +322,7 @@ class GitRepositoryReader { FileUtil.processFilesRecursively(myRefsRemotesDir, new Processor<File>() { @Override public boolean process(File file) { - if (!file.isDirectory()) { + if (!file.isDirectory() && !file.getName().equalsIgnoreCase(GitRepositoryFiles.HEAD)) { final String relativePath = FileUtil.getRelativePath(myGitDir, file); if (relativePath != null) { String branchName = FileUtil.toSystemIndependentName(relativePath); @@ -357,10 +358,10 @@ class GitRepositoryReader { } hash = shortBuffer(hash); if (branchName.startsWith(REFS_HEADS_PREFIX)) { - localBranches.add(new GitLocalBranch(branchName, Hash.create(hash))); + localBranches.add(new GitLocalBranch(branchName, HashImpl.build(hash))); } else if (branchName.startsWith(REFS_REMOTES_PREFIX)) { - GitRemoteBranch remoteBranch = GitBranchUtil.parseRemoteBranch(branchName, Hash.create(hash), remotes); + GitRemoteBranch remoteBranch = GitBranchUtil.parseRemoteBranch(branchName, HashImpl.build(hash), remotes); if (remoteBranch != null) { remoteBranches.add(remoteBranch); } diff --git a/plugins/git4idea/src/git4idea/ui/GitCommitListWithDiffPanel.java b/plugins/git4idea/src/git4idea/ui/GitCommitListWithDiffPanel.java index cd795b3033b9..7c14b04ec990 100644 --- a/plugins/git4idea/src/git4idea/ui/GitCommitListWithDiffPanel.java +++ b/plugins/git4idea/src/git4idea/ui/GitCommitListWithDiffPanel.java @@ -25,6 +25,7 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -45,7 +46,7 @@ public class GitCommitListWithDiffPanel extends JPanel { myCommitListPanel = new GitCommitListPanel(commits, null); myCommitListPanel.addListSelectionListener(new Consumer<GitCommit>() { @Override public void consume(GitCommit commit) { - myChangesBrowser.setChangesToDisplay(commit.getChanges()); + myChangesBrowser.setChangesToDisplay(new ArrayList<Change>(commit.getChanges())); } }); diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitBranchesAction.java b/plugins/git4idea/src/git4idea/ui/branch/GitBranchesAction.java index 732d5560b727..d98dcdb2c63e 100644 --- a/plugins/git4idea/src/git4idea/ui/branch/GitBranchesAction.java +++ b/plugins/git4idea/src/git4idea/ui/branch/GitBranchesAction.java @@ -16,6 +16,7 @@ package git4idea.ui.branch; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; @@ -39,7 +40,7 @@ public class GitBranchesAction extends DumbAwareAction { final Project project = e.getData(PlatformDataKeys.PROJECT); assert project != null; GitRepositoryManager repositoryManager = GitUtil.getRepositoryManager(project); - VirtualFile file = e.getData(PlatformDataKeys.VIRTUAL_FILE); + VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE); GitRepository repository = (file == null ? GitBranchUtil.getCurrentRepository(project): repositoryManager.getRepositoryForRoot(GitBranchUtil.getVcsRootOrGuess(project, file))); diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitCompareBranchesLogPanel.java b/plugins/git4idea/src/git4idea/ui/branch/GitCompareBranchesLogPanel.java index 78c9e378a463..ca5a551e16eb 100644 --- a/plugins/git4idea/src/git4idea/ui/branch/GitCompareBranchesLogPanel.java +++ b/plugins/git4idea/src/git4idea/ui/branch/GitCompareBranchesLogPanel.java @@ -149,7 +149,7 @@ class GitCompareBranchesLogPanel extends JPanel { sourcePanel.addListSelectionListener(new Consumer<GitCommit>() { @Override public void consume(GitCommit commit) { - changesBrowser.setChangesToDisplay(commit.getChanges()); + changesBrowser.setChangesToDisplay(new ArrayList<Change>(commit.getChanges())); otherPanel.clearSelection(); } }); diff --git a/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java b/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java index c2f503d741cf..b314cc914a41 100644 --- a/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java +++ b/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java @@ -27,16 +27,16 @@ import git4idea.GitBranch; import git4idea.GitUtil; import git4idea.Notificator; import git4idea.branch.GitBranchPair; -import git4idea.commands.*; -import git4idea.rebase.GitRebaseProblemDetector; +import git4idea.commands.Git; +import git4idea.commands.GitCommandResult; import git4idea.rebase.GitRebaser; import git4idea.repo.GitRepository; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; import java.util.Collections; +import java.util.List; import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; /** * Handles 'git pull --rebase' @@ -60,42 +60,13 @@ public class GitRebaseUpdater extends GitUpdater { protected GitUpdateResult doUpdate() { LOG.info("doUpdate "); String remoteBranch = getRemoteBranchToMerge(); - - final GitLineHandler rebaseHandler = new GitLineHandler(myProject, myRoot, GitCommand.REBASE); - rebaseHandler.addParameters(remoteBranch); - final GitRebaseProblemDetector rebaseConflictDetector = new GitRebaseProblemDetector(); - rebaseHandler.addLineListener(rebaseConflictDetector); - GitUntrackedFilesOverwrittenByOperationDetector untrackedFilesDetector = new GitUntrackedFilesOverwrittenByOperationDetector(myRoot); - rebaseHandler.addLineListener(untrackedFilesDetector); - - String progressTitle = makeProgressTitle("Rebasing"); - GitTask rebaseTask = new GitTask(myProject, rebaseHandler, progressTitle); - rebaseTask.setProgressIndicator(myProgressIndicator); - rebaseTask.setProgressAnalyzer(new GitStandardProgressAnalyzer()); - final AtomicReference<GitUpdateResult> updateResult = new AtomicReference<GitUpdateResult>(); - final AtomicBoolean failure = new AtomicBoolean(); - rebaseTask.executeInBackground(true, new GitTaskResultHandlerAdapter() { - @Override - protected void onSuccess() { - updateResult.set(GitUpdateResult.SUCCESS); - } - + List<String> params = Arrays.asList(remoteBranch); + return myRebaser.rebase(myRoot, params, new Runnable() { @Override - protected void onCancel() { + public void run() { cancel(); - updateResult.set(GitUpdateResult.CANCEL); } - - @Override - protected void onFailure() { - failure.set(true); - } - }); - - if (failure.get()) { - updateResult.set(myRebaser.handleRebaseFailure(rebaseHandler, myRoot, rebaseConflictDetector, untrackedFilesDetector)); - } - return updateResult.get(); + }, null); } @NotNull diff --git a/plugins/git4idea/src/git4idea/update/GitSkippedCommits.java b/plugins/git4idea/src/git4idea/update/GitSkippedCommits.java index f3b167faf340..b230162ce68f 100644 --- a/plugins/git4idea/src/git4idea/update/GitSkippedCommits.java +++ b/plugins/git4idea/src/git4idea/update/GitSkippedCommits.java @@ -15,6 +15,7 @@ */ package git4idea.update; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.CommonShortcuts; import com.intellij.openapi.actionSystem.CustomShortcutSet; import com.intellij.openapi.actionSystem.DefaultActionGroup; @@ -153,7 +154,7 @@ public class GitSkippedCommits extends PanelWithActionsAndCloseButton { @Override public Object getData(String dataId) { - if (PlatformDataKeys.PROJECT.is(dataId)) { + if (CommonDataKeys.PROJECT.is(dataId)) { return myProject; } TreePath selectionPath = myTree.getSelectionPath(); diff --git a/plugins/git4idea/src/org/hanuna/gitalk/git/reader/util/GitException.java b/plugins/git4idea/src/org/hanuna/gitalk/git/reader/util/GitException.java new file mode 100644 index 000000000000..fae6082502c9 --- /dev/null +++ b/plugins/git4idea/src/org/hanuna/gitalk/git/reader/util/GitException.java @@ -0,0 +1,11 @@ +package org.hanuna.gitalk.git.reader.util; + +/** + * @author erokhins + */ +public class GitException extends RuntimeException { + public GitException(String message) { + super(message); + } + +} diff --git a/plugins/git4idea/testFramework/git4idea/test/GitTestRepositoryManager.groovy b/plugins/git4idea/testFramework/git4idea/test/GitTestRepositoryManager.java index 4d6d89ef3b35..52bf562280fe 100644 --- a/plugins/git4idea/testFramework/git4idea/test/GitTestRepositoryManager.groovy +++ b/plugins/git4idea/testFramework/git4idea/test/GitTestRepositoryManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,19 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package git4idea.test +package git4idea.test; + +import com.intellij.dvcs.repo.RepositoryManager; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vfs.VirtualFile; +import git4idea.repo.GitRepository; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; -import com.intellij.dvcs.repo.RepositoryManager -import com.intellij.openapi.vcs.FilePath -import com.intellij.openapi.vfs.VirtualFile -import git4idea.repo.GitRepository -import org.jetbrains.annotations.NotNull -import org.jetbrains.annotations.Nullable /** * @author Kirill Likhodedov */ public class GitTestRepositoryManager implements RepositoryManager<GitRepository> { - private final List<GitRepository> myRepositories = new ArrayList<GitRepository>(); public void add(GitRepository repository) { @@ -39,6 +42,7 @@ public class GitTestRepositoryManager implements RepositoryManager<GitRepository return repository; } } + return null; } @@ -55,12 +59,12 @@ public class GitTestRepositoryManager implements RepositoryManager<GitRepository @NotNull @Override public List<GitRepository> getRepositories() { - myRepositories + return myRepositories; } @Override public boolean moreThanOneRoot() { - myRepositories.size() > 1 + return myRepositories.size() > 1; } @Override @@ -72,4 +76,9 @@ public class GitTestRepositoryManager implements RepositoryManager<GitRepository public void updateAllRepositories() { throw new UnsupportedOperationException(); } + + @Override + public void waitUntilInitialized() { + } + } diff --git a/plugins/git4idea/tests/git4idea/branch/GitBranchWorkerTest.groovy b/plugins/git4idea/tests/git4idea/branch/GitBranchWorkerTest.groovy index 3fd8dae733a9..e109fe74ce9f 100644 --- a/plugins/git4idea/tests/git4idea/branch/GitBranchWorkerTest.groovy +++ b/plugins/git4idea/tests/git4idea/branch/GitBranchWorkerTest.groovy @@ -37,6 +37,7 @@ import git4idea.test.GitLightTest import org.jetbrains.annotations.NotNull import org.junit.After import org.junit.Before +import org.junit.Ignore import org.junit.Test import java.util.regex.Matcher @@ -51,6 +52,7 @@ import static junit.framework.Assert.* * * @author Kirill Likhodedov */ +@Ignore class GitBranchWorkerTest extends GitLightTest { private GitRepository myUltimate diff --git a/plugins/git4idea/tests/git4idea/crlf/GitCrlfProblemsDetectorTest.groovy b/plugins/git4idea/tests/git4idea/crlf/GitCrlfProblemsDetectorTest.groovy index 5eb63813eb4a..da7de5b7fefa 100644 --- a/plugins/git4idea/tests/git4idea/crlf/GitCrlfProblemsDetectorTest.groovy +++ b/plugins/git4idea/tests/git4idea/crlf/GitCrlfProblemsDetectorTest.groovy @@ -21,6 +21,7 @@ import com.intellij.openapi.vfs.VirtualFile import git4idea.test.GitLightTest import org.junit.After import org.junit.Before +import org.junit.Ignore import org.junit.Test import static com.intellij.dvcs.test.Executor.cd @@ -31,6 +32,7 @@ import static org.junit.Assert.assertTrue * * @author Kirill Likhodedov */ +@Ignore class GitCrlfProblemsDetectorTest extends GitLightTest { private String myOldGlobalAutoCrlfValue diff --git a/plugins/git4idea/tests/git4idea/history/GitAnnotationsClosedTest.java b/plugins/git4idea/tests/git4idea/history/GitAnnotationsClosedTest.java index 827f6eee69cf..7b885681994f 100644 --- a/plugins/git4idea/tests/git4idea/history/GitAnnotationsClosedTest.java +++ b/plugins/git4idea/tests/git4idea/history/GitAnnotationsClosedTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,8 @@ package git4idea.history; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vcs.ProjectLevelVcsManager; @@ -201,7 +201,7 @@ public class GitAnnotationsClosedTest extends GitTest { @Nullable @Override public Object getData(@NonNls String dataId) { - if (PlatformDataKeys.PROJECT.is(dataId)) { + if (CommonDataKeys.PROJECT.is(dataId)) { return myProject; } return null; @@ -215,7 +215,8 @@ public class GitAnnotationsClosedTest extends GitTest { private void annotateFirst(final VirtualFile first) throws VcsException { final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(first); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), first); + annotation.setCloser(new Runnable() { @Override public void run() { @@ -228,7 +229,7 @@ public class GitAnnotationsClosedTest extends GitTest { private void annotateSecond() throws VcsException { final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(second); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), second); annotation.setCloser(new Runnable() { @Override public void run() { diff --git a/plugins/git4idea/tests/git4idea/history/GitLogParserTest.java b/plugins/git4idea/tests/git4idea/history/GitLogParserTest.java index 8da3c9f12b02..3290e4359a96 100644 --- a/plugins/git4idea/tests/git4idea/history/GitLogParserTest.java +++ b/plugins/git4idea/tests/git4idea/history/GitLogParserTest.java @@ -48,8 +48,8 @@ import static org.testng.Assert.assertTrue; public class GitLogParserTest extends GitTest { public static final GitLogOption[] GIT_LOG_OPTIONS = - new GitLogOption[]{SHORT_HASH, HASH, COMMIT_TIME, AUTHOR_NAME, AUTHOR_TIME, AUTHOR_EMAIL, COMMITTER_NAME, - COMMITTER_EMAIL, SUBJECT, BODY, SHORT_PARENTS, PARENTS, RAW_BODY + new GitLogOption[]{HASH, COMMIT_TIME, AUTHOR_NAME, AUTHOR_TIME, AUTHOR_EMAIL, COMMITTER_NAME, + COMMITTER_EMAIL, SUBJECT, BODY, PARENTS, PARENTS, RAW_BODY }; private VirtualFile myRoot; private GitLogParser myParser; @@ -189,8 +189,7 @@ public class GitLogParserTest extends GitTest { private void assertRecord(GitLogRecord actual, GitTestLogRecord expected, GitTestLogRecord.NameStatusOption option) throws VcsException { assertEquals(actual.getHash(), expected.getHash()); - assertEquals(actual.getShortHash(), expected.shortHash()); - + assertEquals(actual.getCommitterName(), expected.getCommitterName()); assertEquals(actual.getCommitterEmail(), expected.getCommitterEmail()); assertEquals(actual.getDate(), expected.getCommitTime()); @@ -208,8 +207,7 @@ public class GitLogParserTest extends GitTest { assertEquals(actual.getRawBody(), expected.rawBody()); assertEquals(actual.getParentsHashes(), expected.getParents()); - assertEquals(actual.getParentsShortHashes(), expected.shortParents()); - + if (option == GitTestLogRecord.NameStatusOption.NAME) { assertPaths(actual.getFilePaths(myRoot), expected.paths()); } else if (option == GitTestLogRecord.NameStatusOption.STATUS) { @@ -328,10 +326,6 @@ public class GitLogParserTest extends GitTest { return (GitTestChange[])myData.get(GitTestLogRecordInfo.CHANGES); } - String shortHash() { - return getHash().substring(0, 7); - } - String[] shortParents() { String[] parents = getParents(); String[] shortParents = new String[parents.length]; @@ -428,10 +422,6 @@ public class GitLogParserTest extends GitTest { return rawBody(); case COMMIT_TIME: return String.valueOf(getCommitTime().getTime() / 1000); - case SHORT_PARENTS: - return shortParentsAsString(); - case SHORT_HASH: - return shortHash(); case AUTHOR_NAME: return getAuthorName(); case AUTHOR_TIME: diff --git a/plugins/git4idea/tests/git4idea/log/GitLogRefSorterTest.java b/plugins/git4idea/tests/git4idea/log/GitLogRefSorterTest.java new file mode 100644 index 000000000000..7346852bab68 --- /dev/null +++ b/plugins/git4idea/tests/git4idea/log/GitLogRefSorterTest.java @@ -0,0 +1,311 @@ +package git4idea.log; + +import com.intellij.mock.MockVirtualFile; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.testFramework.UsefulTestCase; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.vcs.log.VcsRef; +import com.intellij.vcs.log.VcsRefType; +import com.intellij.vcs.log.impl.HashImpl; +import com.intellij.vcs.log.impl.VcsRefImpl; +import git4idea.GitLocalBranch; +import git4idea.GitRemoteBranch; +import git4idea.branch.GitBranchesCollection; +import git4idea.repo.*; +import git4idea.test.GitTestRepositoryManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +/** + * @author Kirill Likhodedov + */ +public class GitLogRefSorterTest extends UsefulTestCase { + + public static final MockVirtualFile MOCK_VIRTUAL_FILE = new MockVirtualFile("mockFile"); + + public void testEmpty() { + check(Collections.<VcsRef>emptyList(), Collections.<VcsRef>emptyList()); + } + + public void testSingle() { + check(given("HEAD"), + expect("HEAD")); + } + + public void testHeadIsMoreImportantThanBranch() { + check(given("master", "HEAD"), + expect("HEAD", "master")); + } + + public void testLocalBranchesAreComparedAsStrings() { + check(given("release", "feature"), + expect("feature", "release")); + } + + public void testTagIsTheLessImportant() { + check(given("tag/v1", "origin/master"), + expect("origin/master", "tag/v1")); + } + + public void testMasterIsMoreImportant() { + check(given("feature", "master"), + expect("master", "feature")); + } + + public void testOriginMasterIsMoreImportant() { + check(given("origin/master", "origin/aaa"), + expect("origin/master", "origin/aaa")); + } + + public void testRemoteBranchHavingTrackingBranchIsMoreImportant() { + check(given("feature", "origin/aaa", "origin/feature"), + expect("feature", "origin/feature", "origin/aaa")); + } + + public void testSeveral1() { + check(given("tag/v1", "feature", "HEAD", "master"), + expect("HEAD", "master", "feature", "tag/v1")); + } + + public void testSeveral2() { + check(given("origin/master", "origin/great_feature", "tag/v1", "release", "HEAD", "master"), + expect("HEAD", "master", "release", "origin/master", "origin/great_feature", "tag/v1")); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + } + + private static Collection<VcsRef> given(String... refs) { + return convertToRefs(refs); + } + + private static List<VcsRef> expect(String... refs) { + return new ArrayList<VcsRef>(convertToRefs(refs)); + } + + private static List<VcsRef> convertToRefs(String[] refs) { + return ContainerUtil.map(refs, new Function<String, VcsRef>() { + @Override + public VcsRef fun(String name) { + return ref(name); + } + }); + } + + private static VcsRef ref(String name) { + String randomHash = randomHash(); + if (isHead(name)) { + return ref(randomHash, name, GitRefManager.HEAD); + } + if (isRemoteBranch(name)) { + return ref(randomHash, name, GitRefManager.REMOTE_BRANCH); + } + if (isTag(name)) { + return ref(randomHash, name, GitRefManager.TAG); + } + return ref(randomHash, name, GitRefManager.LOCAL_BRANCH); + } + + private static String randomHash() { + return String.valueOf(new Random().nextInt()); + } + + private static boolean isHead(String name) { + return name.equals("HEAD"); + } + + private static boolean isTag(String name) { + return name.startsWith("tag/"); + } + + private static boolean isRemoteBranch(String name) { + return name.startsWith("origin/"); + } + + private static boolean isLocalBranch(String name) { + return !isHead(name) && !isTag(name) && !isRemoteBranch(name); + } + + private static VcsRef ref(String hash, String name, VcsRefType type) { + return new VcsRefImpl(HashImpl.build(hash), name, type, MOCK_VIRTUAL_FILE); + } + + private static void check(Collection<VcsRef> unsorted, List<VcsRef> expected) { + // for the sake of simplicity we check only names of references + List<VcsRef> actual = sort(unsorted); + assertEquals("Collections size don't match", expected.size(), actual.size()); + for (int i = 0; i < actual.size(); i++) { + assertEquals("Incorrect element at place " + i, expected.get(i).getName(), actual.get(i).getName()); + } + } + + private static List<VcsRef> sort(final Collection<VcsRef> refs) { + final GitTestRepositoryManager manager = new GitTestRepositoryManager(); + manager.add(new MockGitRepository() { + @NotNull + @Override + public Collection<GitBranchTrackInfo> getBranchTrackInfos() { + List<GitBranchTrackInfo> infos = new ArrayList<GitBranchTrackInfo>(); + List<VcsRef> remoteRefs = ContainerUtil.findAll(refs, new Condition<VcsRef>() { + @Override + public boolean value(VcsRef ref) { + return isRemoteBranch(ref.getName()); + } + }); + List<VcsRef> localRefs = ContainerUtil.findAll(refs, new Condition<VcsRef>() { + @Override + public boolean value(VcsRef ref) { + return isLocalBranch(ref.getName()); + } + }); + + for (final VcsRef localRef : localRefs) { + final VcsRef trackedRef = ContainerUtil.find(remoteRefs, new Condition<VcsRef>() { + @Override + public boolean value(VcsRef remoteRef) { + return localRef.getName().equals(remoteRef.getName().substring("origin/".length())); + } + }); + if (trackedRef != null) { + infos.add(new GitBranchTrackInfo(new GitLocalBranch(localRef.getName(), HashImpl.build(randomHash())), + new GitRemoteBranch(trackedRef.getName(), HashImpl.build(randomHash())) { + @NotNull + @Override + public String getNameForRemoteOperations() { + return trackedRef.getName().substring("origin/".length()); + } + + @NotNull + @Override + public String getNameForLocalOperations() { + return trackedRef.getName(); + } + + @NotNull + @Override + public GitRemote getRemote() { + return GitRemote.DOT; + } + + @Override + public boolean isRemote() { + return true; + } + }, true)); + } + } + return infos; + } + }); + return new GitRefManager(manager).sort(refs); + } + + // TODO either use the real GitRepository, or move upwards and make more generic implementation + private static class MockGitRepository implements GitRepository { + @NotNull + @Override + public VirtualFile getGitDir() { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public GitUntrackedFilesHolder getUntrackedFilesHolder() { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public GitRepoInfo getInfo() { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public GitLocalBranch getCurrentBranch() { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public GitBranchesCollection getBranches() { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public Collection<GitRemote> getRemotes() { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public Collection<GitBranchTrackInfo> getBranchTrackInfos() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isRebaseInProgress() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isOnBranch() { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public VirtualFile getRoot() { + return MOCK_VIRTUAL_FILE; + } + + @NotNull + @Override + public String getPresentableUrl() { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public Project getProject() { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public State getState() { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public String getCurrentRevision() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isFresh() { + throw new UnsupportedOperationException(); + } + + @Override + public void update() { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public String toLogString() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/plugins/git4idea/tests/git4idea/log/RefParserTest.java b/plugins/git4idea/tests/git4idea/log/RefParserTest.java new file mode 100644 index 000000000000..ea393fec1e48 --- /dev/null +++ b/plugins/git4idea/tests/git4idea/log/RefParserTest.java @@ -0,0 +1,64 @@ +package git4idea.log; + +import com.intellij.openapi.vfs.newvfs.impl.NullVirtualFile; +import com.intellij.vcs.log.VcsRef; +import org.junit.Test; + +import java.util.List; + +import static junit.framework.Assert.assertEquals; + +/** + * @author erokhins + */ +public class RefParserTest { + + public String toStr(VcsRef ref) { + return String.format("%s TAG %s", ref.getCommitHash().asString(), ref.getName()); + } + + public void runTest(String inputStr, String outStr) { + List<VcsRef> refs = RefParser.parseCommitRefs(inputStr, NullVirtualFile.INSTANCE); + StringBuilder s = new StringBuilder(); + for (VcsRef ref : refs) { + if (s.length() > 0) { + s.append("\n"); + } + s.append(toStr(ref)); + } + assertEquals(outStr, s.toString()); + } + + @Test + public void tagTest() { + runTest("22762ebf7203f6a2888425a3207d2ddc63085dd7 (tag: refs/tags/v3.6-rc1, refs/heads/br)", + "22762ebf7203f6a2888425a3207d2ddc63085dd7 TAG v3.6-rc1"); + } + + @Test + public void severalRefsTest() { + runTest("f85125c (refs/tags/v3.6-rc1, HEAD)", "f85125c TAG v3.6-rc1"); + } + + @Test + public void severalRefsTest2() { + runTest("ed7a0d14da090ea256d68a06c6f8dd7311de192e (refs/tags/category/v3.6-rc1, HEAD, refs/remotes/origin/graph_fix)", + "ed7a0d14da090ea256d68a06c6f8dd7311de192e TAG category/v3.6-rc1"); + } + + @Test + public void severalRefsTest3() { + runTest("ed7a0d14da090ea256d68a06c6f8dd7311de192e (tag: refs/tags/web/130.1599, tag: refs/tags/ruby/130.1597, " + + "tag: refs/tags/py/130.1598, " + + "tag: refs/tags/php/130.1596, tag: refs/tags/idea/130.1601, tag: refs/tags/app/130.1600)", + "ed7a0d14da090ea256d68a06c6f8dd7311de192e TAG web/130.1599\n" + + "ed7a0d14da090ea256d68a06c6f8dd7311de192e TAG ruby/130.1597\n" + + "ed7a0d14da090ea256d68a06c6f8dd7311de192e TAG py/130.1598\n" + + "ed7a0d14da090ea256d68a06c6f8dd7311de192e TAG php/130.1596\n" + + "ed7a0d14da090ea256d68a06c6f8dd7311de192e TAG idea/130.1601\n" + + "ed7a0d14da090ea256d68a06c6f8dd7311de192e TAG app/130.1600" + ); + } + + +} diff --git a/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderNewTest.groovy b/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderNewTest.groovy index ffb238d2909c..afe96be4b817 100644 --- a/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderNewTest.groovy +++ b/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderNewTest.groovy @@ -21,6 +21,7 @@ import git4idea.GitLocalBranch import git4idea.test.GitLightTest import org.junit.After import org.junit.Before +import org.junit.Ignore import org.junit.Test import static git4idea.test.GitScenarios.commit @@ -33,6 +34,7 @@ import static junit.framework.Assert.assertNull * * @author Kirill Likhodedov */ +@Ignore class GitRepositoryReaderNewTest extends GitLightTest { GitRepository myRepository diff --git a/plugins/github/github.iml b/plugins/github/github.iml index ea922cfeadc6..4a9a26bd3323 100644 --- a/plugins/github/github.iml +++ b/plugins/github/github.iml @@ -20,6 +20,10 @@ <orderEntry type="library" name="gson" level="project" /> <orderEntry type="module" module-name="dvcs" /> <orderEntry type="module" module-name="testFramework" scope="TEST" /> + <orderEntry type="module" module-name="xml-openapi" /> + <orderEntry type="module" module-name="xml" /> + <orderEntry type="module" module-name="vcs-log-api" /> + <orderEntry type="module" module-name="vcs-log-impl" /> </component> </module> diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java index c3ce3b90c6c7..bfc285c93466 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.github; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -64,15 +65,15 @@ public class GithubCreateGistAction extends DumbAwareAction { @Override public void update(final AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); if (project == null || project.isDefault()) { e.getPresentation().setVisible(false); e.getPresentation().setEnabled(false); return; } - Editor editor = e.getData(PlatformDataKeys.EDITOR); - VirtualFile file = e.getData(PlatformDataKeys.VIRTUAL_FILE); - VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); + Editor editor = e.getData(CommonDataKeys.EDITOR); + VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE); + VirtualFile[] files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY); if ((editor == null && file == null && files == null) || (editor != null && editor.getDocument().getTextLength() == 0)) { GithubUtil.setVisibleEnabled(e, false, false); @@ -83,14 +84,14 @@ public class GithubCreateGistAction extends DumbAwareAction { @Override public void actionPerformed(final AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); if (project == null || project.isDefault()) { return; } - final Editor editor = e.getData(PlatformDataKeys.EDITOR); - final VirtualFile file = e.getData(PlatformDataKeys.VIRTUAL_FILE); - final VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); + final Editor editor = e.getData(CommonDataKeys.EDITOR); + final VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE); + final VirtualFile[] files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY); if (editor == null && file == null && files == null) { return; } diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubCreatePullRequestAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubCreatePullRequestAction.java index 8c0ff6bf621f..3b69d0757273 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubCreatePullRequestAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubCreatePullRequestAction.java @@ -16,6 +16,7 @@ package org.jetbrains.plugins.github; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; @@ -82,8 +83,8 @@ public class GithubCreatePullRequestAction extends DumbAwareAction { } public void update(AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); - final VirtualFile file = e.getData(PlatformDataKeys.VIRTUAL_FILE); + final Project project = e.getData(CommonDataKeys.PROJECT); + final VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE); if (project == null || project.isDefault()) { setVisibleEnabled(e, false, false); return; @@ -105,8 +106,8 @@ public class GithubCreatePullRequestAction extends DumbAwareAction { @Override public void actionPerformed(AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); - final VirtualFile file = e.getData(PlatformDataKeys.VIRTUAL_FILE); + final Project project = e.getData(CommonDataKeys.PROJECT); + final VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE); if (project == null || project.isDisposed() || !GithubUtil.testGitExecutable(project)) { return; diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java index cfab3291206d..e72256635015 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.github; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.SelectionModel; @@ -55,7 +56,7 @@ public class GithubOpenInBrowserAction extends DumbAwareAction { @Override public void update(final AnActionEvent e) { Project project = e.getData(PlatformDataKeys.PROJECT); - VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE); + VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE); if (project == null || project.isDefault() || virtualFile == null) { setVisibleEnabled(e, false, false); return; @@ -91,8 +92,8 @@ public class GithubOpenInBrowserAction extends DumbAwareAction { @Override public void actionPerformed(final AnActionEvent e) { final Project project = e.getData(PlatformDataKeys.PROJECT); - final VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE); - final Editor editor = e.getData(PlatformDataKeys.EDITOR); + final VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE); + final Editor editor = e.getData(CommonDataKeys.EDITOR); if (virtualFile == null || project == null || project.isDisposed()) { return; } diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java index e62aee3adca0..756c50e79231 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java @@ -16,6 +16,7 @@ package org.jetbrains.plugins.github; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; @@ -66,8 +67,8 @@ public class GithubRebaseAction extends DumbAwareAction { } public void update(AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); - final VirtualFile file = e.getData(PlatformDataKeys.VIRTUAL_FILE); + final Project project = e.getData(CommonDataKeys.PROJECT); + final VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE); if (project == null || project.isDefault()) { setVisibleEnabled(e, false, false); return; @@ -89,8 +90,8 @@ public class GithubRebaseAction extends DumbAwareAction { @Override public void actionPerformed(final AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); - final VirtualFile file = e.getData(PlatformDataKeys.VIRTUAL_FILE); + final Project project = e.getData(CommonDataKeys.PROJECT); + final VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE); if (project == null || project.isDisposed() || !GithubUtil.testGitExecutable(project)) { return; @@ -170,7 +171,7 @@ public class GithubRebaseAction extends DumbAwareAction { return null; } - final String parentRepoUrl = GithubUrlUtil.getGitHost() + '/' + repositoryInfo.getParent().getFullName() + ".git"; + final String parentRepoUrl = GithubUrlUtil.getCloneUrl(repositoryInfo.getParent().getFullPath()); LOG.info("Adding GitHub parent as a remote host"); indicator.setText("Adding GitHub parent as a remote host..."); diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java index 5efa2682e695..c34102b84c19 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java @@ -95,9 +95,9 @@ public class GithubShareAction extends DumbAwareAction { @Override public void actionPerformed(final AnActionEvent e) { final Project project = e.getData(PlatformDataKeys.PROJECT); - final VirtualFile file = e.getData(PlatformDataKeys.VIRTUAL_FILE); + final VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE); - if (project == null || project.isDisposed()) { + if (project == null || project.isDisposed() || !GithubUtil.testGitExecutable(project)) { return; } @@ -172,7 +172,7 @@ public class GithubShareAction extends DumbAwareAction { return; } - final String remoteUrl = GithubUrlUtil.getGitHost() + "/" + githubInfo.getUser().getLogin() + "/" + name + ".git"; + final String remoteUrl = GithubUrlUtil.getCloneUrl(githubInfo.getUser().getLogin(), name); final String remoteName = finalExternalRemoteDetected ? "github" : "origin"; //git remote add origin git@github.com:login/name.git @@ -330,7 +330,7 @@ public class GithubShareAction extends DumbAwareAction { catch (VcsException e) { LOG.warn(e); GithubNotifications.showErrorURL(project, "Can't finish GitHub sharing process", "Successfully created project ", "'" + name + "'", - " on GitHub, but initial commit failed:<br/>" + e.getMessage(), url); + " on GitHub, but initial commit failed:<br/>" + GithubUtil.getErrorTextFromException(e), url); return false; } LOG.info("Successfully created initial commit"); diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserAction.java index 607d9d90b407..70bc45037e47 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserAction.java @@ -49,7 +49,7 @@ abstract class GithubShowCommitInBrowserAction extends DumbAwareAction { return; } - String githubUrl = GithubUrlUtil.getGitHost() + '/' + userAndRepository.getUser() + '/' + String githubUrl = GithubUrlUtil.getGithubHost() + '/' + userAndRepository.getUser() + '/' + userAndRepository.getRepository() + "/commit/" + revisionHash; BrowserUtil.launchBrowser(githubUrl); } diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserFromAnnotateAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserFromAnnotateAction.java index 0b02a0bdfe06..7306c0777887 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserFromAnnotateAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserFromAnnotateAction.java @@ -16,6 +16,7 @@ package org.jetbrains.plugins.github; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -73,8 +74,8 @@ public class GithubShowCommitInBrowserFromAnnotateAction extends GithubShowCommi @Nullable private static EventData calcData(AnActionEvent e, int lineNumber) { - Project project = e.getData(PlatformDataKeys.PROJECT); - VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE); + Project project = e.getData(CommonDataKeys.PROJECT); + VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE); if (project == null || virtualFile == null) { return null; } diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java index f1e244caa0c9..fddf6441812a 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java @@ -30,10 +30,7 @@ import org.jetbrains.plugins.github.exceptions.GithubAuthenticationException; import org.jetbrains.plugins.github.exceptions.GithubJsonException; import org.jetbrains.plugins.github.exceptions.GithubRateLimitExceededException; import org.jetbrains.plugins.github.exceptions.GithubStatusCodeException; -import org.jetbrains.plugins.github.util.GithubAuthData; -import org.jetbrains.plugins.github.util.GithubSslSupport; -import org.jetbrains.plugins.github.util.GithubUrlUtil; -import org.jetbrains.plugins.github.util.GithubUtil; +import org.jetbrains.plugins.github.util.*; import java.io.IOException; import java.io.InputStream; @@ -49,7 +46,6 @@ public class GithubApiUtil { public static final String DEFAULT_GITHUB_HOST = "github.com"; - private static final int CONNECTION_TIMEOUT = 5000; private static final String PER_PAGE = "per_page=100"; private static final Logger LOG = GithubUtil.LOG; @@ -178,10 +174,11 @@ public class GithubApiUtil { @NotNull private static HttpClient getHttpClient(@Nullable GithubAuthData.BasicAuth basicAuth, boolean useProxy) { + int timeout = GithubSettings.getInstance().getConnectionTimeout(); final HttpClient client = new HttpClient(); HttpConnectionManagerParams params = client.getHttpConnectionManager().getParams(); - params.setConnectionTimeout(CONNECTION_TIMEOUT); //set connection timeout (how long it takes to connect to remote host) - params.setSoTimeout(CONNECTION_TIMEOUT); //set socket timeout (how long it takes to retrieve data from remote host) + params.setConnectionTimeout(timeout); //set connection timeout (how long it takes to connect to remote host) + params.setSoTimeout(timeout); //set socket timeout (how long it takes to retrieve data from remote host) client.getParams().setContentCharset("UTF-8"); // Configure proxySettings if it is required @@ -240,7 +237,7 @@ public class GithubApiUtil { @NotNull private static JsonElement parseResponse(@NotNull InputStream githubResponse) throws IOException { - Reader reader = new InputStreamReader(githubResponse); + Reader reader = new InputStreamReader(githubResponse, "UTF-8"); try { return new JsonParser().parse(reader); } diff --git a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java index 9331d1ff3207..a3686c93e3c6 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java +++ b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java @@ -91,7 +91,7 @@ public class GithubRepository extends BaseRepositoryImpl { return new Task[0]; } catch (GithubAuthenticationException e) { - throw new Exception(e.getMessage(), e); + throw new Exception(e.getMessage(), e); // Wrap to show error message } catch (GithubStatusCodeException e) { throw new Exception(e.getMessage(), e); diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreateGistPanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreateGistPanel.form index 5b6207c7257a..8e0e283578e6 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreateGistPanel.form +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreateGistPanel.form @@ -69,7 +69,7 @@ </grid> </constraints> <properties/> - <border type="none"/> + <border type="empty"/> <children> <component id="51bc1" class="javax.swing.JTextArea" binding="myDescriptionTextArea"> <constraints/> diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsConfigurable.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsConfigurable.java index 87e137b2f9ad..2b369fca89fc 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsConfigurable.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsConfigurable.java @@ -7,7 +7,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.VcsConfigurableProvider; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.github.util.GithubSettings; import javax.swing.*; @@ -16,10 +15,8 @@ import javax.swing.*; */ public class GithubSettingsConfigurable implements SearchableConfigurable, VcsConfigurableProvider { private GithubSettingsPanel mySettingsPane; - private final GithubSettings mySettings; public GithubSettingsConfigurable() { - mySettings = GithubSettings.getInstance(); } @NotNull @@ -35,7 +32,7 @@ public class GithubSettingsConfigurable implements SearchableConfigurable, VcsCo @NotNull public JComponent createComponent() { if (mySettingsPane == null) { - mySettingsPane = new GithubSettingsPanel(mySettings); + mySettingsPane = new GithubSettingsPanel(); } return mySettingsPane.getPanel(); } @@ -46,8 +43,7 @@ public class GithubSettingsConfigurable implements SearchableConfigurable, VcsCo public void apply() throws ConfigurationException { if (mySettingsPane != null) { - mySettings.setCredentials(mySettingsPane.getHost(), mySettingsPane.getAuthData(), true); - mySettingsPane.resetCredentialsModification(); + mySettingsPane.apply(); } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form index b166fce1ef38..747f0ec390a5 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form @@ -1,11 +1,15 @@ <?xml version="1.0" encoding="UTF-8"?> <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.plugins.github.ui.GithubSettingsPanel"> - <grid id="27dc6" binding="myPane" layout-manager="GridLayoutManager" row-count="4" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="27dc6" binding="myPane" layout-manager="GridLayoutManager" row-count="5" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <xy x="20" y="20" width="563" height="400"/> + <xy x="20" y="20" width="646" height="400"/> </constraints> <properties/> + <clientProperties> + <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/> + <html.disable class="java.lang.Boolean" value="false"/> + </clientProperties> <border type="none"/> <children> <component id="28ddd" class="javax.swing.JTextPane" binding="mySignupTextField"> @@ -25,7 +29,7 @@ </component> <vspacer id="6ace"> <constraints> - <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> + <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> </constraints> </vspacer> <component id="45bab" class="com.intellij.ui.components.JBLabel"> @@ -153,6 +157,47 @@ <text value="Auth Type:"/> </properties> </component> + <grid id="d384a" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <margin top="0" left="0" bottom="0" right="0"/> + <constraints> + <grid row="3" column="0" row-span="1" col-span="5" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + </constraints> + <properties/> + <clientProperties> + <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/> + <html.disable class="java.lang.Boolean" value="false"/> + </clientProperties> + <border type="etched" title="Other Settings:"/> + <children> + <component id="ae995" class="javax.swing.JLabel"> + <constraints> + <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <text value="Connection timeout:"/> + </properties> + </component> + <component id="cd677" class="javax.swing.JSpinner" binding="myTimeoutSpinner" custom-create="true"> + <constraints> + <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties/> + </component> + <hspacer id="f53f1"> + <constraints> + <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/> + </constraints> + </hspacer> + <component id="628fe" class="javax.swing.JLabel"> + <constraints> + <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <text value="ms"/> + </properties> + </component> + </children> + </grid> </children> </grid> </form> diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java index f07512db669b..17e5cc597fd7 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java @@ -18,6 +18,7 @@ package org.jetbrains.plugins.github.ui; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.ui.ComboBox; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.DocumentAdapter; @@ -65,11 +66,12 @@ public class GithubSettingsPanel { private ComboBox myAuthTypeComboBox; private JPanel myCardPanel; private JBLabel myAuthTypeLabel; + private JSpinner myTimeoutSpinner; private boolean myCredentialsModified; - public GithubSettingsPanel(@NotNull final GithubSettings settings) { - mySettings = settings; + public GithubSettingsPanel() { + mySettings = GithubSettings.getInstance(); mySignupTextField.addHyperlinkListener(new HyperlinkAdapter() { @Override protected void hyperlinkActivated(final HyperlinkEvent e) { @@ -227,16 +229,34 @@ public class GithubSettingsPanel { return GithubAuthData.createAnonymous(getHost()); } + public void setConnectionTimeout(int timeout) { + myTimeoutSpinner.setValue(Integer.valueOf(timeout)); + } + + public int getConnectionTimeout() { + return ((SpinnerNumberModel)myTimeoutSpinner.getModel()).getNumber().intValue(); + } + public void reset() { setHost(mySettings.getHost()); setLogin(mySettings.getLogin()); setPassword(mySettings.isAuthConfigured() ? DEFAULT_PASSWORD_TEXT : ""); setAuthType(mySettings.getAuthType()); + setConnectionTimeout(mySettings.getConnectionTimeout()); + resetCredentialsModification(); + } + + public void apply() { + if (myCredentialsModified) { + mySettings.setCredentials(getHost(), getAuthData(), true); + } + mySettings.setConnectionTimeout(getConnectionTimeout()); resetCredentialsModification(); } public boolean isModified() { - return !Comparing.equal(mySettings.getHost(), getHost()) || myCredentialsModified; + return myCredentialsModified || !Comparing.equal(mySettings.getHost(), getHost()) || + !Comparing.equal(mySettings.getConnectionTimeout(), getConnectionTimeout()); } public void resetCredentialsModification() { @@ -247,5 +267,7 @@ public class GithubSettingsPanel { Document doc = new PlainDocument(); myPasswordField = new JPasswordField(doc, null, 0); myTokenField = new JPasswordField(doc, null, 0); + myTimeoutSpinner = + new JSpinner(new SpinnerNumberModel(Integer.valueOf(5000), Integer.valueOf(0), Integer.valueOf(60000), Integer.valueOf(500))); } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubShareDialog.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubShareDialog.java index 5c94dc9dcd0d..3b464b2828ac 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubShareDialog.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubShareDialog.java @@ -86,7 +86,7 @@ public class GithubShareDialog extends DialogWrapper { } @TestOnly - public void setRepositoryName(@NotNull String name) { + public void testSetRepositoryName(@NotNull String name) { myGithubSharePanel.setRepositoryName(name); } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSharePanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSharePanel.form index 6fe13b6383eb..31fa28e4c1c9 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSharePanel.form +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSharePanel.form @@ -23,9 +23,6 @@ </grid> </constraints> <properties/> - <clientProperties> - <caretAspectRatio class="java.lang.Float" value="0.04"/> - </clientProperties> </component> <scrollpane id="83208" class="com.intellij.ui.components.JBScrollPane"> <constraints> @@ -34,14 +31,11 @@ </grid> </constraints> <properties/> - <border type="none"/> + <border type="empty"/> <children> <component id="26029" class="javax.swing.JTextArea" binding="myDescriptionTextArea"> <constraints/> <properties/> - <clientProperties> - <caretAspectRatio class="java.lang.Float" value="0.04"/> - </clientProperties> </component> </children> </scrollpane> diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubNotifications.java b/plugins/github/src/org/jetbrains/plugins/github/util/GithubNotifications.java index 8cb16c4fb2db..4b3b6e3645d8 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/util/GithubNotifications.java +++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubNotifications.java @@ -27,6 +27,8 @@ import org.jetbrains.annotations.Nullable; import java.awt.*; +import static org.jetbrains.plugins.github.util.GithubUtil.getErrorTextFromException; + /** * @author Aleksey Pivovarov */ @@ -61,7 +63,7 @@ public class GithubNotifications { public static void showError(@NotNull Project project, @NotNull String title, @NotNull Exception e) { LOG.warn(title + "; ", e); - Notification notification = new Notification(GITHUB_NOTIFICATION_GROUP, title, e.getMessage(), NotificationType.ERROR); + Notification notification = new Notification(GITHUB_NOTIFICATION_GROUP, title, getErrorTextFromException(e), NotificationType.ERROR); Notificator.getInstance(project).notify(notification); } @@ -126,7 +128,7 @@ public class GithubNotifications { public static void showErrorDialog(final @Nullable Project project, final @NotNull String title, final @NotNull Exception e) { LOG.warn(title, e); - Messages.showErrorDialog(project, e.getMessage(), title); + Messages.showErrorDialog(project, getErrorTextFromException(e), title); } public static void showErrorDialog(final @NotNull Component component, final @NotNull String title, final @NotNull String message) { @@ -136,7 +138,7 @@ public class GithubNotifications { public static void showErrorDialog(final @NotNull Component component, final @NotNull String title, final @NotNull Exception e) { LOG.info(title, e); - Messages.showInfoMessage(component, e.getMessage(), title); + Messages.showInfoMessage(component, getErrorTextFromException(e), title); } public static int showYesNoDialog(final @Nullable Project project, final @NotNull String title, final @NotNull String message) { diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubSettings.java b/plugins/github/src/org/jetbrains/plugins/github/util/GithubSettings.java index 9a3fc6a4b3aa..deb9e9e0e4e5 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/util/GithubSettings.java +++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubSettings.java @@ -62,12 +62,21 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S public boolean PRIVATE_GIST = true; public boolean SAVE_PASSWORD = true; @NotNull public Collection<String> TRUSTED_HOSTS = new ArrayList<String>(); + public int CONNECTION_TIMEOUT = 5000; } public static GithubSettings getInstance() { return ServiceManager.getService(GithubSettings.class); } + public int getConnectionTimeout() { + return myState.CONNECTION_TIMEOUT; + } + + public void setConnectionTimeout(int timeout) { + myState.CONNECTION_TIMEOUT = timeout; + } + @NotNull public String getHost() { return myState.HOST; diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubSslSupport.java b/plugins/github/src/org/jetbrains/plugins/github/util/GithubSslSupport.java index d2aa2f1568a8..e8b34c1ef332 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/util/GithubSslSupport.java +++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubSslSupport.java @@ -111,7 +111,13 @@ public class GithubSslSupport { } @CalledInAwt - public boolean askIfShouldProceed(final String host) { + public boolean askIfShouldProceed(final String url) { + String host = GithubUrlUtil.getHostFromUrl(url); + if (host == null) { + GithubUtil.LOG.warn("Bad SSL host: " + url); + return false; + } + final String BACK_TO_SAFETY = "No, I don't trust"; final String TRUST = "Proceed anyway"; //int choice = Messages.showDialog("The security certificate of " + host + " is not trusted. Do you want to proceed anyway?", diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubUrlUtil.java b/plugins/github/src/org/jetbrains/plugins/github/util/GithubUrlUtil.java index 1b30da78843c..c93f648d0728 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/util/GithubUrlUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubUrlUtil.java @@ -16,11 +16,12 @@ package org.jetbrains.plugins.github.util; import com.intellij.openapi.util.text.StringUtil; +import org.apache.commons.httpclient.URI; +import org.apache.commons.httpclient.URIException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.github.api.GithubApiUtil; import org.jetbrains.plugins.github.api.GithubFullPath; -import org.jetbrains.plugins.github.util.GithubSettings; /** * @author Aleksey Pivovarov @@ -62,17 +63,30 @@ public class GithubUrlUtil { } /** - * Returns the "host" part of Git URLs. + * Returns the "host" part of Github URLs. * E.g.: https://github.com * https://my.company.url * Note: there is no trailing slash in the returned url. */ @NotNull - public static String getGitHost() { + public static String getGithubHost() { return "https://" + getGitHostWithoutProtocol(); } /** + * E.g.: https://github.com/suffix/ -> github.com + */ + @Nullable + public static String getHostFromUrl(@NotNull String url) { + try { + return new URI(url, false).getHost(); + } + catch (URIException e) { + return null; + } + } + + /** * E.g.: github.com * my.company.url */ @@ -153,7 +167,7 @@ public class GithubUrlUtil { */ @Nullable public static String makeGithubRepoUrlFromRemoteUrl(@NotNull String remoteUrl) { - return makeGithubRepoUrlFromRemoteUrl(remoteUrl, getGitHost()); + return makeGithubRepoUrlFromRemoteUrl(remoteUrl, getGithubHost()); } @Nullable @@ -177,6 +191,11 @@ public class GithubUrlUtil { @NotNull public static String getCloneUrl(@NotNull GithubFullPath path) { - return getGitHost() + "/" + path.getUser() + "/" + path.getRepository() + ".git"; + return getCloneUrl(path.getUser(), path.getRepository()); + } + + @NotNull + public static String getCloneUrl(@NotNull String user, @NotNull String repo) { + return getGithubHost() + "/" + user + "/" + repo + ".git"; } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubUtil.java b/plugins/github/src/org/jetbrains/plugins/github/util/GithubUtil.java index 260cb8dfaf96..804d3a1ba37c 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/util/GithubUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubUtil.java @@ -49,6 +49,7 @@ import org.jetbrains.plugins.github.ui.GithubBasicLoginDialog; import org.jetbrains.plugins.github.ui.GithubLoginDialog; import java.io.IOException; +import java.net.UnknownHostException; import java.util.List; import java.util.concurrent.atomic.AtomicReference; @@ -232,7 +233,17 @@ public class GithubUtil { throw new GithubAuthenticationException("Anonymous connection not allowed"); } - return testConnection(auth); + try { + return testConnection(auth); + } + catch (IOException e) { + if (GithubSslSupport.isCertificateException(e)) { + if (GithubSslSupport.getInstance().askIfShouldProceed(auth.getHost())) { + return testConnection(auth); + } + } + throw e; + } } @NotNull @@ -371,7 +382,10 @@ public class GithubUtil { } @NotNull - public static String getErrorTextFromException(@NotNull IOException e) { + public static String getErrorTextFromException(@NotNull Exception e) { + if (e instanceof UnknownHostException) { + return "Unknown host: " + e.getMessage(); + } return e.getMessage(); } diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubIssuesTest.java b/plugins/github/test/org/jetbrains/plugins/github/GithubIssuesTest.java index 1b471691107d..e1f6a9291920 100644 --- a/plugins/github/test/org/jetbrains/plugins/github/GithubIssuesTest.java +++ b/plugins/github/test/org/jetbrains/plugins/github/GithubIssuesTest.java @@ -68,7 +68,7 @@ public class GithubIssuesTest extends GithubTest { } }); - List<Long> expected = Arrays.asList(1L, 2L, 5L, 6L, 7L, 8L, 9L, 10L, 11L); + List<Long> expected = Arrays.asList(1L, 2L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 13L); assertTrue(Comparing.haveEqualElements(issues, expected)); } diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubShareProjectTestBase.java b/plugins/github/test/org/jetbrains/plugins/github/GithubShareProjectTestBase.java index 5dd9b218dfed..abfb5ece3819 100644 --- a/plugins/github/test/org/jetbrains/plugins/github/GithubShareProjectTestBase.java +++ b/plugins/github/test/org/jetbrains/plugins/github/GithubShareProjectTestBase.java @@ -55,7 +55,7 @@ public abstract class GithubShareProjectTestBase extends GithubTest { myDialogManager.registerDialogHandler(GithubShareDialog.class, new TestDialogHandler<GithubShareDialog>() { @Override public int handleDialog(GithubShareDialog dialog) { - dialog.setRepositoryName(PROJECT_NAME); + dialog.testSetRepositoryName(PROJECT_NAME); return DialogWrapper.OK_EXIT_CODE; } }); diff --git a/plugins/gradle/gradle.iml b/plugins/gradle/gradle.iml index d202ca053ba4..0925b1e3b32b 100644 --- a/plugins/gradle/gradle.iml +++ b/plugins/gradle/gradle.iml @@ -25,233 +25,100 @@ <orderEntry type="module-library" exported=""> <library name="Gradle"> <CLASSES> - <root url="jar://$MODULE_DIR$/lib/gradle-base-services-1.8-rc-1.jar!/" /> - <root url="jar://$MODULE_DIR$/lib/gradle-core-1.8-rc-1.jar!/" /> - <root url="jar://$MODULE_DIR$/lib/gradle-messaging-1.8-rc-1.jar!/" /> - <root url="jar://$MODULE_DIR$/lib/gradle-tooling-api-1.8-rc-1.jar!/" /> - <root url="jar://$MODULE_DIR$/lib/gradle-wrapper-1.8-rc-1.jar!/" /> - <root url="jar://$MODULE_DIR$/lib/gradle-plugins-1.8-rc-1.jar!/" /> - <root url="jar://$MODULE_DIR$/lib/gradle-build-setup-1.8-rc-1.jar!/" /> + <root url="jar://$MODULE_DIR$/lib/gradle-base-services-1.8.jar!/" /> + <root url="jar://$MODULE_DIR$/lib/gradle-core-1.8.jar!/" /> + <root url="jar://$MODULE_DIR$/lib/gradle-messaging-1.8.jar!/" /> + <root url="jar://$MODULE_DIR$/lib/gradle-tooling-api-1.8.jar!/" /> + <root url="jar://$MODULE_DIR$/lib/gradle-wrapper-1.8.jar!/" /> + <root url="jar://$MODULE_DIR$/lib/gradle-plugins-1.8.jar!/" /> + <root url="jar://$MODULE_DIR$/lib/gradle-build-setup-1.8.jar!/" /> + <root url="jar://$MODULE_DIR$/lib/gradle-native-1.8.jar!/" /> </CLASSES> <JAVADOC /> <SOURCES> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/buildSrc/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/buildSrc/src/test/resources" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ui/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ui/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ui/src/integTest/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/cli/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/cpp/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/cpp/src/integTest/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ear/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ide/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ide/src/main/resources" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ide/src/integTest/resources/org/gradle/plugins/ide/idea/IdeaIntegrationTest/canCreateAndDeleteMetaData/api/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ide/src/integTest/resources/org/gradle/plugins/ide/eclipse/EclipseIntegrationTest/canCreateAndDeleteMetaData/api/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ide/src/integTest/resources/org/gradle/plugins/ide/eclipse/EclipseIntegrationTest/canCreateAndDeleteMetaData/api/src/integTest/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ide/src/integTest/resources/org/gradle/plugins/ide/eclipse/EclipseIntegrationTest/canCreateAndDeleteMetaData/webAppJava6/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ide/src/integTest/resources/org/gradle/plugins/ide/eclipse/EclipseIntegrationTest/canCreateAndDeleteMetaData/groovyproject/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ide/src/integTest/resources/org/gradle/plugins/ide/eclipse/EclipseIntegrationTest/canCreateAndDeleteMetaData/webAppWithVars/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/tasks" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/plugins" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/ivy/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/core/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/core/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/core/src/integTest/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/core/src/testFixtures/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/ear/earWithWar/war/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/ear/earCustomized/war/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/base/prod/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/base/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/onlyif/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/onlyif/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/apiAndImpl/src/api/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/apiAndImpl/src/impl/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/apiAndImpl/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/quickstart/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/quickstart/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/multiproject/api/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/multiproject/shared/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/multiproject/shared/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/multiproject/buildSrc/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/multiproject/buildSrc/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/multiproject/services/shared/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/multiproject/services/webservice/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/multiproject/services/webservice/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/testListener/src/test/java/org/gradle" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/customizedLayout/src/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/customizedLayout/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/withIntegrationTests/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/withIntegrationTests/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/java/withIntegrationTests/src/integration-test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/antlr/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/maven/quickstart/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/maven/pomGeneration/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/scala/mixedJavaAndScala/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/scala/mixedJavaAndScala/src/main/scala" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/sonar/quickstart/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/sonar/quickstart/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/groovy/multiproject/testproject/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/groovy/multiproject/testproject/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/groovy/multiproject/testproject/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/groovy/multiproject/testproject/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/groovy/multiproject/groovycDetector/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/groovy/mixedJavaAndGroovy/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/groovy/mixedJavaAndGroovy/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/signing/maven/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/signing/conditional/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/testing/junit/categories/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/testing/jacoco/quickstart/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/testing/jacoco/quickstart/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/testing/jacoco/application/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/testing/testng/groups/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/testing/testng/suitexmlbuilder/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/testing/testng/suitexmlbuilder/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/testing/testng/java-jdk14-passing/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/testing/testng/java-jdk14-passing/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/testing/testng/java-jdk15-passing/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/testing/testng/java-jdk15-passing/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/testing/testReport/core/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/testing/testReport/util/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/userguide/ant/useExternalAntTaskWithConfig/src" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/userguide/java/sourceSets/src/intTest/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/userguide/multiproject/dependencies/java/api/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/userguide/multiproject/dependencies/java/api/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/userguide/multiproject/dependencies/java/shared/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/userguide/multiproject/dependencies/java/shared/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/userguide/multiproject/dependencies/java/services/personService/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/userguide/multiproject/dependencies/java/services/personService/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/userguide/multiproject/dependencies/webDist/date/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/userguide/multiproject/dependencies/webDist/hello/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/userguide/multiproject/dependencies/javaWithCustomConf/api/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/userguide/multiproject/dependencies/javaWithCustomConf/shared/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/ivypublish/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/ivypublish/subproject/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/toolingApi/idea/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/toolingApi/model/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/toolingApi/eclipse/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/toolingApi/runBuild/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/toolingApi/customModel/plugin/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/toolingApi/customModel/tooling/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/application/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/codeQuality/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/sonarRunner/quickstart/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/sonarRunner/quickstart/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/maven-publish/quickstart/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/maven-publish/javaProject/subproject/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/buildDashboard/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/webApplication/customized/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/webApplication/customized/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/webApplication/quickstart/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/docs/src/samples/clientModuleDependencies/shared/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/osgi/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/osgi/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/antlr/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/jetty/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/maven/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/maven/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/scala/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/scala/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/scala/src/integTest/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/scala/src/integTest/resources/org/gradle/scala/compile/jdk6/ZincScalaCompilerJdk6IntegrationTest/compilesJavaCodeIncrementally/src/main/scala" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/scala/src/integTest/resources/org/gradle/scala/compile/IncrementalScalaCompileIntegrationTest/recompilesSourceWhenPropertiesChange/src/main/scala" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/sonar/runner/SonarRunnerSmokeIntegrationTest/shared/nested/nested2/nestedProject/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/sonar/runner/SonarRunnerSmokeIntegrationTest/shared/nested/nested2/nestedProject/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/sonar/runner/SonarRunnerSmokeIntegrationTest/shared/skippedProject/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/sonar/runner/SonarRunnerSmokeIntegrationTest/shared/skippedProject/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/sonar/runner/SonarRunnerSmokeIntegrationTest/shared/customizedProject/src" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/sonar/runner/SonarRunnerSmokeIntegrationTest/shared/customizedProject/test" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/sonar/runner/SonarRunnerSmokeIntegrationTest/shared/javaProjectWithJacoco/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/sonar/runner/SonarRunnerSmokeIntegrationTest/shared/javaProjectWithJacoco/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/plugins/sonar/SonarSmokeIntegrationTest/shared/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/plugins/sonar/SonarSmokeIntegrationTest/shared/nested/nested2/nestedProject/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/plugins/sonar/SonarSmokeIntegrationTest/shared/nested/nested2/nestedProject/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/plugins/sonar/SonarSmokeIntegrationTest/shared/skippedProject/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/plugins/sonar/SonarSmokeIntegrationTest/shared/skippedProject/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/plugins/sonar/SonarSmokeIntegrationTest/shared/customizedProject/src" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/plugins/sonar/SonarSmokeIntegrationTest/shared/customizedProject/test" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/plugins/sonar/SonarSmokeIntegrationTest/shared/javaProjectWithJacoco/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/sonar/src/integTest/resources/org/gradle/api/plugins/sonar/SonarSmokeIntegrationTest/shared/javaProjectWithJacoco/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/jacoco/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/native/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/java/compile/IncrementalJavaCompileIntegrationTest/recompilesDependentClasses/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/java/compile/IncrementalJavaCompileIntegrationTest/recompilesDependentClasses" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/java/compile/IncrementalJavaCompileIntegrationTest/recompilesSourceWhenPropertiesChange/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/java/compile/IncrementalJavaCompileIntegrationTest/recompilesDependentClassesAcrossProjectBoundaries/app/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/java/compile/IncrementalJavaCompileIntegrationTest/recompilesDependentClassesAcrossProjectBoundaries/lib/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/java/compile/IncrementalJavaCompileIntegrationTest/recompilesDependentClassesAcrossProjectBoundaries" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/groovy/compile/GroovyCompilerIntegrationSpec/canUseThirdPartyAstTransform/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/groovy/compile/GroovyCompilerIntegrationSpec/canJointCompileWithJavaCompilerExecutable/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/groovy/compile/GroovyCompilerIntegrationSpec/canUseAstTransformThatReferencesGroovyTestCase/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/groovy/compile/BasicGroovyCompilerIntegrationSpec/compileBadJavaCode/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/groovy/compile/IncrementalGroovyCompileIntegrationTest/recompilesSourceWhenPropertiesChange/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/compile/daemon/ParallelCompilerDaemonIntegrationTest/shared" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/javadoc/JavadocIntegrationTest/handlesTagsAndTaglets/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/javadoc/JavadocIntegrationTest/handlesTagsAndTaglets/src/taglet/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/javadoc/JavadocIntegrationTest/canCombineLocalOptionWithOtherOptions/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/javadoc/JavadocIntegrationTest/canCombineLocalOptionWithOtherOptions/src/taglet/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources/org/gradle/testing/junit/JUnitIntegrationTest/junit3Tests/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/integTest/resources" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/plugins/src/testFixtures/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/publish/src/main/groovy/org/gradle/api/publish/plugins" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/publish/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/wrapper/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/wrapper/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/announce/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/launcher/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/launcher/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/launcher/src/integTest/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/open-api/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/open-api/src/integTest/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/core-impl/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/core-impl/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/messaging/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/messaging/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/reporting/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/resources/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/integ-test/src/integTest/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/integ-test/src/integTest/resources/org/gradle/integtests/ExecIntegrationTest/shared/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/integ-test/src/integTest/resources/org/gradle/integtests/ProjectLayoutIntegrationTest/canUseANonStandardBuildDir/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/integ-test/src/integTest/resources/org/gradle/integtests/ProjectLayoutIntegrationTest/canUseANonStandardBuildDir/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/javascript/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-setup/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-setup/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/testjar/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/testjar/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/multiModule/webinar-api/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/multiModule/webinar-impl/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/multiModule/webinar-impl/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/singleModule/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/singleModule/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/enforcerplugin/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-api/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-impl/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-impl/src/test/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/diagnostics/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/diagnostics/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/diagnostics/src/integTest/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/performance/src/configPlugin" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/performance/src/testFixtures/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/tooling-api/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/tooling-api/src/integTest/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/tooling-api/src/testFixtures/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/code-quality/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/language-jvm/src/main/groovy/org/gradle/language/jvm/tasks" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/language-jvm/src/main/groovy/org/gradle/language/jvm/plugins" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/language-jvm/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/base-services/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/base-services/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/language-base/src/main/groovy/org/gradle/language/base/plugins" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/language-base/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-comparison/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-comparison/src/integTest/resources/org/gradle/api/plugins/buildcomparison/gradle/BuildComparisonIntegrationSpec/compareArchives/source/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/build-comparison/src/integTest/resources/org/gradle/api/plugins/buildcomparison/gradle/BuildComparisonIntegrationSpec/compareArchives/target/src/main/java" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/internal-testing/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/base-services-groovy/src/main/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/base-services-groovy/src/test/groovy" /> - <root url="jar://$MODULE_DIR$/lib/gradle-1.8-rc-1-src.zip!/gradle-1.8-rc-1/subprojects/internal-integ-testing/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/buildSrc/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/buildSrc/src/test/resources" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/ui/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/ui/src/test/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/ui/src/integTest/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/cli/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/cpp/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/cpp/src/integTest/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/ear/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/ide/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/ide/src/main/resources" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/tasks" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/plugins" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/ivy/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/core/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/core/src/test/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/core/src/integTest/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/core/src/testFixtures/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/osgi/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/osgi/src/test/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/antlr/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/jetty/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/maven/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/maven/src/test/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/scala/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/scala/src/test/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/jacoco/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/native/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/plugins/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/plugins/src/test/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/plugins/src/testFixtures/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/publish/src/main/groovy/org/gradle/api/publish/plugins" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/publish/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/wrapper/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/wrapper/src/test/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/announce/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/launcher/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/launcher/src/test/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/launcher/src/integTest/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/open-api/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/open-api/src/integTest/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/core-impl/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/core-impl/src/test/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/messaging/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/messaging/src/test/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/reporting/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/resources/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/javascript/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-setup/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-setup/src/test/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/testjar/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/testjar/src/test/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/multiModule/webinar-api/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/multiModule/webinar-impl/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/multiModule/webinar-impl/src/test/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/singleModule/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/singleModule/src/test/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/enforcerplugin/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-api/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-impl/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-setup/src/integTest/resources/org/gradle/buildsetup/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-impl/src/test/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/diagnostics/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/diagnostics/src/test/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/diagnostics/src/integTest/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/performance/src/configPlugin" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/performance/src/testFixtures/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/tooling-api/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/tooling-api/src/integTest/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/tooling-api/src/testFixtures/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/code-quality/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/language-jvm/src/main/groovy/org/gradle/language/jvm/tasks" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/language-jvm/src/main/groovy/org/gradle/language/jvm/plugins" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/language-jvm/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/base-services/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/base-services/src/test/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/language-base/src/main/groovy/org/gradle/language/base/plugins" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/language-base/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-comparison/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-comparison/src/integTest/resources/org/gradle/api/plugins/buildcomparison/gradle/BuildComparisonIntegrationSpec/compareArchives/source/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/build-comparison/src/integTest/resources/org/gradle/api/plugins/buildcomparison/gradle/BuildComparisonIntegrationSpec/compareArchives/target/src/main/java" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/internal-testing/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/base-services-groovy/src/main/groovy" /> + <root url="jar://$MODULE_DIR$/lib/gradle-1.8-src.zip!/gradle-1.8/subprojects/base-services-groovy/src/test/groovy" /> </SOURCES> </library> </orderEntry> @@ -287,6 +154,15 @@ </SOURCES> </library> </orderEntry> + <orderEntry type="module-library" exported=""> + <library name="commons-io"> + <CLASSES> + <root url="jar://$MODULE_DIR$/lib/commons-io-1.4.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES /> + </library> + </orderEntry> <orderEntry type="module" module-name="external-system-impl" /> <orderEntry type="module" module-name="external-system-api" /> </component> diff --git a/plugins/gradle/lib/commons-io-1.4.jar b/plugins/gradle/lib/commons-io-1.4.jar Binary files differnew file mode 100644 index 000000000000..133dc6cb35f5 --- /dev/null +++ b/plugins/gradle/lib/commons-io-1.4.jar diff --git a/plugins/gradle/lib/gradle-1.8-rc-1-src.zip b/plugins/gradle/lib/gradle-1.8-src.zip Binary files differindex efb165c65be0..d4857b6e5b95 100644 --- a/plugins/gradle/lib/gradle-1.8-rc-1-src.zip +++ b/plugins/gradle/lib/gradle-1.8-src.zip diff --git a/plugins/gradle/lib/gradle-base-services-1.8-rc-1.jar b/plugins/gradle/lib/gradle-base-services-1.8.jar Binary files differindex 987ca414bdd1..8f1c65d7e537 100644 --- a/plugins/gradle/lib/gradle-base-services-1.8-rc-1.jar +++ b/plugins/gradle/lib/gradle-base-services-1.8.jar diff --git a/plugins/gradle/lib/gradle-build-setup-1.8-rc-1.jar b/plugins/gradle/lib/gradle-build-setup-1.8.jar Binary files differindex 277fc457fd15..5a92990ca915 100644 --- a/plugins/gradle/lib/gradle-build-setup-1.8-rc-1.jar +++ b/plugins/gradle/lib/gradle-build-setup-1.8.jar diff --git a/plugins/gradle/lib/gradle-core-1.8-rc-1.jar b/plugins/gradle/lib/gradle-core-1.8.jar Binary files differindex 507542ae20dc..e0fda00c9b10 100644 --- a/plugins/gradle/lib/gradle-core-1.8-rc-1.jar +++ b/plugins/gradle/lib/gradle-core-1.8.jar diff --git a/plugins/gradle/lib/gradle-messaging-1.8-rc-1.jar b/plugins/gradle/lib/gradle-messaging-1.8.jar Binary files differindex ccec28658045..9cf71f59eaf2 100644 --- a/plugins/gradle/lib/gradle-messaging-1.8-rc-1.jar +++ b/plugins/gradle/lib/gradle-messaging-1.8.jar diff --git a/plugins/gradle/lib/gradle-native-1.8.jar b/plugins/gradle/lib/gradle-native-1.8.jar Binary files differnew file mode 100644 index 000000000000..84b4bf79af1c --- /dev/null +++ b/plugins/gradle/lib/gradle-native-1.8.jar diff --git a/plugins/gradle/lib/gradle-plugins-1.8-rc-1.jar b/plugins/gradle/lib/gradle-plugins-1.8.jar Binary files differindex 82d8c42c127a..071d1c1bfc4e 100644 --- a/plugins/gradle/lib/gradle-plugins-1.8-rc-1.jar +++ b/plugins/gradle/lib/gradle-plugins-1.8.jar diff --git a/plugins/gradle/lib/gradle-tooling-api-1.8-rc-1.jar b/plugins/gradle/lib/gradle-tooling-api-1.8.jar Binary files differindex babe71ae9684..7e744bbc33ee 100644 --- a/plugins/gradle/lib/gradle-tooling-api-1.8-rc-1.jar +++ b/plugins/gradle/lib/gradle-tooling-api-1.8.jar diff --git a/plugins/gradle/lib/gradle-wrapper-1.8-rc-1.jar b/plugins/gradle/lib/gradle-wrapper-1.8.jar Binary files differindex 9377c402af67..31e2d66f8404 100644 --- a/plugins/gradle/lib/gradle-wrapper-1.8-rc-1.jar +++ b/plugins/gradle/lib/gradle-wrapper-1.8.jar diff --git a/plugins/gradle/resources/fileTemplates/internal/Gradle Build Script with wrapper.gradle.ft b/plugins/gradle/resources/fileTemplates/internal/Gradle Build Script with wrapper.gradle.ft index 60464171c93d..6199e791db69 100644 --- a/plugins/gradle/resources/fileTemplates/internal/Gradle Build Script with wrapper.gradle.ft +++ b/plugins/gradle/resources/fileTemplates/internal/Gradle Build Script with wrapper.gradle.ft @@ -4,8 +4,8 @@ sourceCompatibility = 1.5 version = '1.0' task wrapper(type: Wrapper) { - gradleVersion = '1.8-rc-1' - distributionUrl = 'http://services.gradle.org/distributions/gradle-1.8-rc-1-all.zip' + gradleVersion = '1.8' + distributionUrl = 'http://services.gradle.org/distributions/gradle-1.8-all.zip' } repositories { diff --git a/plugins/gradle/resources/i18n/GradleDocumentationBundle.properties b/plugins/gradle/resources/i18n/GradleDocumentationBundle.properties index d286e2bd17ba..857b741c2b60 100644 --- a/plugins/gradle/resources/i18n/GradleDocumentationBundle.properties +++ b/plugins/gradle/resources/i18n/GradleDocumentationBundle.properties @@ -43,39 +43,39 @@ gradle.documentation.org.gradle.api.Project.apply.plugin.build-announcements=\ <p>Sends local announcements to your desktop about interesting events in the build lifecycle.</p> gradle.documentation.org.gradle.api.Project.apply.plugin.checkstyle=\ <p>Performs quality checks on your project's Java source files using\ - <a class="ulink" href="http://checkstyle.sourceforge.net/index.html" target="_top">Checkstyle</a>\ + <a class="ulink" href="http://checkstyle.sourceforge.net/index.html" target="_top">Checkstyle</a> \ and generates reports from these checks.\ </p> gradle.documentation.org.gradle.api.Project.apply.plugin.codenarc=\ - <p>Performs quality checks on your project's Groovy source files using\ + <p>Performs quality checks on your project's Groovy source files using \ <a class="ulink" href="http://codenarc.sourceforge.net/index.html" target="_top">CodeNarc</a>\ and generates reports from these checks.\ </p> gradle.documentation.org.gradle.api.Project.apply.plugin.eclipse=\ - <p>Generates files that are used by <a class="ulink" href="http://eclipse.org" target="_top">Eclipse IDE</a>, thus making\ + <p>Generates files that are used by <a class="ulink" href="http://eclipse.org" target="_top">Eclipse IDE</a>, thus making \ it possible to import the project into Eclipse. \ See also <a class="xref" href="http://www.gradle.org/docs/current/userguide/tutorial_java_projects.html">Chapter 7, <i>Java Quickstart</i></a>.</p> gradle.documentation.org.gradle.api.Project.apply.plugin.eclipse-wtp=\ - <p>Does the same as the eclipse plugin plus generates eclipse WTP (Web Tools Platform) configuration files.\ + <p>Does the same as the eclipse plugin plus generates eclipse WTP (Web Tools Platform) configuration files. \ After importing to eclipse your war/ear projects should be configured to work with WTP.\ - See also <a class="xref" href="http://www.gradle.org/docs/current/userguide/tutorial_java_projects.html">Chapter 7, <i>Java Quickstart</i></a>.\ + See also <a class="xref" href="http://www.gradle.org/docs/current/userguide/tutorial_java_projects.html">Chapter 7, <i>Java Quickstart</i></a>. \ </p> gradle.documentation.org.gradle.api.Project.apply.plugin.findbugs=\ - <p>Performs quality checks on your project's Java source files using\ + <p>Performs quality checks on your project's Java source files using \ <a class="ulink" href="http://findbugs.sourceforge.net" target="_top">FindBugs</a>\ and generates reports from these checks.\ </p> gradle.documentation.org.gradle.api.Project.apply.plugin.idea=\ - <p>Generates files that are used by <a class="ulink" href="http://www.jetbrains.com/idea/index.html" target="_top">Intellij IDEA IDE</a>,\ + <p>Generates files that are used by <a class="ulink" href="http://www.jetbrains.com/idea/index.html" target="_top">Intellij IDEA IDE</a>, \ thus making it possible to import the project into IDEA.\ </p> gradle.documentation.org.gradle.api.Project.apply.plugin.jdepend=\ - <p>Performs quality checks on your project's source files using\ - <a class="ulink" href="http://clarkware.com/software/JDepend.html" target="_top">JDepend</a>\ + <p>Performs quality checks on your project's source files using \ + <a class="ulink" href="http://clarkware.com/software/JDepend.html" target="_top">JDepend</a> \ and generates reports from these checks.\ </p> gradle.documentation.org.gradle.api.Project.apply.plugin.pmd=\ - <p>Performs quality checks on your project's Java source files using\ + <p>Performs quality checks on your project's Java source files using \ <a class="ulink" href="http://pmd.sourceforge.net" target="_top">PMD</a>\ and generates reports from these checks.\ </p> diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml index eda8db047b09..e536f5a7512d 100644 --- a/plugins/gradle/src/META-INF/plugin.xml +++ b/plugins/gradle/src/META-INF/plugin.xml @@ -22,6 +22,7 @@ <depends>com.intellij.modules.lang</depends> <depends>org.intellij.groovy</depends> + <depends optional="true" config-file="gradle-javaee-plugin.xml">com.intellij.javaee</depends> <extensionPoints> <extensionPoint name="projectResolve" interface="org.jetbrains.plugins.gradle.service.project.GradleProjectResolverExtension"/> @@ -29,14 +30,15 @@ </extensionPoints> <extensions defaultExtensionNs="org.jetbrains.plugins.gradle"> - <resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleRepositoriesContributor"/> - <resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleDependenciesContributor"/> + <resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleRootContributor"/> + <resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleTaskContributor"/> <resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleConfigurationsContributor"/> <resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleBuildScriptContributor"/> + <resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleRepositoriesContributor"/> + <resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleDependenciesContributor"/> <resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleArtifactsContributor"/> <resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleSourceSetsContributor"/> - <resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleTaskContributor"/> - <resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleRootContributor"/> + <resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleImplicitContributor"/> </extensions> <extensions defaultExtensionNs="com.intellij"> @@ -70,6 +72,7 @@ <lang.documentationProvider language="Groovy" implementationClass="org.jetbrains.plugins.gradle.documentation.GradleDocumentationProvider"/> <editorNotificationProvider implementation="org.jetbrains.plugins.gradle.codeInsight.UseDistributionWithSourcesNotificationProvider"/> + <annotator language="Groovy" implementationClass="org.jetbrains.plugins.gradle.service.resolve.dsl.GradleDslAnnotator"/> </extensions> @@ -83,6 +86,8 @@ <methodDescriptor class="org.gradle.api.Project" name="apply"> <namedArgument name="plugin" values="java,groovy,idea,eclipse,scala,antlr,application,ear,jetty,maven,osgi,war,announce,build-announcements,checkstyle,codenarc,eclipse-wtp,findbugs,jdepend,pmd,project-report,signing,sonar"/> </methodDescriptor> + <referenceTypeEnhancer implementation="org.jetbrains.plugins.gradle.service.resolve.NamedDomainObjectCollectionTypeEnhancer"/> + <unresolvedHighlightFilter implementation="org.jetbrains.plugins.gradle.service.resolve.GradleUnresolvedReferenceFilter"/> </extensions> </idea-plugin> diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java index 1acfbf15fd69..0ffd7cd803e5 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java @@ -40,6 +40,7 @@ import com.intellij.openapi.externalSystem.service.ui.DefaultExternalSystemUiAwa import com.intellij.openapi.externalSystem.task.ExternalSystemTaskManager; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; +import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.module.EmptyModuleType; import com.intellij.openapi.module.JavaModuleType; @@ -339,7 +340,7 @@ public class GradleManager @Override public void onFailure(@NotNull String errorMessage, @Nullable String errorDetails) { } - }, true, true); + }, false, ProgressExecutionMode.MODAL_SYNC); } } }); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/AbstractGradleLinkedProjectAction.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/AbstractGradleLinkedProjectAction.java index 451fdd97fa6a..8045316d5eee 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/AbstractGradleLinkedProjectAction.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/AbstractGradleLinkedProjectAction.java @@ -2,6 +2,7 @@ package org.jetbrains.plugins.gradle.action; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; @@ -33,7 +34,7 @@ public abstract class AbstractGradleLinkedProjectAction extends AnAction { @Override public void actionPerformed(AnActionEvent e) { - final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); if (project == null) { return; } @@ -51,7 +52,7 @@ public abstract class AbstractGradleLinkedProjectAction extends AnAction { return null; } - final Project project = PlatformDataKeys.PROJECT.getData(context); + final Project project = CommonDataKeys.PROJECT.getData(context); if (project == null) { return null; } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleToolWindowHelpAction.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleToolWindowHelpAction.java index 6f9dbfb00a86..d8274df4b3a8 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleToolWindowHelpAction.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleToolWindowHelpAction.java @@ -2,6 +2,7 @@ package org.jetbrains.plugins.gradle.action; import com.intellij.ide.actions.ContextHelpAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; @@ -17,7 +18,7 @@ public class GradleToolWindowHelpAction extends ContextHelpAction { @Override public void update(AnActionEvent event) { - final Project project = PlatformDataKeys.PROJECT.getData(event.getDataContext()); + final Project project = CommonDataKeys.PROJECT.getData(event.getDataContext()); if (project == null) { event.getPresentation().setVisible(false); return; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInsight/UseDistributionWithSourcesNotificationProvider.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInsight/UseDistributionWithSourcesNotificationProvider.java index 754a52664d57..aa42f084cc04 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInsight/UseDistributionWithSourcesNotificationProvider.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInsight/UseDistributionWithSourcesNotificationProvider.java @@ -25,6 +25,7 @@ import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataMan import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; +import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtilCore; @@ -142,7 +143,7 @@ public class UseDistributionWithSourcesNotificationProvider extends EditorNotifi @Override public void onFailure(@NotNull String errorMessage, @Nullable String errorDetails) { } - }, true, true); + }, true, ProgressExecutionMode.START_IN_FOREGROUND_ASYNC); } }); return panel; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleClassFinder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleClassFinder.java index 695399a30c67..f85c75acce16 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleClassFinder.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleClassFinder.java @@ -17,19 +17,13 @@ package org.jetbrains.plugins.gradle.config; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.NonClasspathClassFinder; -import com.intellij.psi.PsiClass; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.gradle.service.GradleInstallationManager; -import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; import java.util.Collections; import java.util.List; -import java.util.Set; /** * @author peter @@ -51,24 +45,4 @@ public class GradleClassFinder extends NonClasspathClassFinder { } return Collections.emptyList(); } - - @Override - public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) { - PsiClass psiClass = null; - if (StringUtil.containsChar(qualifiedName, '.')) { - psiClass = super.findClass(qualifiedName, scope); - } - else { - final Set<String> fqnSet = ContainerUtil.set(GroovyFileBase.IMPLICITLY_IMPORTED_PACKAGES); - ContainerUtil.addAll(fqnSet, GradleDefaultImportContributor.IMPLICIT_GRADLE_PACKAGES); - for (String implicitPackage : fqnSet) { - psiClass = super.findClass(implicitPackage + '.' + qualifiedName, scope); - if (psiClass != null) { - break; - } - } - } - - return psiClass; - } }
\ No newline at end of file diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/documentation/GradleDocumentationProvider.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/documentation/GradleDocumentationProvider.java index e5948193b47c..4137a4f554dc 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/documentation/GradleDocumentationProvider.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/documentation/GradleDocumentationProvider.java @@ -27,6 +27,7 @@ import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.util.GradleConstants; import org.jetbrains.plugins.gradle.util.GradleDocumentationBundle; +import org.jetbrains.plugins.groovy.dsl.CustomMembersGenerator; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; @@ -56,13 +57,29 @@ public class GradleDocumentationProvider implements DocumentationProvider { @Nullable @Override public String generateDoc(PsiElement element, PsiElement originalElement) { - String result = null; - PsiFile file = element.getContainingFile(); - if (file == null || !file.getName().endsWith(GradleConstants.EXTENSION)) { - return null; - } + if (file == null || !file.getName().endsWith(GradleConstants.EXTENSION)) return null; + return element instanceof GrLiteral ? findDoc(element, GrLiteral.class.cast(element).getValue()) : null; + } + + @Nullable + @Override + public PsiElement getDocumentationElementForLookupItem(PsiManager psiManager, Object object, PsiElement element) { + final PsiFile file = element.getContainingFile(); + if (file == null || !file.getName().endsWith(GradleConstants.EXTENSION)) return null; + final String doc = findDoc(element, object); + return !StringUtil.isEmpty(doc) ? new CustomMembersGenerator.GdslNamedParameter(String.valueOf(object), doc, element, null) : null; + } + + @Nullable + @Override + public PsiElement getDocumentationElementForLink(PsiManager psiManager, String link, PsiElement context) { + return JavaDocUtil.findReferenceTarget(psiManager, link, context); + } + @Nullable + private static String findDoc(@Nullable PsiElement element, Object argValue) { + String result = null; if (element instanceof GrLiteral) { GrLiteral grLiteral = (GrLiteral)element; PsiElement stmt = PsiTreeUtil.findFirstParent(grLiteral, new Condition<PsiElement>() { @@ -84,28 +101,15 @@ public class GradleDocumentationProvider implements DocumentationProvider { qualifiedName, psiMethod.getName(), namedArgument.getLabelName(), - String.valueOf(grLiteral.getValue()), + String.valueOf(argValue), }, "." ); - String bndMsg = GradleDocumentationBundle.messageOrDefault(key, ""); - result = bndMsg.isEmpty() ? null : bndMsg; + result = GradleDocumentationBundle.messageOrDefault(key, ""); } } } } return result; } - - @Nullable - @Override - public PsiElement getDocumentationElementForLookupItem(PsiManager psiManager, Object object, PsiElement element) { - return null; - } - - @Nullable - @Override - public PsiElement getDocumentationElementForLink(PsiManager psiManager, String link, PsiElement context) { - return JavaDocUtil.findReferenceTarget(psiManager, link, context); - } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java index a106a73ea0fa..7745b6100e7e 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java @@ -28,11 +28,11 @@ import com.intellij.util.SystemProperties; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtilRt; import org.gradle.StartParameter; +import org.gradle.process.internal.JvmOptions; import org.gradle.tooling.*; import org.gradle.tooling.internal.consumer.DefaultGradleConnector; import org.gradle.tooling.internal.consumer.Distribution; -import org.gradle.tooling.model.idea.BasicIdeaProject; -import org.gradle.tooling.model.idea.IdeaProject; +import org.gradle.tooling.model.build.BuildEnvironment; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.settings.DistributionType; @@ -43,7 +43,6 @@ import org.jetbrains.plugins.gradle.util.GradleUtil; import java.io.File; import java.io.IOException; import java.lang.reflect.Field; -import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; @@ -53,16 +52,6 @@ import java.util.concurrent.TimeUnit; */ public class GradleExecutionHelper { - @NotNull - public ModelBuilder<? extends IdeaProject> getModelBuilder(@NotNull final ExternalSystemTaskId id, - @Nullable GradleExecutionSettings settings, - @NotNull ProjectConnection connection, - @NotNull ExternalSystemTaskNotificationListener listener, - boolean downloadLibraries) - { - return getModelBuilder(downloadLibraries ? IdeaProject.class : BasicIdeaProject.class, id, settings, connection, listener, - Collections.<String>emptyList()); - } @SuppressWarnings("MethodMayBeStatic") @NotNull @@ -74,7 +63,7 @@ public class GradleExecutionHelper { @NotNull List<String> extraJvmArgs) { ModelBuilder<T> result = connection.model(modelType); - prepare(result, id, settings, listener, extraJvmArgs); + prepare(result, id, settings, listener, extraJvmArgs, connection); return result; } @@ -88,7 +77,7 @@ public class GradleExecutionHelper { { BuildLauncher result = connection.newBuild(); List<String> extraJvmArgs = vmOptions == null ? ContainerUtil.<String>emptyList() : ContainerUtil.newArrayList(vmOptions.trim()); - prepare(result, id, settings, listener, extraJvmArgs); + prepare(result, id, settings, listener, extraJvmArgs, connection); return result; } @@ -97,7 +86,8 @@ public class GradleExecutionHelper { @NotNull final ExternalSystemTaskId id, @Nullable GradleExecutionSettings settings, @NotNull final ExternalSystemTaskNotificationListener listener, - @NotNull List<String> extraJvmArgs) + @NotNull List<String> extraJvmArgs, + @NotNull ProjectConnection connection) { if (settings == null) { return; @@ -119,7 +109,9 @@ public class GradleExecutionHelper { jvmArgs.addAll(extraJvmArgs); if (!jvmArgs.isEmpty()) { - operation.setJvmArguments(ArrayUtilRt.toStringArray(jvmArgs)); + List<String> args = connection.getModel(BuildEnvironment.class).getJava().getJvmArguments(); + List<String> merged = mergeJvmArgs(args, jvmArgs); + operation.setJvmArguments(ArrayUtilRt.toStringArray(merged)); } listener.onStart(id); @@ -231,6 +223,12 @@ public class GradleExecutionHelper { } } + private static List<String> mergeJvmArgs(List<String> jvmArgs1, List<String> jvmArgs2) { + JvmOptions jvmOptions = new JvmOptions(null); + jvmOptions.setAllJvmArgs(ContainerUtil.concat(jvmArgs1, jvmArgs2)); + return jvmOptions.getAllJvmArgs(); + } + /** * Allows to retrieve gradle api connection to use for the given project. * diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java index 9c9e361778d1..cba157a90fe1 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java @@ -18,9 +18,8 @@ import com.intellij.util.BooleanFunction; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.text.CharArrayUtil; -import gnu.trove.TObjectIntHashMap; -import gnu.trove.TObjectIntProcedure; -import org.gradle.tooling.*; +import org.gradle.tooling.ModelBuilder; +import org.gradle.tooling.ProjectConnection; import org.gradle.tooling.model.DomainObjectSet; import org.gradle.tooling.model.GradleTask; import org.gradle.tooling.model.idea.*; @@ -29,7 +28,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.remote.impl.GradleLibraryNamesMixer; import org.jetbrains.plugins.gradle.settings.ClassHolder; -import org.jetbrains.plugins.gradle.settings.DistributionType; import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings; import org.jetbrains.plugins.gradle.util.GradleConstants; import org.jetbrains.plugins.gradle.util.GradleUtil; @@ -56,7 +54,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad @Override public DataNode<ProjectData> resolveProjectInfo(@NotNull final ExternalSystemTaskId id, @NotNull final String projectPath, - final boolean downloadLibraries, + final boolean isPreviewMode, @Nullable final GradleExecutionSettings settings, @NotNull final ExternalSystemTaskNotificationListener listener) throws ExternalSystemException, IllegalArgumentException, IllegalStateException @@ -82,7 +80,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad myCachedExtensions = Pair.create(key, extensions); } for (GradleProjectResolverExtension extension : myCachedExtensions.second) { - DataNode<ProjectData> result = extension.resolveProjectInfo(id, projectPath, downloadLibraries, settings, listener); + DataNode<ProjectData> result = extension.resolveProjectInfo(id, projectPath, isPreviewMode, settings, listener); if (result != null) { return result; } @@ -92,7 +90,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad return myHelper.execute(projectPath, settings, new Function<ProjectConnection, DataNode<ProjectData>>() { @Override public DataNode<ProjectData> fun(ProjectConnection connection) { - return doResolveProjectInfo(id, projectPath, settings, connection, listener, downloadLibraries); + return doResolveProjectInfo(id, projectPath, settings, connection, listener, isPreviewMode); } }); } @@ -103,10 +101,9 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad @Nullable GradleExecutionSettings settings, @NotNull ProjectConnection connection, @NotNull ExternalSystemTaskNotificationListener listener, - boolean downloadLibraries) - throws IllegalArgumentException, IllegalStateException - { - ModelBuilder<? extends IdeaProject> modelBuilder = myHelper.getModelBuilder(id, settings, connection, listener, downloadLibraries); + boolean isPreviewMode) throws IllegalArgumentException, IllegalStateException { + ModelBuilder<? extends IdeaProject> modelBuilder = myHelper.getModelBuilder( + isPreviewMode ? BasicIdeaProject.class : IdeaProject.class, id, settings, connection, listener, Collections.<String>emptyList()); IdeaProject project = modelBuilder.get(); DataNode<ProjectData> result = populateProject(project, projectPath); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleArtifactsContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleArtifactsContributor.java index d4ae45e8fa36..5f00e43f6568 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleArtifactsContributor.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleArtifactsContributor.java @@ -49,9 +49,9 @@ public class GradleArtifactsContributor implements GradleMethodContextContributo } GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); + GradleResolverUtil.processDeclarations(psiManager, processor, state, place, GradleCommonClassNames.GRADLE_API_ARTIFACT_HANDLER); PsiClass contributorClass = psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_ARTIFACT_HANDLER, place.getResolveScope()); if (contributorClass != null) { - contributorClass.processDeclarations(processor, state, null, place); // assuming that the method call is addition of an artifact to the given configuration. processAtrifactAddition(methodCallInfo.get(0), contributorClass, processor, state, place); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java index d5a20ed3307b..f66f0c6aaed9 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java @@ -37,7 +37,25 @@ public final class GradleCommonClassNames { @NonNls public static final String GRADLE_API_SOURCE_SET_CONTAINER = "org.gradle.api.tasks.SourceSetContainer"; @NonNls public static final String GRADLE_API_SCRIPT_HANDLER = "org.gradle.api.initialization.dsl.ScriptHandler"; @NonNls public static final String GRADLE_API_TASK = "org.gradle.api.Task"; + @NonNls public static final String GRADLE_API_DEFAULT_TASK = "org.gradle.api.DefaultTask"; + @NonNls public static final String GRADLE_API_TASKS_DELETE = "org.gradle.api.tasks.Delete"; + @NonNls public static final String GRADLE_API_TASKS_BUNDLING_JAR = "org.gradle.api.tasks.bundling.Jar"; + @NonNls public static final String GRADLE_API_TASKS_COMPILE_JAVA_COMPILE = "org.gradle.api.tasks.compile.JavaCompile"; + @NonNls public static final String GRADLE_API_TASKS_WRAPPER_WRAPPER = "org.gradle.api.tasks.wrapper.Wrapper"; + @NonNls public static final String GRADLE_API_TASKS_JAVADOC_JAVADOC = "org.gradle.api.tasks.javadoc.Javadoc"; + @NonNls public static final String GRADLE_API_TASKS_DIAGNOSTICS_DEPENDENCY_REPORT_TASK = "org.gradle.api.tasks.diagnostics.DependencyReportTask"; + @NonNls public static final String GRADLE_API_TASKS_DIAGNOSTICS_DEPENDENCY_INSIGHT_REPORT_TASK = "org.gradle.api.tasks.diagnostics.DependencyInsightReportTask"; + @NonNls public static final String GRADLE_API_TASKS_DIAGNOSTICS_PROJECT_REPORT_TASK = "org.gradle.api.tasks.diagnostics.ProjectReportTask"; + @NonNls public static final String GRADLE_API_TASKS_DIAGNOSTICS_PROPERTY_REPORT_TASK = "org.gradle.api.tasks.diagnostics.PropertyReportTask"; + @NonNls public static final String GRADLE_API_TASKS_DIAGNOSTICS_TASK_REPORT_TASK = "org.gradle.api.tasks.diagnostics.TaskReportTask"; + @NonNls public static final String GRADLE_API_TASKS_TESTING_TEST = "org.gradle.api.tasks.testing.Test"; + @NonNls public static final String GRADLE_API_TASKS_UPLOAD = "org.gradle.api.tasks.Upload"; + @NonNls public static final String GRADLE_API_ARTIFACTS_REPOSITORIES_FLAT_DIRECTORY_ARTIFACT_REPOSITORY = "org.gradle.api.artifacts.repositories.FlatDirectoryArtifactRepository"; + @NonNls public static final String GRADLE_LANGUAGE_JVM_TASKS_PROCESS_RESOURCES = "org.gradle.language.jvm.tasks.ProcessResources"; + @NonNls public static final String GRADLE_BUILDSETUP_TASKS_SETUP_BUILD = "org.gradle.buildsetup.tasks.SetupBuild"; @NonNls public static final String GRADLE_API_TASK_CONTAINER = "org.gradle.api.tasks.TaskContainer"; + @NonNls public static final String GRADLE_API_JAVA_ARCHIVES_MANIFEST = "org.gradle.api.java.archives.Manifest"; + @NonNls public static final String GRADLE_API_NAMED_DOMAIN_OBJECT_COLLECTION = "org.gradle.api.NamedDomainObjectCollection"; private GradleCommonClassNames() { } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleConfigurationsContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleConfigurationsContributor.java index 926a1b77621b..9cbe87c6ae72 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleConfigurationsContributor.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleConfigurationsContributor.java @@ -15,7 +15,6 @@ */ package org.jetbrains.plugins.gradle.service.resolve; -import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.ResolveState; import com.intellij.psi.scope.PsiScopeProcessor; @@ -43,31 +42,33 @@ public class GradleConfigurationsContributor implements GradleMethodContextContr } final String methodCall = methodCallInfo.get(0); - PsiClass contributorClass = null; - GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); + String contributorClass = null; if (methodCallInfo.size() == 1) { if (methodCall.startsWith(CONFIGURATIONS + '.')) { - contributorClass = psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_CONFIGURATION, place.getResolveScope()); + contributorClass = GradleCommonClassNames.GRADLE_API_CONFIGURATION; } else if (CONFIGURATIONS.equals(methodCall)) { - contributorClass = psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_CONFIGURATION_CONTAINER, place.getResolveScope()); + contributorClass = GradleCommonClassNames.GRADLE_API_CONFIGURATION_CONTAINER; if (place instanceof GrReferenceExpressionImpl) { - GradleResolverUtil.addImplicitVariable(processor, state, (GrReferenceExpressionImpl)place, GradleCommonClassNames.GRADLE_API_CONFIGURATION); + GradleResolverUtil + .addImplicitVariable(processor, state, (GrReferenceExpressionImpl)place, GradleCommonClassNames.GRADLE_API_CONFIGURATION); return; } } } else if (methodCallInfo.size() == 2) { if (CONFIGURATIONS.equals(methodCallInfo.get(1))) { - contributorClass = psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_CONFIGURATION_CONTAINER, place.getResolveScope()); + contributorClass = GradleCommonClassNames.GRADLE_API_CONFIGURATION_CONTAINER; if (place instanceof GrReferenceExpressionImpl) { - GradleResolverUtil.addImplicitVariable(processor, state, (GrReferenceExpressionImpl)place, GradleCommonClassNames.GRADLE_API_CONFIGURATION); + GradleResolverUtil + .addImplicitVariable(processor, state, (GrReferenceExpressionImpl)place, GradleCommonClassNames.GRADLE_API_CONFIGURATION); return; } } } if (contributorClass != null) { - contributorClass.processDeclarations(processor, state, null, place); + GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); + GradleResolverUtil.processDeclarations(psiManager, processor, state, place, contributorClass); } } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java index 7685a25148db..d4cf0cdfa983 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java @@ -57,11 +57,8 @@ public class GradleDependenciesContributor implements GradleMethodContextContrib final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); if (methodCallInfo.size() == 2) { - PsiClass psiClass = - psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_ARTIFACTS_EXTERNAL_MODULE_DEPENDENCY, place.getResolveScope()); - if (psiClass != null) { - psiClass.processDeclarations(processor, state, null, place); - } + GradleResolverUtil.processDeclarations( + psiManager, processor, state, place, GradleCommonClassNames.GRADLE_API_ARTIFACTS_EXTERNAL_MODULE_DEPENDENCY); // Assuming that the method call is addition of new dependency into configuration. PsiClass contributorClass = psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_DEPENDENCY_HANDLER, place.getResolveScope()); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java new file mode 100644 index 000000000000..2936d684c361 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java @@ -0,0 +1,200 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.gradle.service.resolve; + +import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo; +import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtilCore; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiType; +import com.intellij.psi.ResolveState; +import com.intellij.psi.scope.PsiScopeProcessor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.gradle.settings.GradleLocalSettings; +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.path.GrMethodCallExpression; +import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; +import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder; +import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import static com.intellij.util.containers.ContainerUtil.*; +import static org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames.*; +import static org.jetbrains.plugins.gradle.service.resolve.GradleResolverUtil.canBeMethodOf; + +/** + * @author Vladislav.Soroka + * @since 9/24/13 + */ +public class GradleImplicitContributor implements GradleMethodContextContributor { + private final static Map<String, String> BUILT_IN_TASKS = newHashMap( + new Pair<String, String>("assemble", GRADLE_API_DEFAULT_TASK), + new Pair<String, String>("build", GRADLE_API_DEFAULT_TASK), + new Pair<String, String>("buildDependents", GRADLE_API_DEFAULT_TASK), + new Pair<String, String>("buildNeeded", GRADLE_API_DEFAULT_TASK), + new Pair<String, String>("clean", GRADLE_API_TASKS_DELETE), + new Pair<String, String>("jar", GRADLE_API_TASKS_BUNDLING_JAR), + new Pair<String, String>("classes", GRADLE_API_DEFAULT_TASK), + new Pair<String, String>("compileJava", GRADLE_API_TASKS_COMPILE_JAVA_COMPILE), + new Pair<String, String>("compileTestJava", GRADLE_API_DEFAULT_TASK), + new Pair<String, String>("processTestResources", GRADLE_API_DEFAULT_TASK), + new Pair<String, String>("testClasses", GRADLE_API_DEFAULT_TASK), + new Pair<String, String>("processResources", GRADLE_LANGUAGE_JVM_TASKS_PROCESS_RESOURCES), + new Pair<String, String>("setupBuild", GRADLE_BUILDSETUP_TASKS_SETUP_BUILD), + new Pair<String, String>("wrapper", GRADLE_API_TASKS_WRAPPER_WRAPPER), + new Pair<String, String>("javadoc", GRADLE_API_TASKS_JAVADOC_JAVADOC), + new Pair<String, String>("dependencies", GRADLE_API_TASKS_DIAGNOSTICS_DEPENDENCY_REPORT_TASK), + new Pair<String, String>("dependencyInsight", GRADLE_API_TASKS_DIAGNOSTICS_DEPENDENCY_INSIGHT_REPORT_TASK), + new Pair<String, String>("projects", GRADLE_API_TASKS_DIAGNOSTICS_PROJECT_REPORT_TASK), + new Pair<String, String>("properties", GRADLE_API_TASKS_DIAGNOSTICS_PROPERTY_REPORT_TASK), + new Pair<String, String>("tasks", GRADLE_API_TASKS_DIAGNOSTICS_TASK_REPORT_TASK), + new Pair<String, String>("check", GRADLE_API_DEFAULT_TASK), + new Pair<String, String>("test", GRADLE_API_TASKS_TESTING_TEST), + new Pair<String, String>("uploadArchives", GRADLE_API_TASKS_UPLOAD) + ); + + @Override + public void process(@NotNull List<String> methodCallInfo, + @NotNull PsiScopeProcessor processor, + @NotNull ResolveState state, + @NotNull PsiElement place) { + if (methodCallInfo.isEmpty()) { + checkForAvailableTasks(0, place.getText(), processor, state, place); + return; + } + + final String methodCall = getLastItem(methodCallInfo); + if (methodCall == null) return; + + if (!methodCall.equals("task")) { + if (methodCallInfo.size() == 1) { + checkForAvailableTasks(1, place.getText(), processor, state, place); + } + if (methodCallInfo.size() == 2) { + processAvailableTasks(methodCall, processor, state, place); + } + } + + if (methodCallInfo.size() >= 3 && Arrays.equals( + ar("dirs", "flatDir", "repositories"), methodCallInfo.subList(0, 3).toArray())) { + final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); + GradleResolverUtil.processDeclarations( + psiManager, processor, state, place, GRADLE_API_ARTIFACTS_REPOSITORIES_FLAT_DIRECTORY_ARTIFACT_REPOSITORY); + } + + if (methodCallInfo.size() == 3) { + final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); + if ("manifest".equals(methodCallInfo.get(1)) && "jar".equals(methodCallInfo.get(2))) { + GradleResolverUtil.processDeclarations( + psiManager, processor, state, place, GRADLE_API_JAVA_ARCHIVES_MANIFEST); + } + } + + if (place instanceof GrExpression && GradleResolverUtil.getTypeOf((GrExpression)place) == null) { + GrClosableBlock closableBlock = GradleResolverUtil.findParent(place, GrClosableBlock.class); + if (closableBlock != null && closableBlock.getParent() instanceof GrMethodCallExpression) { + PsiType psiType = GradleResolverUtil.getTypeOf(((GrExpression)closableBlock.getParent())); + if (psiType != null) { + final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); + GradleResolverUtil.processDeclarations( + psiManager, processor, state, place, psiType.getCanonicalText()); + } + } + } + } + + public static void processImplicitDeclarations(PsiScopeProcessor processor, ResolveState state, PsiElement place) { + if (!place.getText().equals("resources")) { + GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); + GradleResolverUtil.processDeclarations(psiManager, processor, state, place, GRADLE_API_PROJECT); + } + } + + private static void checkForAvailableTasks(int level, + String taskName, + PsiScopeProcessor processor, + ResolveState state, + PsiElement place) { + final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); + PsiClass gradleApiProjectClass = psiManager.findClassWithCache(GRADLE_API_PROJECT, place.getResolveScope()); + if (canBeMethodOf(taskName, gradleApiProjectClass)) return; + if (canBeMethodOf(GroovyPropertyUtils.getGetterNameNonBoolean(taskName), gradleApiProjectClass)) return; + + final String className = BUILT_IN_TASKS.get(taskName); + if (className != null) { + if (level <= 1) { + GradleResolverUtil.addImplicitVariable(processor, state, place, className); + } + processTask(taskName, className, psiManager, processor, state, place); + return; + } + + Module module = ModuleUtilCore.findModuleForPsiElement(place); + if (module == null) return; + String path = module.getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY); + GradleLocalSettings localSettings = GradleLocalSettings.getInstance(place.getProject()); + Collection<ExternalTaskPojo> taskPojos = localSettings.getAvailableTasks().get(path); + if (taskPojos == null) return; + + for (ExternalTaskPojo taskPojo : taskPojos) { + if (taskName.equals(taskPojo.getName())) { + processTask(taskName, GRADLE_API_TASK, psiManager, processor, state, place); + return; + } + } + } + + private static void processTask(String taskName, + String fqName, + GroovyPsiManager psiManager, + PsiScopeProcessor processor, + ResolveState state, + PsiElement place) { + if (taskName.equals(place.getText())) { + if (!(place instanceof GrClosableBlock)) { + GrLightMethodBuilder methodBuilder = GradleResolverUtil.createMethodWithClosure(taskName, fqName, fqName, place, psiManager); + if (methodBuilder == null) return; + processor.execute(methodBuilder, state); + PsiClass contributorClass = + psiManager.findClassWithCache(fqName, place.getResolveScope()); + if (contributorClass == null) return; + GradleResolverUtil.processMethod(taskName, contributorClass, processor, state, place); + } + } + else { + GradleResolverUtil.processDeclarations(psiManager, processor, state, place, fqName); + } + } + + private static void processAvailableTasks(String taskName, PsiScopeProcessor processor, ResolveState state, PsiElement place) { + final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); + PsiClass gradleApiProjectClass = psiManager.findClassWithCache(GRADLE_API_PROJECT, place.getResolveScope()); + if (canBeMethodOf(taskName, gradleApiProjectClass)) return; + if (canBeMethodOf(GroovyPropertyUtils.getGetterNameNonBoolean(taskName), gradleApiProjectClass)) return; + final String className = BUILT_IN_TASKS.get(taskName); + if (className != null) { + GradleResolverUtil.processDeclarations(psiManager, processor, state, place, className); + } + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java index ace58391b0fc..d10fe21c920e 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java @@ -15,14 +15,18 @@ */ package org.jetbrains.plugins.gradle.service.resolve; +import com.intellij.openapi.util.Key; import com.intellij.psi.*; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; +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.impl.GroovyPsiManager; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceExpressionImpl; @@ -31,11 +35,14 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; +import java.util.Set; + /** * @author Vladislav.Soroka * @since 8/30/13 */ public class GradleResolverUtil { + private static final Key<Integer> TYPE_RESOLVE_IN_PROGRESS_KEY = Key.create("TYPE_RESOLVE_IN_PROGRESS_KEY"); public static int getGrMethodArumentsCount(@NotNull GrArgumentList args) { int argsCount = 0; @@ -73,16 +80,37 @@ public class GradleResolverUtil { } - public static GrLightMethodBuilder createMethodWithClosure(@NotNull String name, @NotNull PsiElement place, @Nullable String returnType) { - GrLightMethodBuilder methodWithClosure = new GrLightMethodBuilder(place.getManager(), name); + @Nullable + public static GrLightMethodBuilder createMethodWithClosure(@NotNull String name, + @Nullable String returnType, + @Nullable String closureTypeParameter, + @NotNull PsiElement place, + @NotNull GroovyPsiManager psiManager) { + PsiClassType closureType; + PsiClass closureClass = + psiManager.findClassWithCache(GroovyCommonClassNames.GROOVY_LANG_CLOSURE, place.getResolveScope()); + if (closureClass == null) return null; + PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getManager().getProject()); - PsiClassType closureType = factory.createTypeByFQClassName(GroovyCommonClassNames.GROOVY_LANG_CLOSURE, place.getResolveScope()); + + if (closureTypeParameter != null) { + PsiClassType closureClassTypeParameter = + factory.createTypeByFQClassName(closureTypeParameter, place.getResolveScope()); + closureType = factory.createType(closureClass, closureClassTypeParameter); + } + else { + PsiClassType closureClassTypeParameter = + factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, place.getResolveScope()); + closureType = factory.createType(closureClass, closureClassTypeParameter); + } + + GrLightMethodBuilder methodWithClosure = new GrLightMethodBuilder(place.getManager(), name); GrLightParameter closureParameter = new GrLightParameter("closure", closureType, methodWithClosure); methodWithClosure.addParameter(closureParameter); - PsiClassType retType = factory.createTypeByFQClassName( returnType != null ? returnType : CommonClassNames.JAVA_LANG_OBJECT, place.getResolveScope()); methodWithClosure.setReturnType(retType); + methodWithClosure.setContainingClass(retType.resolve()); return methodWithClosure; } @@ -149,4 +177,47 @@ public class GradleResolverUtil { } } } + + @Nullable + public static PsiElement findParent(@NotNull PsiElement element, int level) { + PsiElement parent = element; + do { + parent = parent.getParent(); + } + while (parent != null && --level > 0); + return parent; + } + + @Nullable + public static <T extends PsiElement> T findParent(@NotNull PsiElement element, Class<T> clazz) { + PsiElement parent = element; + do { + parent = parent.getParent(); + if (clazz.isInstance(parent)) { + //noinspection unchecked + return (T)parent; + } + } + while (parent != null && !(parent instanceof GroovyFile)); + return null; + } + + public static boolean canBeMethodOf(@Nullable String methodName, @Nullable PsiClass aClass) { + return methodName != null && aClass != null && aClass.findMethodsByName(methodName, true).length != 0; + } + + @Nullable + public static PsiType getTypeOf(@Nullable GrExpression expression) { + PsiType psiType = null; + if (expression != null) { + Integer count = expression.getUserData(TYPE_RESOLVE_IN_PROGRESS_KEY); + if (count == null) count = 0; + if (count < 15) { + expression.putUserData(TYPE_RESOLVE_IN_PROGRESS_KEY, ++count); + psiType = expression.getNominalType(); + expression.putUserData(TYPE_RESOLVE_IN_PROGRESS_KEY, null); + } + } + return psiType; + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleRootContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleRootContributor.java index 4302c04c4afd..61856bc0ba9c 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleRootContributor.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleRootContributor.java @@ -16,7 +16,6 @@ package org.jetbrains.plugins.gradle.service.resolve; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.ResolveState; import com.intellij.psi.scope.PsiScopeProcessor; @@ -69,9 +68,6 @@ public class GradleRootContributor implements GradleMethodContextContributor { } GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); - PsiClass contributorClass = psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_PROJECT, place.getResolveScope()); - if (contributorClass != null) { - contributorClass.processDeclarations(processor, state, null, place); - } + GradleResolverUtil.processDeclarations(psiManager, processor, state, place, GradleCommonClassNames.GRADLE_API_PROJECT); } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleSimpleContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleSimpleContributor.java index 4e0a2b815ff2..791562a61ef2 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleSimpleContributor.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleSimpleContributor.java @@ -15,7 +15,6 @@ */ package org.jetbrains.plugins.gradle.service.resolve; -import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.ResolveState; import com.intellij.psi.scope.PsiScopeProcessor; @@ -47,9 +46,6 @@ public abstract class GradleSimpleContributor implements GradleMethodContextCont return; } GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); - PsiClass contributorClass = psiManager.findClassWithCache(fqName, place.getResolveScope()); - if (contributorClass != null) { - contributorClass.processDeclarations(processor, state, null, place); - } + GradleResolverUtil.processDeclarations(psiManager, processor, state, place, fqName); } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleSourceSetsContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleSourceSetsContributor.java index b6873acfac4d..e94a44d52bf8 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleSourceSetsContributor.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleSourceSetsContributor.java @@ -52,12 +52,18 @@ public class GradleSourceSetsContributor implements GradleMethodContextContribut if (methodCall == null) { return; } + + if (methodCallInfo.size() > 1 && "sourceSets".equals(place.getText()) && place instanceof GrReferenceExpressionImpl) { + GradleResolverUtil + .addImplicitVariable(processor, state, (GrReferenceExpressionImpl)place, GradleCommonClassNames.GRADLE_API_SOURCE_SET_CONTAINER); + } + if (methodCallInfo.size() > 1 && methodCall.equals("project")) { methodCallInfo.remove(methodCallInfo.size() - 1); methodCall = ContainerUtil.getLastItem(methodCallInfo); } - if (methodCallInfo.size() > SOURCE_DIRECTORY_CLOSURE_LEVEL || !StringUtil.startsWith(methodCall, SOURCE_SETS)) { + if (methodCall == null || methodCallInfo.size() > SOURCE_DIRECTORY_CLOSURE_LEVEL || !StringUtil.startsWith(methodCall, SOURCE_SETS)) { return; } @@ -83,7 +89,10 @@ public class GradleSourceSetsContributor implements GradleMethodContextContribut contributorClass = GradleCommonClassNames.GRADLE_API_SOURCE_SET; } else if (methodCallInfo.size() == SOURCE_DIRECTORY_LEVEL) { - configureClosureClazz = GradleCommonClassNames.GRADLE_API_SOURCE_DIRECTORY_SET; + GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); + PsiClass psiClass = psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_SOURCE_SET, place.getResolveScope()); + configureClosureClazz = + GradleResolverUtil.canBeMethodOf(place.getText(), psiClass) ? null : GradleCommonClassNames.GRADLE_API_SOURCE_DIRECTORY_SET; contributorClass = GradleCommonClassNames.GRADLE_API_SOURCE_DIRECTORY_SET; } else if (methodCallInfo.size() == SOURCE_DIRECTORY_CLOSURE_LEVEL) { @@ -91,23 +100,21 @@ public class GradleSourceSetsContributor implements GradleMethodContextContribut } if (configureClosureClazz != null && !isRootRelated) { + final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); GrLightMethodBuilder methodWithClosure = - GradleResolverUtil.createMethodWithClosure(CONFIGURE_CLOSURE_METHOD, place, configureClosureClazz); - processor.execute(methodWithClosure, state); - } - else { - GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); - PsiClass contributorPsiClass = psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_PROJECT, place.getResolveScope()); - if (contributorPsiClass != null) { - contributorPsiClass.processDeclarations(processor, state, null, place); + GradleResolverUtil + .createMethodWithClosure(CONFIGURE_CLOSURE_METHOD, configureClosureClazz, null, place, psiManager); + if (methodWithClosure != null) { + processor.execute(methodWithClosure, state); } } + //else { + // GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); + // GradleResolverUtil.processDeclarations(psiManager, processor, state, place, GradleCommonClassNames.GRADLE_API_PROJECT); + //} if (contributorClass != null) { GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); - PsiClass psiClass = psiManager.findClassWithCache(contributorClass, place.getResolveScope()); - if (psiClass != null) { - psiClass.processDeclarations(processor, state, null, place); - } + GradleResolverUtil.processDeclarations(psiManager, processor, state, place, contributorClass); } } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java index 15d3182fd77c..80f2adb3d469 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java @@ -20,9 +20,7 @@ import com.intellij.psi.*; import com.intellij.psi.impl.source.PsiImmediateClassType; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; @@ -42,18 +40,13 @@ import java.util.List; * @since 9/9/13 */ public class GradleTaskContributor implements GradleMethodContextContributor { + @Override public void process(@NotNull List<String> methodCallInfo, @NotNull PsiScopeProcessor processor, @NotNull ResolveState state, @NotNull PsiElement place) { - if (methodCallInfo.isEmpty()) { - return; - } - final String methodCall = ContainerUtil.getLastItem(methodCallInfo); - if (methodCall == null || !methodCall.equals("task")) { - return; - } + if (methodCallInfo.isEmpty()) return; if (methodCallInfo.size() == 1) { if (place.getParent() instanceof GrShiftExpressionImpl) { @@ -68,18 +61,14 @@ public class GradleTaskContributor implements GradleMethodContextContributor { else { processTaskTypeParameter(processor, state, place); } - GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); - PsiClass psiClass = psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_PROJECT, place.getResolveScope()); - if (psiClass != null) { - psiClass.processDeclarations(processor, state, null, place); - } + + GradleImplicitContributor.processImplicitDeclarations(processor, state, place); } else if (methodCallInfo.size() >= 3) { - GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); - PsiClass psiClass = psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_PROJECT, place.getResolveScope()); - if (psiClass != null) { - psiClass.processDeclarations(processor, state, null, place); - } + processTaskTypeParameter(processor, state, place); + + GradleImplicitContributor.processImplicitDeclarations(processor, state, place); + if (place.getText().equals(GradleSourceSetsContributor.SOURCE_SETS) && StringUtil.startsWith(methodCallInfo.get(0), GradleSourceSetsContributor.SOURCE_SETS + '.')) { GradleResolverUtil.addImplicitVariable(processor, state, place, GradleCommonClassNames.GRADLE_API_SOURCE_SET_CONTAINER); @@ -91,46 +80,37 @@ public class GradleTaskContributor implements GradleMethodContextContributor { @NotNull ResolveState state, @NotNull PsiElement place) { final int taskTypeParameterLevel = 3; - PsiElement psiElement = findParent(place, taskTypeParameterLevel); + PsiElement psiElement = GradleResolverUtil.findParent(place, taskTypeParameterLevel); if (psiElement instanceof GrMethodCallExpression) { GrMethodCallExpression callExpression = (GrMethodCallExpression)psiElement; GrArgumentList argumentList = callExpression.getArgumentList(); - if (argumentList != null) { + if (argumentList != null && argumentList.getAllArguments().length > 0) { for (GroovyPsiElement argument : argumentList.getAllArguments()) { if (argument instanceof GrNamedArgument) { GrNamedArgument namedArgument = (GrNamedArgument)argument; GrExpression grExpression = namedArgument.getExpression(); PsiType psiType = null; if (grExpression != null) { - psiType = grExpression.getType(); + psiType = GradleResolverUtil.getTypeOf(grExpression); } if (psiType instanceof PsiImmediateClassType) { PsiImmediateClassType immediateClassType = (PsiImmediateClassType)psiType; for (PsiType type : immediateClassType.getParameters()) { GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); - PsiClass psiClass = psiManager.findClassWithCache(type.getCanonicalText(), place.getResolveScope()); - if (psiClass != null) { - psiClass.processDeclarations(processor, state, null, place); - } + GradleResolverUtil.processDeclarations(psiManager, processor, state, place, type.getCanonicalText()); } } } } } + else { + GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject()); + GradleResolverUtil.processDeclarations(psiManager, processor, state, place, GradleCommonClassNames.GRADLE_API_TASK); + } } } - @Nullable - private static PsiElement findParent(@NotNull PsiElement element, int level) { - PsiElement parent = element; - do { - parent = parent.getParent(); - } - while (parent != null && --level > 0); - return parent; - } - private static void processTaskAddition(@NotNull String name, @NotNull String handlerClass, @NotNull PsiScopeProcessor processor, diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleUnresolvedReferenceFilter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleUnresolvedReferenceFilter.java new file mode 100644 index 000000000000..3f2084a6083f --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleUnresolvedReferenceFilter.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.gradle.service.resolve; + +import com.intellij.psi.PsiType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.extensions.GroovyUnresolvedHighlightFilter; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; + +import java.util.Set; + +import static com.intellij.util.containers.ContainerUtil.newHashSet; + +/** + * @author Vladislav.Soroka + * @since 9/25/13 + */ +public class GradleUnresolvedReferenceFilter extends GroovyUnresolvedHighlightFilter { + + private final static Set<String> IGNORE_SET = newHashSet( + GradleCommonClassNames.GRADLE_API_TASK, + GradleCommonClassNames.GRADLE_API_SOURCE_SET, + GradleCommonClassNames.GRADLE_API_CONFIGURATION); + + @Override + public boolean isReject(@NotNull GrReferenceExpression expression) { + final PsiType psiType = GradleResolverUtil.getTypeOf(expression); + return psiType != null && IGNORE_SET.contains(psiType.getCanonicalText()); + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/NamedDomainObjectCollectionTypeEnhancer.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/NamedDomainObjectCollectionTypeEnhancer.java new file mode 100644 index 000000000000..0180eb6e482a --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/NamedDomainObjectCollectionTypeEnhancer.java @@ -0,0 +1,88 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.gradle.service.resolve; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiType; +import com.intellij.psi.impl.source.PsiClassReferenceType; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.extensions.GroovyMapContentProvider; +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.impl.GroovyPsiManager; +import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrReferenceTypeEnhancer; + +/** + * @author Vladislav.Soroka + * @since 9/25/13 + */ +public class NamedDomainObjectCollectionTypeEnhancer extends GrReferenceTypeEnhancer { + @Override + public PsiType getReferenceType(GrReferenceExpression ref, @Nullable PsiElement resolved) { + if (resolved != null) return null; + + GrExpression qualifierExpression = ref.getQualifierExpression(); + if (qualifierExpression == null) return null; + + PsiType namedDomainCollectionType = GradleResolverUtil.getTypeOf(qualifierExpression); + + if (!GroovyPsiManager.isInheritorCached(namedDomainCollectionType, GradleCommonClassNames.GRADLE_API_NAMED_DOMAIN_OBJECT_COLLECTION)) { + return null; + } + + PsiElement qResolved; + + if (qualifierExpression instanceof GrReferenceExpression) { + qResolved = ((GrReferenceExpression)qualifierExpression).resolve(); + } + else if (qualifierExpression instanceof GrMethodCall) { + qResolved = ((GrMethodCall)qualifierExpression).resolveMethod(); + } + else { + return null; + } + + String key = ref.getReferenceName(); + if (key == null) return null; + + for (GroovyMapContentProvider provider : GroovyMapContentProvider.EP_NAME.getExtensions()) { + PsiType type = provider.getValueType(qualifierExpression, qResolved, key); + if (type != null) { + return type; + } + } + + if (namedDomainCollectionType instanceof PsiClassReferenceType) { + final PsiClassReferenceType referenceType = (PsiClassReferenceType)namedDomainCollectionType; + final String fqName = referenceType.getCanonicalText(); + if (GradleCommonClassNames.GRADLE_API_SOURCE_SET_CONTAINER.equals(fqName)) { + final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(ref.getProject()); + return psiManager.createTypeByFQClassName(GradleCommonClassNames.GRADLE_API_SOURCE_SET, ref.getResolveScope()); + } + else if (GradleCommonClassNames.GRADLE_API_CONFIGURATION_CONTAINER.equals(fqName)) { + final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(ref.getProject()); + return psiManager.createTypeByFQClassName(GradleCommonClassNames.GRADLE_API_CONFIGURATION, ref.getResolveScope()); + } + else if (GradleCommonClassNames.GRADLE_API_TASK_CONTAINER.equals(fqName)) { + final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(ref.getProject()); + return psiManager.createTypeByFQClassName(GradleCommonClassNames.GRADLE_API_TASK, ref.getResolveScope()); + } + } + + return null; + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/dsl/GradleDslAnnotator.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/dsl/GradleDslAnnotator.java new file mode 100644 index 000000000000..afa46a709f91 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/dsl/GradleDslAnnotator.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.gradle.service.resolve.dsl; + +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.lang.annotation.Annotator; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiType; +import com.intellij.psi.util.InheritanceUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames; +import org.jetbrains.plugins.gradle.service.resolve.GradleResolverUtil; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; +import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; +import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; + +import static org.jetbrains.plugins.gradle.service.resolve.GradleResolverUtil.canBeMethodOf; +import static org.jetbrains.plugins.groovy.highlighter.DefaultHighlighter.MAP_KEY; + +/** + * @author Vladislav.Soroka + * @since 9/25/13 + */ +public class GradleDslAnnotator implements Annotator { + @Override + public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { + if (element instanceof GrReferenceExpression) { + GrReferenceExpression referenceExpression = (GrReferenceExpression)element; + final GrExpression qualifier = ResolveUtil.getSelfOrWithQualifier(referenceExpression); + if (qualifier == null) return; + if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass) return; + + PsiType psiType = GradleResolverUtil.getTypeOf(qualifier); + if (psiType == null) return; + if (InheritanceUtil.isInheritor(psiType, GradleCommonClassNames.GRADLE_API_NAMED_DOMAIN_OBJECT_COLLECTION)) { + final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(element.getProject()); + PsiClass defaultGroovyMethodsClass = + psiManager.findClassWithCache(GroovyCommonClassNames.DEFAULT_GROOVY_METHODS, element.getResolveScope()); + if (canBeMethodOf(referenceExpression.getReferenceName(), defaultGroovyMethodsClass)) return; + + PsiClass containerClass = psiManager.findClassWithCache(psiType.getCanonicalText(), element.getResolveScope()); + if (canBeMethodOf(referenceExpression.getReferenceName(), containerClass)) return; + + PsiElement nameElement = referenceExpression.getReferenceNameElement(); + if (nameElement != null) { + holder.createInfoAnnotation(nameElement, null).setTextAttributes(MAP_KEY); + } + } + } + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExecutionSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExecutionSettings.java index 82cd84cdd682..badb42d771c0 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExecutionSettings.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExecutionSettings.java @@ -54,9 +54,6 @@ public class GradleExecutionSettings extends ExternalSystemExecutionSettings { myGradleHome = gradleHome; myServiceDirectory = serviceDirectory; myDistributionType = distributionType; - if (daemonVmOptions != null && !daemonVmOptions.contains("-Xmx")) { - daemonVmOptions += String.format(" -Xmx%dm", SystemInfo.is32Bit ? 512 : 1024); - } myDaemonVmOptions = daemonVmOptions; setVerboseProcessing(USE_VERBOSE_GRADLE_API_BY_DEFAULT); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyIconProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyIconProvider.java index 60f69c72a9ac..62d133454dec 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyIconProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyIconProvider.java @@ -16,7 +16,6 @@ package org.jetbrains.plugins.groovy; import com.intellij.ide.IconProvider; -import com.intellij.openapi.project.DumbAware; import com.intellij.psi.PsiElement; import icons.JetgroovyIcons; import org.jetbrains.annotations.NotNull; @@ -30,7 +29,7 @@ import javax.swing.*; /** * @author peter */ -public class GroovyIconProvider extends IconProvider implements DumbAware { +public class GroovyIconProvider extends IconProvider { @Nullable public Icon getIcon(@NotNull PsiElement element, int flags) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/DumpGroovyControlFlowAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/DumpGroovyControlFlowAction.java index 1402c4316abd..bcba952255bb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/DumpGroovyControlFlowAction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/DumpGroovyControlFlowAction.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.DumbAware; @@ -39,7 +40,7 @@ import java.util.List; public class DumpGroovyControlFlowAction extends AnAction implements DumbAware { @Override public void actionPerformed(AnActionEvent e) { - final Editor editor = PlatformDataKeys.EDITOR.getData(e.getDataContext()); + final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); if (editor == null) return; final PsiFile psiFile = HandlerUtils.getPsiFile(editor, e.getDataContext()); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/DumpGroovyStubsAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/DumpGroovyStubsAction.java index b26ceb8e28ed..0ec786861e2f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/DumpGroovyStubsAction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/DumpGroovyStubsAction.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.DumbAware; @@ -31,7 +32,7 @@ import org.jetbrains.plugins.groovy.refactoring.convertToJava.GroovyToJavaGenera public class DumpGroovyStubsAction extends AnAction implements DumbAware { @Override public void update(AnActionEvent e) { - Editor editor = PlatformDataKeys.EDITOR.getData(e.getDataContext()); + Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); if (editor != null) { PsiFile psiFile = HandlerUtils.getPsiFile(editor, e.getDataContext()); if (psiFile instanceof GroovyFile) { @@ -44,7 +45,7 @@ public class DumpGroovyStubsAction extends AnAction implements DumbAware { @Override public void actionPerformed(AnActionEvent e) { - final Editor editor = PlatformDataKeys.EDITOR.getData(e.getDataContext()); + final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); if (editor == null) return; final PsiFile psiFile = HandlerUtils.getPsiFile(editor, e.getDataContext()); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/GrGetPsiTypeAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/GrGetPsiTypeAction.java index bcc284c5d90b..e40066cb53bb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/GrGetPsiTypeAction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/GrGetPsiTypeAction.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.DumbAware; @@ -47,7 +48,7 @@ import java.util.List; public class GrGetPsiTypeAction extends AnAction implements DumbAware { @Override public void actionPerformed(AnActionEvent e) { - final Editor editor = PlatformDataKeys.EDITOR.getData(e.getDataContext()); + final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); if (editor == null) return; final PsiFile psiFile = HandlerUtils.getPsiFile(editor, e.getDataContext()); @@ -107,7 +108,7 @@ public class GrGetPsiTypeAction extends AnAction implements DumbAware { @Override public void update(AnActionEvent e) { - Editor editor = PlatformDataKeys.EDITOR.getData(e.getDataContext()); + Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); if (editor != null) { PsiFile psiFile = HandlerUtils.getPsiFile(editor, e.getDataContext()); if (psiFile instanceof GroovyFile) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/NewGroovyClassAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/NewGroovyClassAction.java index b23abd29eb32..8f054d2ced30 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/NewGroovyClassAction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/NewGroovyClassAction.java @@ -88,7 +88,7 @@ public class NewGroovyClassAction extends JavaCreateTemplateInPackageAction<GrTy IdeView view = LangDataKeys.IDE_VIEW.getData(e.getDataContext()); if (view == null) return; - Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); if (project == null) return; ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java index 06a8feb92c9c..002c2d62f2ae 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java @@ -654,10 +654,10 @@ public class DynamicToolWindowWrapper { @Nullable public Object getData(@NonNls String dataId) { - if (LangDataKeys.PSI_ELEMENT.is(dataId)) { + if (CommonDataKeys.PSI_ELEMENT.is(dataId)) { return getSelectedElement(); } - else if (LangDataKeys.PSI_FILE.is(dataId)) { + else if (CommonDataKeys.PSI_FILE.is(dataId)) { final PsiElement element = getSelectedElement(); if (element == null) return null; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyAwareModuleBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyAwareModuleBuilder.java index 427708680b9d..8cece0833c05 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyAwareModuleBuilder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyAwareModuleBuilder.java @@ -17,10 +17,12 @@ package org.jetbrains.plugins.groovy.config; import com.intellij.ide.util.projectWizard.JavaModuleBuilder; import com.intellij.ide.util.projectWizard.ModuleWizardStep; +import com.intellij.ide.util.projectWizard.SettingsStep; import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import icons.JetgroovyIcons; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.mvc.GroovySdkForNewModuleWizardStep; import org.jetbrains.plugins.groovy.mvc.MvcFramework; @@ -37,7 +39,7 @@ public class GroovyAwareModuleBuilder extends JavaModuleBuilder { @SuppressWarnings("UnusedDeclaration") public GroovyAwareModuleBuilder() { - this("groovy", "Groovy Module", "Simple module with attached Groovy library", null); + this("groovy", "Groovy", "Simple module with attached Groovy library", null); } protected GroovyAwareModuleBuilder(String builderId, String presentableName, String description, Icon bigIcon) { @@ -49,15 +51,15 @@ public class GroovyAwareModuleBuilder extends JavaModuleBuilder { @Override public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) { - return new ModuleWizardStep[]{new GroovySdkForNewModuleWizardStep(this, wizardContext, getFramework())}; + return new ModuleWizardStep[]{new GroovySdkForNewModuleWizardStep(this, wizardContext, getFramework(), null)}; + } + + @Nullable + @Override + public ModuleWizardStep modifySettingsStep(@NotNull SettingsStep settingsStep) { + return new GroovySdkForNewModuleWizardStep(this, settingsStep.getContext(), getFramework(), settingsStep); } - //@Nullable - //@Override - //public ModuleWizardStep modifySettingsStep(SettingsStep settingsStep) { - // return new GroovySdkForNewModuleWizardStep(this, settingsStep.getContext(), getFramework()); - //} - // @Override public String getBuilderId() { return myBuilderId; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/actions/GenerateGroovyDocAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/actions/GenerateGroovyDocAction.java index 6c74c46fd77f..8c8e4e7094f7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/actions/GenerateGroovyDocAction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/actions/GenerateGroovyDocAction.java @@ -39,7 +39,7 @@ public final class GenerateGroovyDocAction extends AnAction implements DumbAware public void actionPerformed(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); final Module module = LangDataKeys.MODULE.getData(dataContext); if (module == null) return; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/actions/GroovyDocAddPackageAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/actions/GroovyDocAddPackageAction.java index be83d629ad4d..9b73e604513b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/actions/GroovyDocAddPackageAction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/actions/GroovyDocAddPackageAction.java @@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.doc.actions; import com.intellij.ide.util.PackageChooserDialog; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; @@ -41,7 +42,7 @@ public class GroovyDocAddPackageAction extends AnAction implements DumbAware { } public void actionPerformed(final AnActionEvent e) { - final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); PackageChooserDialog chooser = new PackageChooserDialog("Choose packages", project); chooser.show(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/GroovyLiteralCopyPasteProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/GroovyLiteralCopyPasteProcessor.java index fd85bc206830..5e0006e1e573 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/GroovyLiteralCopyPasteProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/GroovyLiteralCopyPasteProcessor.java @@ -53,7 +53,10 @@ public class GroovyLiteralCopyPasteProcessor extends StringLiteralCopyPasteProce @Override protected boolean isStringLiteral(@NotNull PsiElement token) { ASTNode node = token.getNode(); - return node != null && (TokenSets.STRING_LITERALS.contains(node.getElementType()) || node.getElementType() == GroovyElementTypes.GSTRING_INJECTION); + return node != null && + (TokenSets.STRING_LITERALS.contains(node.getElementType()) || + node.getElementType() == GroovyElementTypes.GSTRING_INJECTION || + node.getElementType() == GroovyElementTypes.GSTRING_CONTENT); } @Nullable @@ -74,11 +77,7 @@ public class GroovyLiteralCopyPasteProcessor extends StringLiteralCopyPasteProce elementType = elementAtSelectionStart.getNode().getElementType(); } - - - if (!isStringLiteral(elementAtSelectionStart) && - !isCharLiteral(elementAtSelectionStart) && - !(elementType == GroovyElementTypes.GSTRING_INJECTION)) { + if (!isStringLiteral(elementAtSelectionStart)) { return null; } @@ -103,9 +102,14 @@ public class GroovyLiteralCopyPasteProcessor extends StringLiteralCopyPasteProce selectionStart++; selectionEnd--; } - if (selectionStart <= textRange.getStartOffset() || selectionEnd >= textRange.getEndOffset()) { + if (textRange.getLength() > 0 && (selectionStart <= textRange.getStartOffset() || selectionEnd >= textRange.getEndOffset())) { return null; } + + if (elementType == GroovyElementTypes.GSTRING_CONTENT) { + elementAtSelectionStart = elementAtSelectionStart.getFirstChild(); + } + return elementAtSelectionStart; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/actions/GroovyEnterHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/actions/GroovyEnterHandler.java index a1e75f1abb14..c31b59b0a137 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/actions/GroovyEnterHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/actions/GroovyEnterHandler.java @@ -19,6 +19,7 @@ package org.jetbrains.plugins.groovy.editor.actions; import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegateAdapter; import com.intellij.lang.ASTNode; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.CaretModel; @@ -208,7 +209,7 @@ public class GroovyEnterHandler extends EnterHandlerDelegateAdapter { DataContext dataContext, EditorActionHandler originalHandler, PsiFile file) { - Project project = PlatformDataKeys.PROJECT.getData(dataContext); + Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null) return false; GroovyCodeStyleSettings codeStyleSettings = @@ -273,7 +274,7 @@ public class GroovyEnterHandler extends EnterHandlerDelegateAdapter { } private static boolean handleInString(Editor editor, int caretOffset, DataContext dataContext, EditorActionHandler originalHandler) { - Project project = PlatformDataKeys.PROJECT.getData(dataContext); + Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null) return false; final VirtualFile vfile = FileDocumentManager.getInstance().getFile(editor.getDocument()); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java index c105fc6c3e0a..ea559fafcaa2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java @@ -673,8 +673,11 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { @Override public void visitAnnotationMethod(GrAnnotationMethod annotationMethod) { - if (myType2 == mLPAREN) { - createSpaceInCode(mySettings.SPACE_BEFORE_METHOD_PARENTHESES); + if (myType2 == DEFAULT_ANNOTATION_VALUE) { + createSpaceInCode(true); + } + else { + super.visitAnnotationMethod(annotationMethod); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppReferenceContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppReferenceContributor.java index ef9072bd97c2..c110707a4fa8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppReferenceContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppReferenceContributor.java @@ -92,7 +92,7 @@ public class GppReferenceContributor extends PsiReferenceContributor { if (setter != null) { applicable.add(new PsiElementResolveResult(setter)); } else { - final PsiField field = PropertyUtil.findPropertyField(psiClass.getProject(), psiClass, memberName, false); + final PsiField field = PropertyUtil.findPropertyField(psiClass, memberName, false); if (field != null) { applicable.add(new PsiElementResolveResult(field)); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonSourceInspector.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonSourceInspector.java index ac81fef51829..2db93f05467a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonSourceInspector.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonSourceInspector.java @@ -16,6 +16,7 @@ package org.jetbrains.plugins.groovy.griffon; import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; @@ -42,7 +43,8 @@ public class GriffonSourceInspector { @Override public Result<List<GriffonSource>> compute() { List<GriffonSource> sources = new ArrayList<GriffonSource>(); - List<VirtualFile> dependencies = new ArrayList<VirtualFile>(); + List<Object> dependencies = ContainerUtil.newArrayList(); + dependencies.add(ProjectRootManager.getInstance(module.getProject())); ContainerUtil.addIfNotNull(dependencies, GriffonFramework.getInstance().getApplicationPropertiesFile(module)); String applicationName = GriffonFramework.getInstance().getApplicationName(module); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveUnnecessaryBracesInGStringIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveUnnecessaryBracesInGStringIntention.java index efdec757750b..4f4baf546522 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveUnnecessaryBracesInGStringIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveUnnecessaryBracesInGStringIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,30 +35,24 @@ public class RemoveUnnecessaryBracesInGStringIntention extends Intention { @NotNull @Override protected PsiElementPredicate getElementPredicate() { - return new MyPredicate(); + return new PsiElementPredicate() { + public boolean satisfiedBy(PsiElement element) { + if (!(element instanceof GrString)) return false; + + if (ErrorUtil.containsError(element)) return false; + + for (GrStringInjection child : ((GrString)element).getInjections()) { + if (GrStringUtil.checkGStringInjectionForUnnecessaryBraces(child)) return true; + } + return false; + } + }; } @Override protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { GrStringUtil.removeUnnecessaryBracesInGString((GrString)element); } - - public static class MyPredicate implements PsiElementPredicate { - public boolean satisfiedBy(PsiElement element) { - return isIntentionAvailable(element); - } - - public static boolean isIntentionAvailable(PsiElement element) { - if (!(element instanceof GrString)) return false; - - if (ErrorUtil.containsError(element)) return false; - - for (GrStringInjection child : ((GrString)element).getInjections()) { - if (GrStringUtil.checkGStringInjectionForUnnecessaryBraces(child)) return true; - } - return false; - } - } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/RemoveUnnecessarySemicolonsIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/RemoveUnnecessarySemicolonsIntention.java index 36f6deab66f6..be1a387d5954 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/RemoveUnnecessarySemicolonsIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/RemoveUnnecessarySemicolonsIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,12 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrTraditionalForClause; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.*; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMembersDeclaration; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; @@ -103,7 +108,7 @@ public class RemoveUnnecessarySemicolonsIntention implements IntentionAction { final int end = selectionModel.getSelectionEnd(); final TextRange range = new TextRange(start, end); - final ArrayList<PsiElement> colons = new ArrayList<PsiElement>(); + final ArrayList<PsiElement> semicolons = new ArrayList<PsiElement>(); file.accept(new PsiRecursiveElementVisitor() { @Override public void visitElement(PsiElement element) { @@ -111,7 +116,7 @@ public class RemoveUnnecessarySemicolonsIntention implements IntentionAction { final IElementType elementType = element.getNode().getElementType(); if (elementType == GroovyTokenTypes.mSEMI) { - colons.add(element); + semicolons.add(element); } else { super.visitElement(element); @@ -120,9 +125,8 @@ public class RemoveUnnecessarySemicolonsIntention implements IntentionAction { }); boolean removed = false; - for (PsiElement colon : colons) { - final boolean b = checkAndRemove(project, colon, document); - removed = removed || b; + for (PsiElement semicolon : semicolons) { + removed = checkAndRemove(project, semicolon, document) || removed; } if (!removed) { @@ -147,7 +151,7 @@ public class RemoveUnnecessarySemicolonsIntention implements IntentionAction { private static boolean checkAndRemove(Project project, @Nullable PsiElement element, Document document) { if (element != null && element.getNode().getElementType() == GroovyTokenTypes.mSEMI) { - if (isColonUnnecessary(element, document.getText(), project)) { + if (isSemiColonUnnecessary(element, document.getText(), project)) { element.delete(); return true; } @@ -155,36 +159,92 @@ public class RemoveUnnecessarySemicolonsIntention implements IntentionAction { return false; } - private static boolean isColonUnnecessary(PsiElement colon, String text, Project project) { - final GrStatement prev = getPreviousStatement(colon); - final GrStatement next = getNextStatement(colon); + private static boolean isSemiColonUnnecessary(PsiElement semicolon, String text, Project project) { + PsiElement parent = semicolon.getParent(); + if (parent instanceof GrTraditionalForClause) { + return false; + } + else if (parent instanceof GrTypeDefinitionBody) { + return isSemiColonUnnecessaryInClassBody(semicolon, text, project); + } + else { + return isSemiColonUnnecessaryInCodeBlock(semicolon, text, project); + } + } + + private static boolean isSemiColonUnnecessaryInCodeBlock(PsiElement semicolon, String text, Project project) { + final GrStatement prev = getPreviousStatement(semicolon, GrStatement.class); + final GrStatement next = getNextStatement(semicolon, GrStatement.class); if (prev == null || next == null) return true; final int startOffset = prev.getTextRange().getStartOffset(); final int endOffset = next.getTextRange().getEndOffset(); - final int offset = colon.getTextRange().getStartOffset(); - final String statementWithoutColon = text.substring(startOffset, offset) + text.substring(offset + 1, endOffset); - final GroovyFile file = GroovyPsiElementFactory.getInstance(project).createGroovyFile(statementWithoutColon, false, null); + final int offset = semicolon.getTextRange().getStartOffset(); + final String statementWithoutSemicolon = text.substring(startOffset, offset) + text.substring(offset + 1, endOffset); + final GroovyFile file = GroovyPsiElementFactory.getInstance(project).createGroovyFile(statementWithoutSemicolon, false, null); final GrStatement[] statements = file.getStatements(); if (statements.length != 2) return false; - return GroovyRefactoringUtil.checkPsiElementsAreEqual(prev, statements[0]) && - GroovyRefactoringUtil.checkPsiElementsAreEqual(next, statements[1]); + return checkStatementsAreEqual(prev, statements[0]) && + checkStatementsAreEqual(next, statements[1]); + } + + private static boolean isSemiColonUnnecessaryInClassBody(PsiElement semicolon, String text, Project project) { + final GrMembersDeclaration prev = getPreviousStatement(semicolon, GrMembersDeclaration.class); + final GrMembersDeclaration next = getNextStatement(semicolon, GrMembersDeclaration.class); + + if (prev == null || next == null) return true; + + + final int startOffset = prev.getTextRange().getStartOffset(); + final int endOffset = next.getTextRange().getEndOffset(); + + final int offset = semicolon.getTextRange().getStartOffset(); + final String declarationsWithoutSemicolon = text.substring(startOffset, offset) + text.substring(offset + 1, endOffset); + + PsiElement parent = semicolon.getParent().getParent(); + + String prefix = parent instanceof GrClassDefinition ? "class": + parent instanceof GrEnumTypeDefinition ? "enum": + parent instanceof GrInterfaceDefinition ? "interface": + parent instanceof GrAnnotationTypeDefinition ? "@interface": + parent instanceof GrAnonymousClassDefinition ? "class": + "class"; + final GroovyFile file = GroovyPsiElementFactory.getInstance(project).createGroovyFile(prefix + " Name {\n" + declarationsWithoutSemicolon + "\n}", false, null); + GrTypeDefinition[] typeDefs = file.getTypeDefinitions(); + if (typeDefs.length != 1) return false; + + GrTypeDefinition clazz = typeDefs[0]; + GrMembersDeclaration[] declarations = clazz.getMemberDeclarations(); + if (declarations.length != 2) return false; + + return checkStatementsAreEqual(prev, declarations[0]) && + checkStatementsAreEqual(next, declarations[1]); + } + + + private static <T extends PsiElement> boolean checkStatementsAreEqual(T before, T after) { + if (before instanceof GrConstructorInvocation) { + return after instanceof GrMethodCall && before.getText().equals(after.getText()); + } + else { + return GroovyRefactoringUtil.checkPsiElementsAreEqual(before, after); + } } @Nullable - private static GrStatement getPreviousStatement(PsiElement colon) { - final PsiElement prev = PsiUtil.skipWhitespacesAndComments(colon.getPrevSibling(), false); - if (prev instanceof GrStatement) return (GrStatement)prev; + private static <T extends PsiElement> T getPreviousStatement(PsiElement semicolon, Class<T> instanceOf) { + final PsiElement prev = PsiUtil.skipWhitespacesAndComments(semicolon.getPrevSibling(), false); + if (instanceOf.isInstance(prev)) return (T)prev; return null; } @Nullable - private static GrStatement getNextStatement(PsiElement colon) { - final PsiElement next = PsiUtil.skipWhitespacesAndComments(colon.getNextSibling(), true); - if (next instanceof GrStatement) return (GrStatement)next; + private static <T extends PsiElement> T getNextStatement(PsiElement semicolon, Class<T> instaceOf) { + final PsiElement next = PsiUtil.skipWhitespacesAndComments(semicolon.getNextSibling(), true); + if (instaceOf.isInstance(next)) return (T)next; return null; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/ClosureCompleter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/ClosureCompleter.java index b66d441ebc63..64e2c6675990 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/ClosureCompleter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/ClosureCompleter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,15 +47,13 @@ import java.util.List; * @author Max Medvedev */ public abstract class ClosureCompleter { - private static ExtensionPointName<ClosureCompleter> EP_NAME = ExtensionPointName.create("org.intellij.groovy.closureCompleter"); + private static final ExtensionPointName<ClosureCompleter> EP_NAME = ExtensionPointName.create("org.intellij.groovy.closureCompleter"); @Nullable protected abstract List<ClosureParameterInfo> getParameterInfos(InsertionContext context, PsiMethod method, PsiSubstitutor substitutor, - Document document, - int offset, - PsiElement parent); + PsiElement place); public static boolean runClosureCompletion(InsertionContext context, PsiMethod method, @@ -64,7 +62,7 @@ public abstract class ClosureCompleter { int offset, PsiElement parent) { for (ClosureCompleter completer : EP_NAME.getExtensions()) { - final List<ClosureParameterInfo> parameterInfos = completer.getParameterInfos(context, method, substitutor, document, offset, parent); + final List<ClosureParameterInfo> parameterInfos = completer.getParameterInfos(context, method, substitutor, parent); if (parameterInfos != null) { runClosureTemplate(context, document, offset, substitutor, method, parameterInfos); return true; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/EachWithIndexClosureCompleter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/EachWithIndexClosureCompleter.java index 54962a1e33c7..a6876211f06d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/EachWithIndexClosureCompleter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/EachWithIndexClosureCompleter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.jetbrains.plugins.groovy.lang.completion; import com.intellij.codeInsight.completion.InsertionContext; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.InheritanceUtil; @@ -42,9 +41,7 @@ public class EachWithIndexClosureCompleter extends ClosureCompleter { protected List<ClosureParameterInfo> getParameterInfos(InsertionContext context, PsiMethod method, PsiSubstitutor substitutor, - Document document, - int offset, - PsiElement parent) { + PsiElement place) { final String name = method.getName(); if (!"eachWithIndex".equals(name)) return null; @@ -63,7 +60,7 @@ public class EachWithIndexClosureCompleter extends ClosureCompleter { final PsiType type = parameters[0].getType(); final PsiType collection = substitutor.substitute(type); - final PsiType iterable = getIteratedType(parent, collection); + final PsiType iterable = getIteratedType(place, collection); if (iterable != null) { return Arrays.asList( new ClosureParameterInfo(iterable.getCanonicalText(), "entry"), @@ -76,7 +73,7 @@ public class EachWithIndexClosureCompleter extends ClosureCompleter { final Project project = context.getProject(); - final PsiClass entry = JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_UTIL_MAP_ENTRY, parent.getResolveScope()); + final PsiClass entry = JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_UTIL_MAP_ENTRY, place.getResolveScope()); if (entry == null) return null; final PsiClassType entryType = JavaPsiFacade.getElementFactory(project).createType(entry, typeParams); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GdslClosureCompleter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GdslClosureCompleter.java index 333f91a7d552..a7f6e342cd60 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GdslClosureCompleter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GdslClosureCompleter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.jetbrains.plugins.groovy.lang.completion; import com.intellij.codeInsight.completion.InsertionContext; -import com.intellij.openapi.editor.Document; import com.intellij.psi.*; import com.intellij.psi.scope.BaseScopeProcessor; import org.jetbrains.annotations.NotNull; @@ -42,8 +41,6 @@ public class GdslClosureCompleter extends ClosureCompleter { protected List<ClosureParameterInfo> getParameterInfos(InsertionContext context, PsiMethod method, PsiSubstitutor substitutor, - Document document, - int offset, PsiElement place) { final ArrayList<ClosureDescriptor> descriptors = new ArrayList<ClosureDescriptor>(); GrReferenceExpression ref = (GrReferenceExpression)place; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index de8dba803249..5610d74ac60e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -71,7 +71,6 @@ import org.jetbrains.plugins.groovy.refactoring.DefaultGroovyVariableNameValidat import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil; import org.jetbrains.plugins.groovy.refactoring.inline.InlineMethodConflictSolver; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -429,10 +428,9 @@ public class GroovyCompletionContributor extends CompletionContributor { final PsiElement qualifier = reference.getQualifier(); final PsiType qualifierType = qualifier instanceof GrExpression ? ((GrExpression)qualifier).getType() : null; - final Set<String> unresolvedProps; if (reference instanceof GrReferenceExpression && (qualifier instanceof GrExpression || qualifier == null)) { - unresolvedProps = CompleteReferenceExpression.getVariantsWithSameQualifier(matcher, (GrExpression)qualifier, (GrReferenceExpression)reference); - for (String string : unresolvedProps) { + for (String string : CompleteReferenceExpression.getVariantsWithSameQualifier(matcher, (GrExpression)qualifier, + (GrReferenceExpression)reference)) { consumer.consume(LookupElementBuilder.create(string).withItemTextUnderlined(true)); } if (parameters.getInvocationCount() < 2 && qualifier != null && qualifierType == null && @@ -443,9 +441,6 @@ public class GroovyCompletionContributor extends CompletionContributor { return EmptyRunnable.INSTANCE; } } - else { - unresolvedProps = Collections.emptySet(); - } final List<LookupElement> zeroPriority = newArrayList(); reference.processVariants(matcher, parameters, new Consumer<LookupElement>() { @@ -667,7 +662,7 @@ public class GroovyCompletionContributor extends CompletionContributor { } } - private String getIdentifier(CompletionInitializationContext context) { + private static String getIdentifier(CompletionInitializationContext context) { if (context.getCompletionType() == CompletionType.BASIC && context.getFile() instanceof GroovyFile) { PsiElement position = context.getFile().findElementAt(context.getStartOffset()); if (position != null && diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocCommentUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocCommentUtil.java index 4f974b364907..a470ed7a08b0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocCommentUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocCommentUtil.java @@ -93,9 +93,9 @@ public abstract class GrDocCommentUtil { PsiElement parent = owner.getParent(); ASTNode node = owner.getNode(); - parent.getNode().addLeaf(GroovyTokenTypes.mNLS, "\n", node); + parent.getNode().addLeaf(GroovyTokenTypes.mNLS, "\n ", node); - PsiElement added = parent.addBefore(comment, node.getPsi()); + PsiElement added = parent.addBefore(comment, owner); assert added instanceof GrDocComment; return (GrDocComment)added; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/CompoundStringExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/CompoundStringExpression.java index fcb7080a7ce3..e9f72ad055b4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/CompoundStringExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/CompoundStringExpression.java @@ -19,6 +19,7 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions. import com.intellij.lang.PsiBuilder; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType; @@ -33,97 +34,152 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; */ public class CompoundStringExpression implements GroovyElementTypes { private static final Logger LOG = Logger.getInstance(CompoundStringExpression.class); + private final PsiBuilder myBuilder; + private final GroovyParser myParser; + private final boolean myForRefExpr; + private final IElementType myBegin; + private final IElementType myContent; + private final IElementType myEnd; + private final IElementType mySimpleLiteral; + private final GroovyElementType myCompoundLiteral; + private final String myMessage; - /** - * Groovy lexer does not smart enough to understand whether a regex contents injections or not. So the parser should do this job. - * We create additional marker2 for the case of absence of injections. In this case resulting tree is as follows: - * - * Regex - * mRegexLiteral (mDollarSlashRegexLiteral) - * mRegexBegin (........................) - * mRegexContent (........................) - * mRegexEnd (........................) - * - * This tree emulates tree of simple GrLiteralImpl structure so we can use regexes where simple strings are expected. - * - * @return true if there are any injections - */ - public static boolean parse(PsiBuilder builder, - GroovyParser parser, - boolean forRefExpr, - IElementType begin, - IElementType content, - IElementType end, - @Nullable IElementType literal, - GroovyElementType compoundLiteral, String message) { - PsiBuilder.Marker marker = builder.mark(); - final PsiBuilder.Marker marker2 = builder.mark(); - LOG.assertTrue(ParserUtils.getToken(builder, begin)); - - if (builder.getTokenType() == content) { - final PsiBuilder.Marker contentMarker = builder.mark(); - builder.advanceLexer(); - if (builder.getTokenType() == mDOLLAR || literal == null) { + private CompoundStringExpression(PsiBuilder builder, + GroovyParser parser, + boolean forRefExpr, + IElementType begin, + IElementType content, + IElementType end, + IElementType literal, + GroovyElementType compoundLiteral, + String message) { + + myBuilder = builder; + myParser = parser; + myForRefExpr = forRefExpr; + myBegin = begin; + myContent = content; + myEnd = end; + mySimpleLiteral = literal; + myCompoundLiteral = compoundLiteral; + myMessage = message; + } + + private boolean parse() { + PsiBuilder.Marker marker = myBuilder.mark(); + final PsiBuilder.Marker marker2 = myBuilder.mark(); + LOG.assertTrue(ParserUtils.getToken(myBuilder, myBegin)); + + + if (mySimpleLiteral != null && myBuilder.getTokenType() == myEnd) { + myBuilder.advanceLexer(); + finishSimpleLiteral(marker, marker2); + return true; + } + + if (myBuilder.getTokenType() == myContent) { + final PsiBuilder.Marker contentMarker = myBuilder.mark(); + myBuilder.advanceLexer(); + if (myBuilder.getTokenType() == mDOLLAR || mySimpleLiteral == null) { contentMarker.done(GSTRING_CONTENT); } else { contentMarker.drop(); } } + else { + processContent(); + } - boolean inj = builder.getTokenType() == mDOLLAR; - while (builder.getTokenType() == mDOLLAR || builder.getTokenType() == content) { - if (builder.getTokenType() == mDOLLAR) { - parseInjection(builder, parser); - } - else { - ParserUtils.eatElement(builder, GSTRING_CONTENT); - } + boolean hasInjection = myBuilder.getTokenType() == mDOLLAR; + while (myBuilder.getTokenType() == mDOLLAR) { + parseInjection(); + processContent(); } - if (!ParserUtils.getToken(builder, end)) { - builder.error(message); + if (!ParserUtils.getToken(myBuilder, myEnd)) { + myBuilder.error(myMessage); } - if (inj || literal == null) { + if (hasInjection || mySimpleLiteral == null) { marker2.drop(); - marker.done(compoundLiteral); + marker.done(myCompoundLiteral); } else { - marker2.done(literal); - if (forRefExpr) { - marker.drop(); - } - else { - marker.done(LITERAL); - } + finishSimpleLiteral(marker, marker2); + } + return hasInjection; + } + + private void processContent() { + PsiBuilder.Marker marker = myBuilder.mark(); + if (myBuilder.getTokenType() == myContent) { + myBuilder.advanceLexer(); + } + else { + myBuilder.mark().done(myContent); + } + marker.done(GSTRING_CONTENT); + } + + private void finishSimpleLiteral(PsiBuilder.Marker marker, PsiBuilder.Marker marker2) { + marker2.done(mySimpleLiteral); + if (myForRefExpr) { + marker.drop(); + } + else { + marker.done(LITERAL); } - return inj; } /** * Parses heredoc's content in GString * - * @param builder given builder * @return nothing */ - private static boolean parseInjection(PsiBuilder builder, GroovyParser parser) { - if (builder.getTokenType() != mDOLLAR) return false; + private boolean parseInjection() { + if (myBuilder.getTokenType() != mDOLLAR) return false; - final PsiBuilder.Marker injection = builder.mark(); - ParserUtils.getToken(builder, mDOLLAR); + final PsiBuilder.Marker injection = myBuilder.mark(); + ParserUtils.getToken(myBuilder, mDOLLAR); - if (mIDENT.equals(builder.getTokenType())) { - PathExpression.parse(builder, parser); + if (mIDENT.equals(myBuilder.getTokenType())) { + PathExpression.parse(myBuilder, myParser); } - else if (mLCURLY.equals(builder.getTokenType())) { - OpenOrClosableBlock.parseClosableBlock(builder, parser); + else if (mLCURLY.equals(myBuilder.getTokenType())) { + OpenOrClosableBlock.parseClosableBlock(myBuilder, myParser); } else { - ParserUtils.wrapError(builder, GroovyBundle.message("identifier.or.block.expected")); + ParserUtils.wrapError(myBuilder, GroovyBundle.message("identifier.or.block.expected")); } injection.done(GSTRING_INJECTION); return true; } + + /** + * Groovy lexer does not smart enough to understand whether a regex contents injections or not. So the parser should do this job. + * We create additional marker2 for the case of absence of injections. In this case resulting tree is as follows: + * + * Regex + * mRegexLiteral (mDollarSlashRegexLiteral) + * mRegexBegin (........................) + * mRegexContent (........................) + * mRegexEnd (........................) + * + * This tree emulates tree of simple GrLiteralImpl structure so we can use regexes where simple strings are expected. + * + * @return true if there are any injections + */ + public static boolean parse(@NotNull PsiBuilder builder, + @NotNull GroovyParser parser, + boolean forRefExpr, + @NotNull IElementType begin, + @NotNull IElementType content, + @NotNull IElementType end, + @Nullable IElementType literal, + @NotNull GroovyElementType compoundLiteral, + @NotNull String message) { + return new CompoundStringExpression(builder, parser, forRefExpr, begin, content, end, literal, compoundLiteral, message).parse(); + } }
\ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java index ab759819ad8f..b59c3ce7fd5b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java @@ -78,7 +78,8 @@ import static org.jetbrains.plugins.groovy.editor.GroovyImportHelper.processImpl */ public class GroovyFileImpl extends GroovyFileBaseImpl implements GroovyFile { private static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl"); - private static final Object lock = new Object(); + + private static final String SYNTHETIC_PARAMETER_NAME = "args"; private static final CachedValueProvider<ConcurrentMap<String, GrBindingVariable>> BINDING_PROVIDER = new CachedValueProvider<ConcurrentMap<String, GrBindingVariable>>() { @Nullable @@ -89,10 +90,11 @@ public class GroovyFileImpl extends GroovyFileBaseImpl implements GroovyFile { } }; + private final Object lock = new Object(); + private volatile Boolean myScript; - private GroovyScriptClass myScriptClass; - private static final String SYNTHETIC_PARAMETER_NAME = "args"; - private GrParameter mySyntheticArgsParameter = null; + private volatile GroovyScriptClass myScriptClass; + private volatile GrParameter mySyntheticArgsParameter = null; private PsiElement myContext; public GroovyFileImpl(FileViewProvider viewProvider) { @@ -382,26 +384,37 @@ public class GroovyFileImpl extends GroovyFileBaseImpl implements GroovyFile { } if (myScript == null) { - final GrTopStatement[] topStatements = findChildrenByClass(GrTopStatement.class); - boolean hasClassDefinitions = false; - boolean hasTopStatements = false; - for (GrTopStatement st : topStatements) { - if (st instanceof GrTypeDefinition) { - hasClassDefinitions = true; - } - else if (!(st instanceof GrImportStatement || st instanceof GrPackageDefinition)) { - hasTopStatements = true; - break; + synchronized (lock) { + boolean isScript = checkIsScript(); + if (myScript == null) { + myScript = isScript; } } - myScript = hasTopStatements || !hasClassDefinitions; } return myScript; } + private boolean checkIsScript() { + final GrTopStatement[] topStatements = findChildrenByClass(GrTopStatement.class); + boolean hasClassDefinitions = false; + boolean hasTopStatements = false; + for (GrTopStatement st : topStatements) { + if (st instanceof GrTypeDefinition) { + hasClassDefinitions = true; + } + else if (!(st instanceof GrImportStatement || st instanceof GrPackageDefinition)) { + hasTopStatements = true; + break; + } + } + return hasTopStatements || !hasClassDefinitions; + } + @Override public void subtreeChanged() { - myScript = null; + synchronized (lock) { + myScript = null; + } super.subtreeChanged(); } @@ -500,9 +513,8 @@ public class GroovyFileImpl extends GroovyFileBaseImpl implements GroovyFile { public void clearCaches() { super.clearCaches(); -// myScriptClass = null; -// myScriptClassInitialized = false; synchronized (lock) { + myScriptClass = null; mySyntheticArgsParameter = null; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java index 3133b1cc2b11..904d130301b0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java @@ -66,6 +66,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod; @@ -79,6 +80,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.arithme import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.literals.GrLiteralImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrSyntheticCodeBlock; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrSyntheticExpression; +import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrSyntheticReferenceList; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrSyntheticTypeElement; import org.jetbrains.plugins.groovy.lang.psi.util.GdkMethodUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil; @@ -100,6 +102,7 @@ public class PsiImplUtil { public static final Key<SoftReference<PsiCodeBlock>> PSI_CODE_BLOCK = Key.create("Psi_code_block"); public static final Key<SoftReference<PsiTypeElement>> PSI_TYPE_ELEMENT = Key.create("psi.type.element"); public static final Key<SoftReference<PsiExpression>> PSI_EXPRESSION = Key.create("psi.expression"); + private static final Key<SoftReference<PsiReferenceList>> PSI_REFERENCE_LIST = Key.create("psi.reference.list"); private PsiImplUtil() { } @@ -606,6 +609,17 @@ public class PsiImplUtil { return newExpr; } + public static PsiReferenceList getOrCreatePsiReferenceList(GrReferenceList list, PsiReferenceList.Role role) { + if (list == null) return null; + + final SoftReference<PsiReferenceList> ref = list.getUserData(PSI_REFERENCE_LIST); + final PsiReferenceList element = ref == null ? null : ref.get(); + if (element != null) return element; + final GrSyntheticReferenceList newList = new GrSyntheticReferenceList(list, role); + list.putUserData(PSI_REFERENCE_LIST, new SoftReference<PsiReferenceList>(newList)); + return newList; + } + public static <T extends GrCondition> T replaceBody(T newBody, GrStatement body, ASTNode node, Project project) { if (body == null || newBody == null) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrStringContentImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrStringContentImpl.java index 8b6889455625..3b37bdabebf1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrStringContentImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrStringContentImpl.java @@ -19,8 +19,7 @@ import com.intellij.lang.ASTNode; import com.intellij.psi.LiteralTextEscaper; import com.intellij.psi.PsiLanguageInjectionHost; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrString; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringContent; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiElementImpl; import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil; @@ -48,10 +47,10 @@ public class GrStringContentImpl extends GroovyPsiElementImpl implements GrStrin @Override public GrStringContentImpl updateText(@NotNull String text) { - - final GrString fromText = (GrString)GroovyPsiElementFactory.getInstance(getProject()).createExpressionFromText("\"${0}" + text + "\""); - final GrStringContent content = fromText.getContents()[0]; - getNode().replaceChild(getFirstChild().getNode(), content.getFirstChild().getNode()); + if (getFirstChild() != null) { + getFirstChild().delete(); + } + getNode().addLeaf(GroovyTokenTypes.mGSTRING_CONTENT, text, null); return this; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrReferenceListImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrReferenceListImpl.java index 0b3f95b8f3d4..6d0c579b03a8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrReferenceListImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrReferenceListImpl.java @@ -61,7 +61,10 @@ public abstract class GrReferenceListImpl extends GrStubElementBase<GrReferenceL keyword.delete(); } else { - PsiElement comma = PsiUtil.skipWhitespacesAndComments(psi, refs[0] == psi, true); + boolean forward = refs[0] == psi; + PsiElement comma = forward + ? PsiUtil.skipWhitespacesAndComments(psi.getNextSibling(), forward, true) + : PsiUtil.skipWhitespacesAndComments(psi.getPrevSibling(), forward, true); if (comma != null && comma.getNode().getElementType() == GroovyTokenTypes.mCOMMA) { comma.delete(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java index 7502ac67a38a..3e3abfc1b494 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java @@ -260,12 +260,12 @@ public abstract class GrTypeDefinitionImpl extends GrStubElementBase<GrTypeDefin @Nullable public PsiReferenceList getExtendsList() { - return null; + return PsiImplUtil.getOrCreatePsiReferenceList(getExtendsClause(), PsiReferenceList.Role.EXTENDS_LIST); } @Nullable public PsiReferenceList getImplementsList() { - return null; + return PsiImplUtil.getOrCreatePsiReferenceList(getImplementsClause(), PsiReferenceList.Role.IMPLEMENTS_LIST); } @NotNull diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrSyntheticReferenceList.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrSyntheticReferenceList.java new file mode 100644 index 000000000000..3cdfb3a7e270 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrSyntheticReferenceList.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.lang.psi.impl.synthetic; + +import com.intellij.psi.PsiClassType; +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.psi.PsiReferenceList; +import com.intellij.psi.impl.light.LightElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList; + +/** + * Created by Max Medvedev on 10/1/13 + */ +public class GrSyntheticReferenceList extends LightElement implements PsiReferenceList { + private final GrReferenceList myList; + private final Role myRole; + + public GrSyntheticReferenceList(GrReferenceList list, Role role) { + super(list.getManager(), list.getLanguage()); + myList = list; + myRole = role; + } + + @Override + public String toString() { + return "Synthetic reference list"; + } + + @NotNull + @Override + public PsiJavaCodeReferenceElement[] getReferenceElements() { + return PsiJavaCodeReferenceElement.EMPTY_ARRAY; + } + + @NotNull + @Override + public PsiClassType[] getReferencedTypes() { + return myList.getReferenceTypes(); + } + + @Override + public Role getRole() { + return myRole; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java index 6863f36b3a85..3cd67f2e649b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java @@ -468,9 +468,10 @@ public class GrStringUtil { if (literal instanceof GrString) { final GrStringInjection[] injections = ((GrString)literal).getInjections(); if (injections.length > 0) { - if (injections[injections.length - 1].getExpression() != null) { - if (!checkBraceIsUnnecessary(injections[injections.length - 1].getExpression(), injection.getNextSibling())) { - wrapInjection(injections[injections.length - 1]); + GrStringInjection last = injections[injections.length - 1]; + if (last.getExpression() != null) { + if (!checkBraceIsUnnecessary(last.getExpression(), injection.getNextSibling())) { + wrapInjection(last); } } } @@ -488,8 +489,9 @@ public class GrStringUtil { final GrExpression expression = factory.createExpressionFromText("\"\"\"${}" + literalText + "\"\"\""); - expression.getFirstChild().delete(); - expression.getFirstChild().delete(); + expression.getFirstChild().delete();//quote + expression.getFirstChild().delete();//empty gstring content + expression.getFirstChild().delete();//empty injection final ASTNode node = grString.getNode(); if (expression.getFirstChild() != null) { @@ -541,12 +543,12 @@ public class GrStringUtil { if (!(statements[0] instanceof GrReferenceExpression)) return false; - final PsiElement next = injection.getNextSibling(); - - return checkBraceIsUnnecessary(statements[0], next); + return checkBraceIsUnnecessary(statements[0], injection.getNextSibling()); } private static boolean checkBraceIsUnnecessary(GrStatement injected, PsiElement next) { + if (next.getTextLength() == 0) next = next.getNextSibling(); + char nextChar = next.getText().charAt(0); if (nextChar == '"' || nextChar == '$') { return true; @@ -561,8 +563,14 @@ public class GrStringUtil { } if (!(gString instanceof GrString)) return false; - final PsiElement child = gString.getChildren()[0]; - if (!(child instanceof GrStringInjection)) return false; + PsiElement child = gString.getFirstChild(); + if (!(child.getNode().getElementType() == mGSTRING_BEGIN)) return false; + + child = child.getNextSibling(); + if (child == null || !(child instanceof GrStringContent)) return false; + + child = child.getNextSibling(); + if (child == null || !(child instanceof GrStringInjection)) return false; final PsiElement refExprCopy = ((GrStringInjection)child).getExpression(); if (!(refExprCopy instanceof GrReferenceExpression)) return false; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkForNewModuleWizardStep.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkForNewModuleWizardStep.java index ddc545b9f598..35516929747f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkForNewModuleWizardStep.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkForNewModuleWizardStep.java @@ -16,22 +16,43 @@ package org.jetbrains.plugins.groovy.mvc; import com.intellij.ide.util.projectWizard.ModuleBuilder; +import com.intellij.ide.util.projectWizard.ModuleWizardStep; +import com.intellij.ide.util.projectWizard.SettingsStep; import com.intellij.ide.util.projectWizard.WizardContext; +import com.intellij.openapi.module.JavaModuleType; +import com.intellij.openapi.options.ConfigurationException; +import org.jetbrains.annotations.Nullable; /** * @author nik */ public class GroovySdkForNewModuleWizardStep extends GroovySdkWizardStepBase { - private final ModuleBuilder myModuleBuilder; - public GroovySdkForNewModuleWizardStep(ModuleBuilder moduleBuilder, WizardContext wizardContext, final MvcFramework framework) { - super(framework, wizardContext); - myModuleBuilder = moduleBuilder; - myModuleBuilder.addModuleConfigurationUpdater(createModuleConfigurationUpdater()); + @Nullable + private ModuleWizardStep myJavaStep; + + public GroovySdkForNewModuleWizardStep(ModuleBuilder moduleBuilder, + WizardContext wizardContext, + final MvcFramework framework, + SettingsStep settingsStep) { + super(framework, wizardContext, moduleBuilder.getContentEntryPath()); + moduleBuilder.addModuleConfigurationUpdater(createModuleConfigurationUpdater()); + if (settingsStep != null) { + myJavaStep = JavaModuleType.getModuleType().modifySettingsStep(settingsStep, moduleBuilder); + settingsStep.addSettingsField("\u001BGroovy library:", getPanel().getSimplePanel()); + } + } + + @Override + public boolean validate() throws ConfigurationException { + return super.validate() && (myJavaStep == null || myJavaStep.validate()); } @Override - protected String getBasePath() { - return myModuleBuilder.getContentEntryPath(); + public void updateDataModel() { + super.updateDataModel(); + if (myJavaStep != null) { + myJavaStep.updateDataModel(); + } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkForProjectFromSourcesStep.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkForProjectFromSourcesStep.java index 926c4aab91e0..83cd58f495d6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkForProjectFromSourcesStep.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkForProjectFromSourcesStep.java @@ -36,18 +36,13 @@ public class GroovySdkForProjectFromSourcesStep extends GroovySdkWizardStepBase public GroovySdkForProjectFromSourcesStep(MvcProjectStructureDetector detector, ProjectFromSourcesBuilder builder, ProjectDescriptor projectDescriptor, MvcFramework framework) { - super(framework, builder.getContext()); + super(framework, builder.getContext(), builder.getBaseProjectPath()); myDetector = detector; myBuilder = builder; myProjectDescriptor = projectDescriptor; } @Override - protected String getBasePath() { - return myBuilder.getBaseProjectPath(); - } - - @Override public void updateDataModel() { super.updateDataModel(); List<ModuleDescriptor> modules = new ArrayList<ModuleDescriptor>(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkWizardStepBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkWizardStepBase.java index ae76950e1cb8..84b96c39fd78 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkWizardStepBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/GroovySdkWizardStepBase.java @@ -35,16 +35,13 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.config.GroovyLibraryDescription; import javax.swing.*; -import javax.swing.border.CompoundBorder; -import javax.swing.border.EmptyBorder; -import javax.swing.border.EtchedBorder; -import java.awt.*; import java.util.ArrayList; /** * @author nik */ public abstract class GroovySdkWizardStepBase extends ModuleWizardStep { + private final String myBasePath; private LibraryOptionsPanel myPanel; private final LibrariesContainer myLibrariesContainer; private boolean myDownloaded; @@ -52,7 +49,8 @@ public abstract class GroovySdkWizardStepBase extends ModuleWizardStep { @Nullable private final MvcFramework myFramework; - public GroovySdkWizardStepBase(@Nullable final MvcFramework framework, WizardContext wizardContext) { + public GroovySdkWizardStepBase(@Nullable final MvcFramework framework, WizardContext wizardContext, String basePath) { + myBasePath = basePath; final Project project = wizardContext.getProject(); myLibrariesContainer = LibrariesContainerFactory.createContainer(project); myFramework = framework; @@ -79,18 +77,7 @@ public abstract class GroovySdkWizardStepBase extends ModuleWizardStep { @Override public JComponent getComponent() { - final JComponent component = getPanel().getMainPanel(); - final JPanel panel = new JPanel(new BorderLayout()); - panel.add(component, BorderLayout.NORTH); - - final JLabel caption = new JLabel("Please specify " + (myFramework == null ? "Groovy" : myFramework.getDisplayName()) + " SDK"); - caption.setBorder(new EmptyBorder(0, 0, 10, 0)); - - final JPanel mainPanel = new JPanel(new BorderLayout()); - mainPanel.setBorder(new CompoundBorder(new EtchedBorder(), new EmptyBorder(5, 5, 5, 5))); - mainPanel.add(caption, BorderLayout.NORTH); - mainPanel.add(panel, BorderLayout.CENTER); - return mainPanel; + return getPanel().getMainPanel(); } @Override @@ -112,16 +99,12 @@ public abstract class GroovySdkWizardStepBase extends ModuleWizardStep { myLibraryCompositionSettings = getPanel().apply(); } - private synchronized LibraryOptionsPanel getPanel() { + protected LibraryOptionsPanel getPanel() { if (myPanel == null) { final GroovyLibraryDescription libraryDescription = myFramework == null ? new GroovyLibraryDescription() : myFramework.createLibraryDescription(); - final String basePath = getBasePath(); - final String baseDirPath = basePath != null ? FileUtil.toSystemIndependentName(basePath) : ""; + final String baseDirPath = myBasePath != null ? FileUtil.toSystemIndependentName(myBasePath) : ""; myPanel = new LibraryOptionsPanel(libraryDescription, baseDirPath, FrameworkLibraryVersionFilter.ALL, myLibrariesContainer, false); } return myPanel; } - - @Nullable - protected abstract String getBasePath(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleBuilder.java index 2b3176bac36c..ea0dae6f6dad 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleBuilder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleBuilder.java @@ -33,7 +33,7 @@ public class MvcModuleBuilder extends GroovyAwareModuleBuilder { private final MvcFramework myFramework; protected MvcModuleBuilder(MvcFramework framework, Icon bigIcon) { - super(framework.getFrameworkName(), framework.getDisplayName() + " Module", + super(framework.getFrameworkName(), framework.getDisplayName(), framework.getDisplayName() + " modules are used for creating <b>" + framework.getDisplayName() + "</b> applications.", bigIcon); myFramework = framework; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GrRefactoringConflictsUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GrRefactoringConflictsUtil.java new file mode 100644 index 000000000000..bb3a5f107283 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GrRefactoringConflictsUtil.java @@ -0,0 +1,262 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.refactoring; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtilCore; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.impl.light.LightElement; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchScopeUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtilCore; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.util.*; +import com.intellij.usageView.UsageInfo; +import com.intellij.util.VisibilityUtil; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.FilteringIterator; +import com.intellij.util.containers.HashSet; +import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember; +import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + + +/** + * Created by Max Medvedev on 9/28/13 + */ +public class GrRefactoringConflictsUtil { + private GrRefactoringConflictsUtil() { } + + public static void analyzeAccessibilityConflicts(@NotNull Set<GrMember> membersToMove, + @NotNull PsiClass targetClass, + @NotNull MultiMap<PsiElement, String> conflicts, + @Nullable String newVisibility) { + analyzeAccessibilityConflicts(membersToMove, targetClass, conflicts, newVisibility, targetClass, null); + } + + public static void analyzeAccessibilityConflicts(@NotNull Set<GrMember> membersToMove, + @Nullable PsiClass targetClass, + @NotNull MultiMap<PsiElement, String> conflicts, + @Nullable String newVisibility, + @NotNull PsiElement context, + @Nullable Set<PsiMethod> abstractMethods) { + if (VisibilityUtil.ESCALATE_VISIBILITY.equals(newVisibility)) { //Still need to check for access object + newVisibility = PsiModifier.PUBLIC; + } + + for (GrMember member : membersToMove) { + checkUsedElements(member, member, membersToMove, abstractMethods, targetClass, context, conflicts); + RefactoringConflictsUtil.checkAccessibilityConflicts(member, newVisibility, targetClass, membersToMove, conflicts); + } + } + + public static void checkUsedElements(PsiMember member, + PsiElement scope, + @NotNull Set<GrMember> membersToMove, + @Nullable Set<PsiMethod> abstractMethods, + @Nullable PsiClass targetClass, + @NotNull PsiElement context, + MultiMap<PsiElement, String> conflicts) { + final Set<PsiMember> moving = new HashSet<PsiMember>(membersToMove); + if (abstractMethods != null) { + moving.addAll(abstractMethods); + } + if (scope instanceof GrReferenceExpression) { + GrReferenceExpression refExpr = (GrReferenceExpression)scope; + PsiElement refElement = refExpr.resolve(); + if (refElement instanceof PsiMember) { + if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, moving, targetClass, false)) { + GrExpression qualifier = refExpr.getQualifierExpression(); + PsiClass accessClass = (PsiClass)(qualifier != null ? PsiUtil.getAccessObjectClass( + qualifier).getElement() : null); + RefactoringConflictsUtil.checkAccessibility((PsiMember)refElement, context, accessClass, member, conflicts); + } + } + } + else if (scope instanceof GrNewExpression) { + final GrNewExpression newExpression = (GrNewExpression)scope; + final GrAnonymousClassDefinition anonymousClass = newExpression.getAnonymousClassDefinition(); + if (anonymousClass != null) { + if (!RefactoringHierarchyUtil.willBeInTargetClass(anonymousClass, moving, targetClass, false)) { + RefactoringConflictsUtil.checkAccessibility(anonymousClass, context, anonymousClass, member, conflicts); + } + } + else { + final PsiMethod refElement = newExpression.resolveMethod(); + if (refElement != null) { + if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, moving, targetClass, false)) { + RefactoringConflictsUtil.checkAccessibility(refElement, context, null, member, conflicts); + } + } + } + } + else if (scope instanceof GrCodeReferenceElement) { + GrCodeReferenceElement refExpr = (GrCodeReferenceElement)scope; + PsiElement refElement = refExpr.resolve(); + if (refElement instanceof PsiMember) { + if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, moving, targetClass, false)) { + RefactoringConflictsUtil.checkAccessibility((PsiMember)refElement, context, null, member, conflicts); + } + } + } + + for (PsiElement child : scope.getChildren()) { + if (child instanceof PsiWhiteSpace || child instanceof PsiComment) continue; + checkUsedElements(member, child, membersToMove, abstractMethods, targetClass, context, conflicts); + } + } + + + + public static void analyzeModuleConflicts(final Project project, + final Collection<? extends PsiElement> scopes, + final UsageInfo[] usages, + final PsiElement target, + final MultiMap<PsiElement,String> conflicts) { + if (scopes == null) return; + final VirtualFile vFile = PsiUtilCore.getVirtualFile(target); + if (vFile == null) return; + + + List<GroovyPsiElement> groovyScopes = + ContainerUtil.collect(scopes.iterator(), new FilteringIterator.InstanceOf<GroovyPsiElement>(GroovyPsiElement.class)); + analyzeModuleConflicts(project, groovyScopes, usages, vFile, conflicts); + scopes.removeAll(groovyScopes); + RefactoringConflictsUtil.analyzeModuleConflicts(project, scopes, usages, vFile, conflicts); + } + + public static void analyzeModuleConflicts(final Project project, + final Collection<? extends GroovyPsiElement> scopes, + final UsageInfo[] usages, + final VirtualFile vFile, + final MultiMap<PsiElement, String> conflicts) { + if (scopes == null) return; + for (final PsiElement scope : scopes) { + if (scope instanceof PsiPackage) return; + } + + final Module targetModule = ModuleUtilCore.findModuleForFile(vFile, project); + if (targetModule == null) return; + final GlobalSearchScope resolveScope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(targetModule); + final HashSet<PsiElement> reported = new HashSet<PsiElement>(); + for (final GroovyPsiElement scope : scopes) { + scope.accept(new GroovyRecursiveElementVisitor() { + @Override + public void visitCodeReferenceElement(GrCodeReferenceElement refElement) { + super.visitCodeReferenceElement(refElement); + visit(refElement); + } + + @Override + public void visitReferenceExpression(GrReferenceExpression reference) { + super.visitReferenceExpression(reference); + visit(reference); + } + + private void visit(GrReferenceElement<? extends GroovyPsiElement> reference) { + final PsiElement resolved = reference.resolve(); + if (resolved != null && + !reported.contains(resolved) && + !CommonRefactoringUtil.isAncestor(resolved, scopes) && + !PsiSearchScopeUtil.isInScope(resolveScope, resolved) && + !(resolved instanceof LightElement)) { + final String scopeDescription = RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(reference), true); + final String message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.in.module.2", + RefactoringUIUtil.getDescription(resolved, true), + scopeDescription, + CommonRefactoringUtil.htmlEmphasize(targetModule.getName())); + conflicts.putValue(resolved, CommonRefactoringUtil.capitalize(message)); + reported.add(resolved); + } + } + }); + } + + boolean isInTestSources = ModuleRootManager.getInstance(targetModule).getFileIndex().isInTestSourceContent(vFile); + NextUsage: + for (UsageInfo usage : usages) { + final PsiElement element = usage.getElement(); + if (element != null && PsiTreeUtil.getParentOfType(element, GrImportStatement.class, false) == null) { + + for (PsiElement scope : scopes) { + if (PsiTreeUtil.isAncestor(scope, element, false)) continue NextUsage; + } + + final GlobalSearchScope resolveScope1 = element.getResolveScope(); + if (!resolveScope1.isSearchInModuleContent(targetModule, isInTestSources)) { + final PsiFile usageFile = element.getContainingFile(); + PsiElement container; + if (usageFile instanceof PsiJavaFile) { + container = ConflictsUtil.getContainer(element); + } + else { + container = usageFile; + } + final String scopeDescription = RefactoringUIUtil.getDescription(container, true); + final VirtualFile usageVFile = usageFile.getVirtualFile(); + if (usageVFile != null) { + Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(usageVFile); + if (module != null) { + final String message; + final PsiElement referencedElement; + if (usage instanceof MoveRenameUsageInfo) { + referencedElement = ((MoveRenameUsageInfo)usage).getReferencedElement(); + } + else { + referencedElement = usage.getElement(); + } + assert referencedElement != null : usage; + if (module == targetModule && isInTestSources) { + message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.from.production.of.module.2", + RefactoringUIUtil.getDescription(referencedElement, true), + scopeDescription, + CommonRefactoringUtil.htmlEmphasize(module.getName())); + } + else { + message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.from.module.2", + RefactoringUIUtil.getDescription(referencedElement, true), + scopeDescription, + CommonRefactoringUtil.htmlEmphasize(module.getName())); + } + conflicts.putValue(referencedElement, CommonRefactoringUtil.capitalize(message)); + } + } + } + } + } + } + +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureConflictSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureConflictSearcher.java index c5f8ebcd07c9..b679c77918c4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureConflictSearcher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureConflictSearcher.java @@ -31,14 +31,13 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.VisibilityUtil; import com.intellij.util.containers.HashSet; import com.intellij.util.containers.MultiMap; -import org.jetbrains.annotations.Nullable; 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.GrConstructorInvocation; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import java.util.Arrays; import java.util.Iterator; @@ -92,7 +91,7 @@ class GrChangeSignatureConflictSearcher { PsiClass accessObjectClass = null; GrExpression qualifier = ((GrReferenceExpression)element).getQualifierExpression(); if (qualifier != null) { - accessObjectClass = getAccessObjectClass(qualifier); + accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass(qualifier).getElement(); } PsiResolveHelper helper = JavaPsiFacade.getInstance(element.getProject()).getResolveHelper(); @@ -112,23 +111,6 @@ class GrChangeSignatureConflictSearcher { } } - @Nullable - private static PsiClass getAccessObjectClass(GrExpression expression) { - if (expression instanceof GrConstructorInvocation) return null; - PsiType type = expression.getType(); - if (type instanceof PsiClassType) { - return ((PsiClassType)type).resolveGenerics().getElement(); - } - if (type == null && expression instanceof PsiReferenceExpression) { - JavaResolveResult resolveResult = ((PsiReferenceExpression)expression).advancedResolve(false); - if (resolveResult.getElement() instanceof PsiClass) { - return (PsiClass)resolveResult.getElement(); - } - } - return null; - } - - private void addMethodConflicts(MultiMap<PsiElement, String> conflicts) { try { GrMethod prototype; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureHandler.java index 03e9120c4915..d67ab211b481 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureHandler.java @@ -16,6 +16,7 @@ package org.jetbrains.plugins.groovy.refactoring.changeSignature; import com.intellij.ide.util.SuperMethodWarningUtil; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -49,7 +50,7 @@ public class GrChangeSignatureHandler implements ChangeSignatureHandler { editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); PsiElement element = findTargetMember(file, editor); if (element == null) { - element = LangDataKeys.PSI_ELEMENT.getData(dataContext); + element = CommonDataKeys.PSI_ELEMENT.getData(dataContext); } invokeOnElement(project, editor, element); } @@ -67,7 +68,7 @@ public class GrChangeSignatureHandler implements ChangeSignatureHandler { public void invoke(@NotNull final Project project, @NotNull final PsiElement[] elements, final DataContext dataContext) { if (elements.length != 1) return; - Editor editor = dataContext == null ? null : PlatformDataKeys.EDITOR.getData(dataContext); + Editor editor = dataContext == null ? null : CommonDataKeys.EDITOR.getData(dataContext); invokeOnElement(project, editor, elements[0]); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaHandler.java index 8e5abecf10d9..5178884f845c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaHandler.java @@ -15,6 +15,7 @@ */ package org.jetbrains.plugins.groovy.refactoring.convertToJava; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; @@ -46,7 +47,7 @@ public class ConvertToJavaHandler implements RefactoringActionHandler { public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) { Editor editor = null; if (dataContext != null) { - editor = PlatformDataKeys.EDITOR.getData(dataContext); + editor = CommonDataKeys.EDITOR.getData(dataContext); } invokeInner(project, elements, editor); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/encapsulateFields/GroovyEncapsulateFieldHelper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/encapsulateFields/GroovyEncapsulateFieldHelper.java index d7be9bf39c54..eeef75863630 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/encapsulateFields/GroovyEncapsulateFieldHelper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/encapsulateFields/GroovyEncapsulateFieldHelper.java @@ -61,13 +61,13 @@ public class GroovyEncapsulateFieldHelper extends EncapsulateFieldHelper { @Override @NotNull public String suggestSetterName(@NotNull PsiField field) { - return PropertyUtil.suggestSetterName(field.getProject(), field); + return PropertyUtil.suggestSetterName(field); } @Override @NotNull public String suggestGetterName(@NotNull PsiField field) { - return PropertyUtil.suggestGetterName(field.getProject(), field); + return PropertyUtil.suggestGetterName(field); } @Override diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpConflictsUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpConflictsUtil.java new file mode 100644 index 000000000000..6cf223cec996 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpConflictsUtil.java @@ -0,0 +1,376 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.refactoring.memberPullUp; + +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.search.searches.ClassInheritorsSearch; +import com.intellij.psi.util.*; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.classMembers.MemberInfoBase; +import com.intellij.refactoring.util.CommonRefactoringUtil; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; +import com.intellij.refactoring.util.RefactoringUIUtil; +import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier; +import com.intellij.usageView.UsageInfo; +import com.intellij.util.VisibilityUtil; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; +import org.jetbrains.plugins.groovy.refactoring.GrRefactoringConflictsUtil; +import org.jetbrains.plugins.groovy.refactoring.classMembers.GrClassMemberReferenceVisitor; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Created by Max Medvedev on 9/28/13 + */ +public class GrPullUpConflictsUtil { + private GrPullUpConflictsUtil() {} + + public static MultiMap<PsiElement, String> checkConflicts(MemberInfoBase<? extends GrMember>[] infos, + PsiClass subclass, + @Nullable PsiClass superClass, + @NotNull PsiPackage targetPackage, + @NotNull PsiDirectory targetDirectory, + final InterfaceContainmentVerifier interfaceContainmentVerifier) { + return checkConflicts(infos, subclass, superClass, targetPackage, targetDirectory, interfaceContainmentVerifier, true); + } + + public static MultiMap<PsiElement, String> checkConflicts(final MemberInfoBase<? extends GrMember>[] infos, + @NotNull final PsiClass subclass, + @Nullable PsiClass superClass, + @NotNull final PsiPackage targetPackage, + @NotNull PsiDirectory targetDirectory, + final InterfaceContainmentVerifier interfaceContainmentVerifier, + boolean movedMembers2Super) { + final PsiElement targetRepresentativeElement; + final boolean isInterfaceTarget; + if (superClass != null) { + isInterfaceTarget = superClass.isInterface(); + targetRepresentativeElement = superClass; + } + else { + isInterfaceTarget = false; + targetRepresentativeElement = targetDirectory; + } + + final Set<GrMember> movedMembers = ContainerUtil.newHashSet(); + final Set<GrMethod> abstractMethods = ContainerUtil.newHashSet(); + for (MemberInfoBase<? extends GrMember> info : infos) { + GrMember member = info.getMember(); + if (member instanceof GrMethod) { + if (!info.isToAbstract() && !isInterfaceTarget) { + movedMembers.add(member); + } + else { + abstractMethods.add((GrMethod)member); + } + } + else { + movedMembers.add(member); + } + } + + final Set<PsiMethod> allAbstractMethods = new HashSet<PsiMethod>(abstractMethods); + if (superClass != null) { + for (PsiMethod method : subclass.getMethods()) { + if (!movedMembers.contains(method) && !method.hasModifierProperty(PsiModifier.PRIVATE)) { + if (method.findSuperMethods(superClass).length > 0) { + allAbstractMethods.add(method); + } + } + } + } + + final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>(); + + GrRefactoringConflictsUtil.analyzeAccessibilityConflicts(movedMembers, superClass, conflicts, VisibilityUtil.ESCALATE_VISIBILITY, targetRepresentativeElement, + allAbstractMethods); + + if (superClass != null) { + if (movedMembers2Super) { + checkSuperclassMembers(superClass, infos, conflicts); + if (isInterfaceTarget) { + checkInterfaceTarget(infos, conflicts); + } + } else { + final String qualifiedName = superClass.getQualifiedName(); + assert qualifiedName != null; + if (superClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { + if (!Comparing.strEqual(StringUtil.getPackageName(qualifiedName), targetPackage.getQualifiedName())) { + conflicts.putValue(superClass, RefactoringUIUtil.getDescription(superClass, true) + " won't be accessible from " +RefactoringUIUtil.getDescription(targetPackage, true)); + } + } + } + } + // check if moved methods use other members in the classes between Subclass and Superclass + List<PsiElement> checkModuleConflictsList = new ArrayList<PsiElement>(); + for (PsiMember member : movedMembers) { + if (member instanceof PsiMethod || member instanceof PsiClass && !(member instanceof PsiCompiledElement)) { + GrClassMemberReferenceVisitor visitor = + movedMembers2Super? new ConflictingUsagesOfSubClassMembers(member, movedMembers, abstractMethods, subclass, superClass, + superClass != null ? null : targetPackage, conflicts, + interfaceContainmentVerifier) + : new ConflictingUsagesOfSuperClassMembers(member, subclass, targetPackage, movedMembers, conflicts); + ((GroovyPsiElement)member).accept(visitor); + } + checkModuleConflictsList.add(member); + } + for (final PsiMethod method : abstractMethods) { + ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getParameterList()); + ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getReturnTypeElement()); + ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getTypeParameterList()); + } + GrRefactoringConflictsUtil.analyzeModuleConflicts(subclass.getProject(), checkModuleConflictsList, new UsageInfo[0], targetRepresentativeElement, conflicts); + final String fqName = subclass.getQualifiedName(); + final String packageName; + if (fqName != null) { + packageName = StringUtil.getPackageName(fqName); + } else { + final PsiFile psiFile = PsiTreeUtil.getParentOfType(subclass, PsiFile.class); + if (psiFile instanceof PsiClassOwner) { + packageName = ((PsiClassOwner)psiFile).getPackageName(); + } else { + packageName = null; + } + } + final boolean toDifferentPackage = !Comparing.strEqual(targetPackage.getQualifiedName(), packageName); + for (final GrMethod abstractMethod : abstractMethods) { + abstractMethod.accept(new GrClassMemberReferenceVisitor(subclass) { + @Override + protected void visitClassMemberReferenceElement(GrMember classMember, GrReferenceElement classMemberReference) { + if (classMember != null && willBeMoved(classMember, movedMembers)) { + boolean isAccessible = false; + if (classMember.hasModifierProperty(PsiModifier.PRIVATE)) { + isAccessible = true; + } + else if (classMember.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && + toDifferentPackage) { + isAccessible = true; + } + if (isAccessible) { + String message = RefactoringUIUtil.getDescription(abstractMethod, false) + + " uses " + + RefactoringUIUtil.getDescription(classMember, true) + + " which won't be accessible from the subclass."; + message = CommonRefactoringUtil.capitalize(message); + conflicts.putValue(classMember, message); + } + } + } + }); + if (abstractMethod.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && toDifferentPackage) { + if (!isInterfaceTarget) { + String message = "Can't make " + RefactoringUIUtil.getDescription(abstractMethod, false) + + " abstract as it won't be accessible from the subclass."; + message = CommonRefactoringUtil.capitalize(message); + conflicts.putValue(abstractMethod, message); + } + } + } + return conflicts; + } + + private static void checkInterfaceTarget(MemberInfoBase<? extends GrMember>[] infos, MultiMap<PsiElement, String> conflictsList) { + for (MemberInfoBase<? extends GrMember> info : infos) { + GrMember member = info.getMember(); + + if (member instanceof PsiField || member instanceof PsiClass) { + if (!member.hasModifierProperty(PsiModifier.STATIC) && !(member instanceof PsiClass && ((PsiClass)member).isInterface())) { + String message = RefactoringBundle.message("0.is.not.static.it.cannot.be.moved.to.the.interface", RefactoringUIUtil.getDescription(member, false)); + message = CommonRefactoringUtil.capitalize(message); + conflictsList.putValue(member, message); + } + } + + if (member instanceof PsiField && ((PsiField)member).getInitializer() == null) { + String message = RefactoringBundle.message("0.is.not.initialized.in.declaration.such.fields.are.not.allowed.in.interfaces", + RefactoringUIUtil.getDescription(member, false)); + conflictsList.putValue(member, CommonRefactoringUtil.capitalize(message)); + } + } + } + + private static void checkSuperclassMembers(PsiClass superClass, + MemberInfoBase<? extends GrMember>[] infos, + MultiMap<PsiElement, String> conflictsList) { + for (MemberInfoBase<? extends GrMember> info : infos) { + GrMember member = info.getMember(); + boolean isConflict = false; + if (member instanceof PsiField) { + String name = member.getName(); + + isConflict = superClass.findFieldByName(name, false) != null; + } + else if (member instanceof PsiMethod) { + PsiSubstitutor superSubstitutor = TypeConversionUtil + .getSuperClassSubstitutor(superClass, member.getContainingClass(), PsiSubstitutor.EMPTY); + MethodSignature signature = ((PsiMethod) member).getSignature(superSubstitutor); + final PsiMethod superClassMethod = MethodSignatureUtil.findMethodBySignature(superClass, signature, false); + isConflict = superClassMethod != null; + } + + if (isConflict) { + String message = RefactoringBundle.message("0.already.contains.a.1", + RefactoringUIUtil.getDescription(superClass, false), + RefactoringUIUtil.getDescription(member, false)); + message = CommonRefactoringUtil.capitalize(message); + conflictsList.putValue(superClass, message); + } + + if (member instanceof PsiMethod) { + final PsiMethod method = (PsiMethod)member; + final PsiModifierList modifierList = method.getModifierList(); + if (!modifierList.hasModifierProperty(PsiModifier.PRIVATE)) { + for (PsiClass subClass : ClassInheritorsSearch.search(superClass)) { + if (method.getContainingClass() != subClass) { + MethodSignature signature = ((PsiMethod) member).getSignature(TypeConversionUtil.getSuperClassSubstitutor(superClass, subClass, PsiSubstitutor.EMPTY)); + final PsiMethod wouldBeOverriden = MethodSignatureUtil.findMethodBySignature(subClass, signature, false); + if (wouldBeOverriden != null && VisibilityUtil.compare(VisibilityUtil.getVisibilityModifier(wouldBeOverriden.getModifierList()), + VisibilityUtil.getVisibilityModifier(modifierList)) > 0) { + conflictsList.putValue(wouldBeOverriden, CommonRefactoringUtil.capitalize(RefactoringUIUtil.getDescription(method, true) + " in super class would clash with local method from " + RefactoringUIUtil.getDescription(subClass, true))); + } + } + } + } + } + } + + } + + private static boolean willBeMoved(PsiElement element, Set<GrMember> movedMembers) { + PsiElement parent = element; + while (parent != null) { + if (movedMembers.contains(parent)) return true; + parent = parent.getParent(); + } + return false; + } + + private static class ConflictingUsagesOfSuperClassMembers extends GrClassMemberReferenceVisitor { + + private PsiMember myMember; + private PsiClass mySubClass; + private PsiPackage myTargetPackage; + private Set<GrMember> myMovedMembers; + private MultiMap<PsiElement, String> myConflicts; + + public ConflictingUsagesOfSuperClassMembers(PsiMember member, PsiClass aClass, + PsiPackage targetPackage, + Set<GrMember> movedMembers, + MultiMap<PsiElement, String> conflicts) { + super(aClass); + myMember = member; + mySubClass = aClass; + myTargetPackage = targetPackage; + myMovedMembers = movedMembers; + myConflicts = conflicts; + } + + @Override + protected void visitClassMemberReferenceElement(GrMember classMember, GrReferenceElement ref) { + if (classMember != null && !willBeMoved(classMember, myMovedMembers)) { + final PsiClass containingClass = classMember.getContainingClass(); + if (containingClass != null && + !PsiUtil.isAccessibleFromPackage(classMember, myTargetPackage) && + (classMember.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) || + classMember.hasModifierProperty(PsiModifier.PROTECTED) && !mySubClass.isInheritor(containingClass, true))) { + myConflicts.putValue(myMember, RefactoringUIUtil.getDescription(classMember, true) + " won't be accessible"); + } + } + + } + + } + + private static class ConflictingUsagesOfSubClassMembers extends GrClassMemberReferenceVisitor { + private final PsiElement myScope; + private final Set<GrMember> myMovedMembers; + private final Set<GrMethod> myAbstractMethods; + private final PsiClass mySubclass; + private final PsiClass mySuperClass; + private final PsiPackage myTargetPackage; + private final MultiMap<PsiElement, String> myConflictsList; + private final InterfaceContainmentVerifier myInterfaceContainmentVerifier; + + ConflictingUsagesOfSubClassMembers(PsiElement scope, + Set<GrMember> movedMembers, Set<GrMethod> abstractMethods, + PsiClass subclass, PsiClass superClass, + PsiPackage targetPackage, MultiMap<PsiElement, String> conflictsList, + InterfaceContainmentVerifier interfaceContainmentVerifier) { + super(subclass); + myScope = scope; + myMovedMembers = movedMembers; + myAbstractMethods = abstractMethods; + mySubclass = subclass; + mySuperClass = superClass; + myTargetPackage = targetPackage; + myConflictsList = conflictsList; + myInterfaceContainmentVerifier = interfaceContainmentVerifier; + } + + @Override + protected void visitClassMemberReferenceElement(GrMember classMember, GrReferenceElement ref) { + if (classMember != null && RefactoringHierarchyUtil.isMemberBetween(mySuperClass, mySubclass, classMember)) { + if (classMember.hasModifierProperty(PsiModifier.STATIC) && !willBeMoved(classMember, myMovedMembers)) { + final boolean isAccessible = mySuperClass != null ? PsiUtil.isAccessible(classMember, mySuperClass, null) : + myTargetPackage != null ? PsiUtil.isAccessibleFromPackage(classMember, myTargetPackage): + classMember.hasModifierProperty(PsiModifier.PUBLIC); + if (!isAccessible) { + String message = RefactoringBundle.message("0.uses.1.which.is.not.accessible.from.the.superclass", + RefactoringUIUtil.getDescription(myScope, false), + RefactoringUIUtil.getDescription(classMember, true)); + message = CommonRefactoringUtil.capitalize(message); + myConflictsList.putValue(classMember, message); + + } + return; + } + if (!myAbstractMethods.contains(classMember) && !willBeMoved(classMember, myMovedMembers)) { + if (!existsInSuperClass(classMember)) { + String message = RefactoringBundle.message("0.uses.1.which.is.not.moved.to.the.superclass", + RefactoringUIUtil.getDescription(myScope, false), + RefactoringUIUtil.getDescription(classMember, true)); + message = CommonRefactoringUtil.capitalize(message); + myConflictsList.putValue(classMember, message); + } + } + } + + } + + private boolean existsInSuperClass(PsiElement classMember) { + if (!(classMember instanceof PsiMethod)) return false; + final PsiMethod method = ((PsiMethod)classMember); + if (myInterfaceContainmentVerifier.checkedInterfacesContain(method)) return true; + if (mySuperClass == null) return false; + final PsiMethod methodBySignature = mySuperClass.findMethodBySignature(method, true); + return methodBySignature != null; + } + } + + +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpDialog.java index 5fc3aa9dbf80..f61413bd809d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpDialog.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpDialog.java @@ -18,16 +18,15 @@ package org.jetbrains.plugins.groovy.refactoring.memberPullUp; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiDocCommentOwner; -import com.intellij.psi.PsiMember; -import com.intellij.psi.PsiMethod; +import com.intellij.psi.*; import com.intellij.psi.statistics.StatisticsInfo; import com.intellij.psi.statistics.StatisticsManager; +import com.intellij.psi.util.MethodSignature; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; -import com.intellij.refactoring.classMembers.AbstractUsesDependencyMemberInfoModel; import com.intellij.refactoring.classMembers.MemberInfoModel; import com.intellij.refactoring.memberPullUp.PullUpDialogBase; import com.intellij.refactoring.memberPullUp.PullUpHelper; @@ -37,8 +36,10 @@ import com.intellij.refactoring.ui.DocCommentPanel; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.RefactoringHierarchyUtil; import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier; +import com.intellij.refactoring.util.classMembers.UsesAndInterfacesDependencyMemberInfoModel; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember; import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo; import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfoStorage; @@ -46,8 +47,6 @@ import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberSelectionTa import javax.swing.*; import java.awt.*; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; import java.util.List; /** @@ -94,19 +93,19 @@ class GrPullUpDialog extends PullUpDialogBase<GrMemberInfoStorage, GrMemberInfo, } @Override + protected void updateMemberInfo() { + super.updateMemberInfo(); + getRefactorAction().setEnabled(GroovyFileType.GROOVY_LANGUAGE.equals(getSuperClass().getLanguage())); + if (myMemberSelectionPanel != null) { + ((MyMemberInfoModel)myMemberInfoModel).setSuperClass(getSuperClass()); + myMemberSelectionPanel.getTable().setMemberInfos(myMemberInfos); + myMemberSelectionPanel.getTable().fireExternalDataChange(); + } + } + + @Override protected void initClassCombo(JComboBox classCombo) { classCombo.setRenderer(new ClassCellRenderer(classCombo.getRenderer())); - classCombo.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - if (e.getStateChange() == ItemEvent.SELECTED) { - if (myMemberSelectionPanel != null) { - // ((MyMemberInfoModel)myMemberInfoModel).setSuperClass(getSuperClass()); - myMemberSelectionPanel.getTable().setMemberInfos(myMemberInfos); - myMemberSelectionPanel.getTable().fireExternalDataChange(); - } - } - } - }); } protected PsiClass getPreselection() { @@ -140,13 +139,11 @@ class GrPullUpDialog extends PullUpDialogBase<GrMemberInfoStorage, GrMemberInfo, final PsiClass superClass = getSuperClass(); String name = superClass.getQualifiedName(); if (name != null) { - StatisticsManager - .getInstance().incUseCount(new StatisticsInfo(PULL_UP_STATISTICS_KEY + myClass.getQualifiedName(), name)); + StatisticsManager.getInstance().incUseCount(new StatisticsInfo(PULL_UP_STATISTICS_KEY + myClass.getQualifiedName(), name)); } List<GrMemberInfo> infos = getSelectedMemberInfos(); - GrPullUpHelper processor = - new GrPullUpHelper(myClass, superClass, infos.toArray(new GrMemberInfo[infos.size()]), new DocCommentPolicy(getJavaDocPolicy())); + GrPullUpHelper processor = new GrPullUpHelper(myClass, superClass, infos.toArray(new GrMemberInfo[infos.size()]), new DocCommentPolicy(getJavaDocPolicy())); invokeRefactoring(processor); close(OK_EXIT_CODE); } @@ -180,17 +177,75 @@ class GrPullUpDialog extends PullUpDialogBase<GrMemberInfoStorage, GrMemberInfo, return new MyMemberInfoModel(myClass, getSuperClass(), false); } - private static class MyMemberInfoModel extends AbstractUsesDependencyMemberInfoModel<GrMember, PsiClass, GrMemberInfo> { + private class MyMemberInfoModel extends UsesAndInterfacesDependencyMemberInfoModel<GrMember, GrMemberInfo> { public MyMemberInfoModel(PsiClass aClass, PsiClass superClass, boolean recursive) { - super(aClass, superClass, recursive); + super(aClass, superClass, recursive, myInterfaceContainmentVerifier); } @Override - protected int doCheck(@NotNull GrMemberInfo memberInfo, int problem) { - if (problem == ERROR && memberInfo.isStatic()) { - return WARNING; + public boolean isMemberEnabled(GrMemberInfo member) { + PsiClass currentSuperClass = getSuperClass(); + if(currentSuperClass == null) return true; + if (myMemberInfoStorage.getDuplicatedMemberInfos(currentSuperClass).contains(member)) return false; + if (myMemberInfoStorage.getExtending(currentSuperClass).contains(member.getMember())) return false; + if (!currentSuperClass.isInterface()) return true; + + PsiElement element = member.getMember(); + if (element instanceof PsiClass && ((PsiClass) element).isInterface()) return true; + if (element instanceof PsiField) { + return ((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC); } - return problem; + if (element instanceof PsiMethod) { + if (currentSuperClass.isInterface()) { + final PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(currentSuperClass, myClass, PsiSubstitutor.EMPTY); + final MethodSignature signature = ((PsiMethod)element).getSignature(superSubstitutor); + final PsiMethod superClassMethod = MethodSignatureUtil.findMethodBySignature(currentSuperClass, signature, false); + if (superClassMethod != null) return false; + } + return !((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC); + } + return true; + } + + @Override + public boolean isAbstractEnabled(GrMemberInfo member) { + PsiClass currentSuperClass = getSuperClass(); + if (currentSuperClass == null || !currentSuperClass.isInterface()) return true; + return false; + } + + @Override + public boolean isAbstractWhenDisabled(GrMemberInfo member) { + PsiClass currentSuperClass = getSuperClass(); + if(currentSuperClass == null) return false; + if (currentSuperClass.isInterface()) { + if (member.getMember() instanceof PsiMethod) { + return true; + } + } + return false; + } + + @Override + public int checkForProblems(@NotNull GrMemberInfo member) { + if (member.isChecked()) return OK; + PsiClass currentSuperClass = getSuperClass(); + + if (currentSuperClass != null && currentSuperClass.isInterface()) { + PsiMember element = member.getMember(); + if (element.hasModifierProperty(PsiModifier.STATIC)) { + return super.checkForProblems(member); + } + return OK; + } + else { + return super.checkForProblems(member); + } + } + + @Override + public Boolean isFixedAbstract(GrMemberInfo member) { + return Boolean.TRUE; } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHandler.java index 533615048f0a..9e004b0378e1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHandler.java @@ -15,6 +15,7 @@ */ package org.jetbrains.plugins.groovy.refactoring.memberPullUp; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; @@ -29,7 +30,6 @@ import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.classMembers.MemberInfoBase; import com.intellij.refactoring.lang.ElementsHandler; -import com.intellij.refactoring.memberPullUp.PullUpConflictsUtil; import com.intellij.refactoring.ui.ConflictsDialog; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.RefactoringHierarchyUtil; @@ -111,7 +111,7 @@ public class GrPullUpHandler implements RefactoringActionHandler, GrPullUpDialog } private void invokeImpl(Project project, DataContext dataContext, GrTypeDefinition aClass, PsiElement aMember) { - final Editor editor = dataContext != null ? PlatformDataKeys.EDITOR.getData(dataContext) : null; + final Editor editor = dataContext != null ? CommonDataKeys.EDITOR.getData(dataContext) : null; if (aClass == null) { String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("is.not.supported.in.the.current.context", REFACTORING_NAME)); @@ -168,8 +168,7 @@ public class GrPullUpHandler implements RefactoringActionHandler, GrPullUpDialog public void run() { final PsiDirectory targetDirectory = superClass.getContainingFile().getContainingDirectory(); final PsiPackage targetPackage = targetDirectory != null ? JavaDirectoryService.getInstance().getPackage(targetDirectory) : null; - conflicts.putAllValues(PullUpConflictsUtil.checkConflicts(infos, mySubclass, superClass, targetPackage, targetDirectory, - dialog.getContainmentVerifier())); + conflicts.putAllValues(GrPullUpConflictsUtil.checkConflicts(infos, mySubclass, superClass, targetPackage, targetDirectory, dialog.getContainmentVerifier())); } }, RefactoringBundle.message("detecting.possible.conflicts"), true, myProject)) { return false; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelper.java index 028e61301631..00397cb4fa61 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelper.java @@ -25,7 +25,6 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.search.LocalSearchScope; -import com.intellij.psi.search.searches.OverridingMethodsSearch; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.MethodSignatureUtil; import com.intellij.psi.util.PsiTreeUtil; @@ -45,6 +44,9 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; import org.codehaus.groovy.runtime.DefaultGroovyMethods; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocCommentOwner; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.impl.GrDocCommentUtil; import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; @@ -187,13 +189,13 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { // do actual move for (GrMemberInfo info : myMembersToMove) { if (info.getMember() instanceof PsiMethod) { - doMoveMethod(movedMembers, substitutor, info); + doMoveMethod(substitutor, info); } else if (info.getMember() instanceof GrField) { - doMoveField(movedMembers, substitutor, info); + doMoveField(substitutor, info); } else if (info.getMember() instanceof PsiClass) { - doMoveClass(movedMembers, substitutor, info); + doMoveClass(substitutor, info); } } @@ -315,7 +317,7 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { return false; } - private void doMoveMethod(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, GrMemberInfo info) { + private void doMoveMethod(PsiSubstitutor substitutor, GrMemberInfo info) { GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject); GrMethod method = (GrMethod)info.getMember(); PsiMethod sibling = method; @@ -346,10 +348,8 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { } replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); - myDocCommentPolicy.processCopiedJavaDoc(methodCopy.getDocComment(), method.getDocComment(), isOriginalMethodAbstract); - - final PsiMember movedElement = - anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy); + final GrMethod movedElement = + anchor != null ? (GrMethod)myTargetSuperClass.addBefore(methodCopy, anchor) : (GrMethod)myTargetSuperClass.add(methodCopy); CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(method.getProject()); if (styleSettings.INSERT_OVERRIDE_ANNOTATION) { if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myTargetSuperClass.isInterface() || @@ -359,19 +359,16 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { } } - if (!PsiUtil.isLanguageLevel6OrHigher(mySourceClass) && myTargetSuperClass.isInterface()) { - if (isOriginalMethodAbstract) { - for (PsiMethod oMethod : OverridingMethodsSearch.search(method)) { - deleteOverrideAnnotationIfFound(oMethod); - } - } - - deleteOverrideAnnotationIfFound(method); + GrDocComment oldDoc = method.getDocComment(); + if (oldDoc != null) { + GrDocCommentUtil.setDocComment(movedElement, oldDoc); } + myDocCommentPolicy.processCopiedJavaDoc(methodCopy.getDocComment(), oldDoc, isOriginalMethodAbstract); + myMembersAfterMove.add(movedElement); if (isOriginalMethodAbstract) { - method.delete(); + deleteMemberWithDocComment(method); } } else { @@ -382,19 +379,30 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { //fixReferencesToStatic(methodCopy, movedMembers); replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(methodCopy, false); + final GrMethod movedElement; if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { - superClassMethod.replace(methodCopy); + movedElement = (GrMethod)superClassMethod.replace(methodCopy); } else { - final PsiMember movedElement = - anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy); + movedElement = + anchor != null ? (GrMethod)myTargetSuperClass.addBefore(methodCopy, anchor) : (GrMethod)myTargetSuperClass.add(methodCopy); myMembersAfterMove.add(movedElement); } - method.delete(); + GrDocCommentUtil.setDocComment(movedElement, method.getDocComment()); + + deleteMemberWithDocComment(method); } } + private static void deleteMemberWithDocComment(GrDocCommentOwner docCommentOwner) { + GrDocComment oldDoc = docCommentOwner.getDocComment(); + if (oldDoc != null) { + oldDoc.delete(); + } + docCommentOwner.delete(); + } + private static void deleteOverrideAnnotationIfFound(PsiMethod oMethod) { final PsiAnnotation annotation = AnnotationUtil.findAnnotation(oMethod, CommonClassNames.JAVA_LANG_OVERRIDE); if (annotation != null) { @@ -551,7 +559,9 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject); GrReferenceExpression thisExpression = (GrReferenceExpression) factory.createExpressionFromText("this", null); for (GrExpression expression : mySupersToDelete) { - expression.delete(); + if (expression.getParent() instanceof GrReferenceExpression) { + ((GrReferenceExpression)expression.getParent()).setQualifier(null); + } } for (GrReferenceExpression superExpression : mySupersToChangeToThis) { @@ -594,7 +604,7 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { } } - private void doMoveField(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, GrMemberInfo info) { + private void doMoveField(PsiSubstitutor substitutor, GrMemberInfo info) { GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject); GrField field = (GrField)info.getMember(); field.normalizeDeclaration(); @@ -605,10 +615,10 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { } final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(field); myMembersAfterMove.add(movedElement); - field.delete(); + deleteMemberWithDocComment(field); } - private void doMoveClass(Set<PsiMember> movedMembers, PsiSubstitutor substitutor, GrMemberInfo info) { + private void doMoveClass(PsiSubstitutor substitutor, GrMemberInfo info) { GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject); GrTypeDefinition aClass = (GrTypeDefinition)info.getMember(); if (Boolean.FALSE.equals(info.getOverrides())) { @@ -654,7 +664,7 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { PsiMember movedElement = (PsiMember)myTargetSuperClass.addAfter(aClass, null); //movedElement = (PsiMember)CodeStyleManager.getInstance(myProject).reformat(movedElement); myMembersAfterMove.add(movedElement); - aClass.delete(); + deleteMemberWithDocComment(aClass); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/PropertyRenameHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/PropertyRenameHandler.java index 553f12101b3f..01de3d75d89f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/PropertyRenameHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/PropertyRenameHandler.java @@ -16,6 +16,7 @@ package org.jetbrains.plugins.groovy.refactoring.rename; import com.intellij.ide.TitledHandler; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -54,7 +55,7 @@ public class PropertyRenameHandler implements RenameHandler, TitledHandler { @Nullable private static PsiElement getElement(DataContext dataContext) { - return LangDataKeys.PSI_ELEMENT.getData(dataContext); + return CommonDataKeys.PSI_ELEMENT.getData(dataContext); } public boolean isRenaming(DataContext dataContext) { @@ -69,7 +70,7 @@ public class PropertyRenameHandler implements RenameHandler, TitledHandler { public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, @Nullable DataContext dataContext) { PsiElement element = elements.length == 1 ? elements[0] : null; if (element == null) element = getElement(dataContext); - Editor editor = dataContext == null ? null : PlatformDataKeys.EDITOR.getData(dataContext); + Editor editor = dataContext == null ? null : CommonDataKeys.EDITOR.getData(dataContext); invokeInner(project, editor, element); } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/RemoveUnnecessarySemicolonTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/RemoveUnnecessarySemicolonTest.groovy index 2d1c6adefb11..4f1c36bde544 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/RemoveUnnecessarySemicolonTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/RemoveUnnecessarySemicolonTest.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ import org.jetbrains.plugins.groovy.util.TestUtils class RemoveUnnecessarySemicolonTest extends LightCodeInsightFixtureTestCase { private static final String hint = GroovyIntentionsBundle.message('remove.unnecessary.semicolons.name'); - final String basePath = TestUtils.testDataPath + 'intentions/removeUnnecessaryBraces/' + final String basePath = TestUtils.testDataPath + 'intentions/removeUnnecessarySemicolon/' void testSimpleCase1() { doTest('print 2;<caret>\nprint 3', 'print 2\nprint 3') @@ -545,4 +545,22 @@ public class CommonRefactoringUtil { } </selection>''') } + + void testTraditionalFor() { + doTest('<selection>for(int i = 0; i < 5; i++);</selection>', '<selection>for(int i = 0; i < 5; i++)</selection>') + } + + void testClassMembers() { + doTest('''\ +<selection>class A { + def x; + def y; +}</selection> +''', '''\ +<selection>class A { + def x + def y +}</selection> +''') + } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/encapsulateFields/GrEncapsulateFieldsTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/encapsulateFields/GrEncapsulateFieldsTest.groovy index cc39826c44b9..f308eb478b7c 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/encapsulateFields/GrEncapsulateFieldsTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/encapsulateFields/GrEncapsulateFieldsTest.groovy @@ -226,8 +226,8 @@ public class A { final Project project = myFixture.getProject() - if (!getterName) getterName = PropertyUtil.suggestGetterName(project, aField) - if (!setterName) setterName = PropertyUtil.suggestSetterName(project, aField) + if (!getterName) getterName = PropertyUtil.suggestGetterName(aField) + if (!setterName) setterName = PropertyUtil.suggestSetterName(aField) try { final EncapsulateFieldsDescriptor descriptor = createMockDescriptor(aClass, aField, generateGetters, generateSetters, getterName, diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpTest.groovy index e3d95a7b5c8d..9813355df7ce 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpTest.groovy @@ -137,12 +137,28 @@ class GrPullUpTest extends LightGroovyTestCase { doTest(false, new MemberDescriptor("foo", PsiMethod)); } - public void _testExtensionMethod() { + public void testPreserveOverride() { doTest(false, new MemberDescriptor("foo", PsiMethod)); } - public void testPreserveOverride() { - doTest(false, new MemberDescriptor("foo", PsiMethod)); + void testImplementsList1() { + doTest(false, new MemberDescriptor("I1", PsiClass)) + } + + void testImplementsList2() { + doTest(false, new MemberDescriptor("I2", PsiClass)) + } + + void testImplementsList3() { + doTest(false, new MemberDescriptor("I1", PsiClass), new MemberDescriptor("I2", PsiClass)) + } + + void testDocCommentInMethod() { + doTest(false, new MemberDescriptor("foo", PsiMethod)) + } + + void testSupers() { + doTest(false, new MemberDescriptor("bar", PsiMethod)) } private void doTest(MemberDescriptor... membersToFind) { diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str7.test b/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str7.test index 0b391b71d296..50c4209d7559 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str7.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str7.test @@ -3,6 +3,9 @@ Groovy script Compound Gstring PsiElement(Gstring begin)('"') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(Gstring content) + <empty list> GString injection PsiElement($)('$') Reference expression diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str8.test b/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str8.test index 5ab631c32cd4..819cd4b5b810 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str8.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str8.test @@ -10,6 +10,9 @@ Groovy script PsiElement($)('$') Reference expression PsiElement(identifier)('str') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(Gstring content) + <empty list> GString injection PsiElement($)('$') Reference expression @@ -31,6 +34,9 @@ Groovy script Reference expression PsiElement(identifier)('str') PsiElement(})('}') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(Gstring content) + <empty list> GString injection PsiElement($)('$') Reference expression diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str_error1.test b/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str_error1.test index 231123f3a330..1a7dcbcf15fb 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str_error1.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str_error1.test @@ -9,5 +9,8 @@ Groovy script PsiWhiteSpace(' ') Compound Gstring PsiElement(Gstring begin)('"') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(Gstring content) + <empty list> PsiErrorElement:String end expected <empty list>
\ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str_error2.test b/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str_error2.test index d8129d9d1f15..7333a8350eb2 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str_error2.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/gstring/str_error2.test @@ -10,6 +10,9 @@ Groovy script PsiWhiteSpace(' ') Compound Gstring PsiElement(Gstring begin)('"') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(Gstring content) + <empty list> PsiErrorElement:String end expected <empty list> PsiElement(new line)('\n') diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/gstring/triple/quote_and_slash.test b/plugins/groovy/testdata/parsing/groovy/expressions/gstring/triple/quote_and_slash.test index 09e20dbb688e..afb32495619f 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/gstring/triple/quote_and_slash.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/gstring/triple/quote_and_slash.test @@ -14,8 +14,14 @@ Groovy script Reference expression PsiElement(identifier)('href') PsiElement(})('}') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(Gstring content) + <empty list> GString injection PsiElement($)('$') Reference expression PsiElement(identifier)('x') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(Gstring content) + <empty list> PsiElement(Gstring end)('"""')
\ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/path/regexp.test b/plugins/groovy/testdata/parsing/groovy/expressions/path/regexp.test index 36e10294be63..286c6e475ff3 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/path/regexp.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/path/regexp.test @@ -23,6 +23,9 @@ Groovy script PsiElement(.)('.') Compound regular expression PsiElement(regex begin)('/') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(regex content) + <empty list> GString injection PsiElement($)('$') Closable block @@ -32,6 +35,9 @@ Groovy script Reference expression PsiElement(identifier)('a') PsiElement(})('}') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(regex content) + <empty list> PsiElement(regex end)('/') PsiElement(.)('.') Compound regular expression @@ -42,4 +48,7 @@ Groovy script PsiElement($)('$') Reference expression PsiElement(identifier)('g') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement($/ regex content) + <empty list> PsiElement($/ regex end)('/$')
\ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashyEof.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashyEof.test index fd25456c4b83..11225a164998 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashyEof.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashyEof.test @@ -13,5 +13,8 @@ Groovy script Literal GroovyASTPsiElementImpl($/ regex literal) PsiElement($/ regex begin)('$/') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement($/ regex content) + <empty list> PsiErrorElement:Dollar slash ending expected <empty list>
\ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex10.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex10.test index d0647051ea3e..c4658dfa217d 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex10.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex10.test @@ -38,6 +38,9 @@ Groovy script Reference expression PsiElement(identifier)('b') PsiElement(})('}') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(Gstring content) + <empty list> PsiElement(Gstring end)('"') PsiElement(})('}') GrStringContentImpl(GString content element) diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex16.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex16.test index b05b726d84a8..afe512535929 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex16.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex16.test @@ -3,9 +3,15 @@ Groovy script Compound regular expression PsiElement(regex begin)('/') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(regex content) + <empty list> GString injection PsiElement($)('$') PsiErrorElement:Identifier or code block expected <empty list> + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(regex content) + <empty list> PsiErrorElement:Regex ending expected <empty list>
\ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex20.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex20.test index e275546ae4bb..b5d112573546 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex20.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex20.test @@ -20,5 +20,8 @@ Groovy script Literal PsiElement(Integer)('2') PsiElement(})('}') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(regex content) + <empty list> PsiElement(regex end)('/') PsiElement())(')')
\ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex22.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex22.test index f13ddd70ad61..34a45ff5fcf1 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex22.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex22.test @@ -3,6 +3,9 @@ Groovy script Compound regular expression PsiElement(regex begin)('/') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(regex content) + <empty list> GString injection PsiElement($)('$') Closable block @@ -12,6 +15,9 @@ Groovy script Literal PsiElement(Integer)('1') PsiElement(})('}') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(regex content) + <empty list> GString injection PsiElement($)('$') Closable block @@ -21,4 +27,7 @@ Groovy script Literal PsiElement(Integer)('2') PsiElement(})('}') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(regex content) + <empty list> PsiElement(regex end)('/')
\ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex23.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex23.test index 00e27cd6ae22..725c940c2f2d 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex23.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex23.test @@ -3,6 +3,9 @@ $/${1}${2}/$ Groovy script Compound regular expression PsiElement($/ regex begin)('$/') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement($/ regex content) + <empty list> GString injection PsiElement($)('$') Closable block @@ -12,6 +15,9 @@ Groovy script Literal PsiElement(Integer)('1') PsiElement(})('}') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement($/ regex content) + <empty list> GString injection PsiElement($)('$') Closable block @@ -21,4 +27,7 @@ Groovy script Literal PsiElement(Integer)('2') PsiElement(})('}') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement($/ regex content) + <empty list> PsiElement($/ regex end)('/$')
\ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex8.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex8.test index 92c95df6163c..e93ba9b41268 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex8.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex8.test @@ -39,6 +39,9 @@ Groovy script Reference expression PsiElement(identifier)('b') PsiElement(})('}') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(Gstring content) + <empty list> PsiElement(Gstring end)('"') PsiElement(})('}') GrStringContentImpl(GString content element) diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex9.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex9.test index 94e1bb1fbce7..437e647a1229 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex9.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex9.test @@ -40,6 +40,9 @@ Groovy script Reference expression PsiElement(identifier)('b') PsiElement(})('}') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(Gstring content) + <empty list> PsiElement(Gstring end)('"') PsiElement(})('}') GrStringContentImpl(GString content element) diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/special/map5.test b/plugins/groovy/testdata/parsing/groovy/expressions/special/map5.test index 4846811bff19..44036dbd7de5 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/special/map5.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/special/map5.test @@ -7,6 +7,9 @@ Groovy script Argument label Compound Gstring PsiElement(Gstring begin)('"') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(Gstring content) + <empty list> GString injection PsiElement($)('$') Reference expression @@ -21,6 +24,9 @@ Groovy script PsiWhiteSpace(' ') Compound Gstring PsiElement(Gstring begin)('"') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(Gstring content) + <empty list> GString injection PsiElement($)('$') Reference expression diff --git a/plugins/groovy/testdata/parsing/groovy/statements/blocks/clos3.test b/plugins/groovy/testdata/parsing/groovy/statements/blocks/clos3.test index 35bc8311b51b..f592aba3901d 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/blocks/clos3.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/blocks/clos3.test @@ -39,6 +39,9 @@ Groovy script Literal PsiElement(Integer)('3') PsiElement(})('}') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(Gstring content) + <empty list> PsiErrorElement:String end expected <empty list> PsiElement(new line)('\n ') @@ -48,5 +51,8 @@ Groovy script Command arguments Compound Gstring PsiElement(Gstring begin)('"""') + GrStringContentImpl(GString content element) + ASTWrapperPsiElement(Gstring content) + <empty list> PsiErrorElement:String end expected <empty list>
\ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/pullUp/DocCommentInMethod.groovy b/plugins/groovy/testdata/refactoring/pullUp/DocCommentInMethod.groovy new file mode 100644 index 000000000000..6eff8a1dd94a --- /dev/null +++ b/plugins/groovy/testdata/refactoring/pullUp/DocCommentInMethod.groovy @@ -0,0 +1,9 @@ +class Super { +} + +class Foo extends Super { + /** + * doc + */ + def fo<caret>o() {} +} diff --git a/plugins/groovy/testdata/refactoring/pullUp/DocCommentInMethod_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/DocCommentInMethod_after.groovy new file mode 100644 index 000000000000..d68f5fdd63cb --- /dev/null +++ b/plugins/groovy/testdata/refactoring/pullUp/DocCommentInMethod_after.groovy @@ -0,0 +1,11 @@ +class Super { + + /** + * doc + */ + def foo() {} +} + +class Foo extends Super { + +} diff --git a/plugins/groovy/testdata/refactoring/pullUp/ImplementsList1.groovy b/plugins/groovy/testdata/refactoring/pullUp/ImplementsList1.groovy new file mode 100644 index 000000000000..ef1ca5f73e1d --- /dev/null +++ b/plugins/groovy/testdata/refactoring/pullUp/ImplementsList1.groovy @@ -0,0 +1,6 @@ +interface I1 {} +interface I2 {} + +class Super {} + +class Foo extends Super impleme<caret>nts I1, I2 {}
\ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/pullUp/ImplementsList1_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/ImplementsList1_after.groovy new file mode 100644 index 000000000000..c19959bc231f --- /dev/null +++ b/plugins/groovy/testdata/refactoring/pullUp/ImplementsList1_after.groovy @@ -0,0 +1,6 @@ +interface I1 {} +interface I2 {} + +class Super implements I1 {} + +class Foo extends Super implements I2 {}
\ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/pullUp/ImplementsList2.groovy b/plugins/groovy/testdata/refactoring/pullUp/ImplementsList2.groovy new file mode 100644 index 000000000000..4b93cd12d08f --- /dev/null +++ b/plugins/groovy/testdata/refactoring/pullUp/ImplementsList2.groovy @@ -0,0 +1,6 @@ +interface I1 {} +interface I2 {} + +class Super {} + +class Foo extends Super imp<caret>lements I1, I2 {}
\ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/pullUp/ImplementsList2_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/ImplementsList2_after.groovy new file mode 100644 index 000000000000..d6c79355b72d --- /dev/null +++ b/plugins/groovy/testdata/refactoring/pullUp/ImplementsList2_after.groovy @@ -0,0 +1,6 @@ +interface I1 {} +interface I2 {} + +class Super implements I2 {} + +class Foo extends Super implements I1 {}
\ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/pullUp/ImplementsList3.groovy b/plugins/groovy/testdata/refactoring/pullUp/ImplementsList3.groovy new file mode 100644 index 000000000000..6208d4438ae0 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/pullUp/ImplementsList3.groovy @@ -0,0 +1,6 @@ +interface I1 {} +interface I2 {} + +class Super {} + +class Foo extends Super impl<caret>ements I1, I2 {}
\ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/pullUp/ImplementsList3_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/ImplementsList3_after.groovy new file mode 100644 index 000000000000..3165cdf5c6de --- /dev/null +++ b/plugins/groovy/testdata/refactoring/pullUp/ImplementsList3_after.groovy @@ -0,0 +1,6 @@ +interface I1 {} +interface I2 {} + +class Super implements I1, I2 {} + +class Foo extends Super {}
\ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/pullUp/Supers.groovy b/plugins/groovy/testdata/refactoring/pullUp/Supers.groovy new file mode 100644 index 000000000000..4bc630e8f56a --- /dev/null +++ b/plugins/groovy/testdata/refactoring/pullUp/Supers.groovy @@ -0,0 +1,8 @@ +class SuperClass { + def foo() {} +} +class SuubClass extends SuperClass { + def ba<caret>r() { + super.foo() + } +}
\ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/pullUp/Supers_after.groovy b/plugins/groovy/testdata/refactoring/pullUp/Supers_after.groovy new file mode 100644 index 000000000000..7e53e8f68a1d --- /dev/null +++ b/plugins/groovy/testdata/refactoring/pullUp/Supers_after.groovy @@ -0,0 +1,9 @@ +class SuperClass { + def foo() {} + + def bar() { + foo() + } +} +class SuubClass extends SuperClass { +}
\ No newline at end of file diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java index 27ec978229e8..a3fa9e4e9e9a 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java @@ -28,6 +28,8 @@ import com.intellij.openapi.vcs.changes.ChangeListManagerImpl; import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.AppUIUtil; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.VcsBackgroundTask; import com.intellij.vcsUtil.VcsUtil; @@ -149,8 +151,14 @@ public class HgVFSListener extends VcsVFSListener { Collection<VirtualFile> unversionedAndIgnoredFiles = new ArrayList<VirtualFile>(); final Map<VirtualFile, Collection<VirtualFile>> sortedSourceFilesByRepos = HgUtil.sortByHgRoots(myProject, copyFromMap.values()); HgStatusCommand statusCommand = new HgStatusCommand.Builder(false).unknown(true).ignored(true).build(myProject); - for (VirtualFile repo : sortedSourceFilesByRepos.keySet()) { - Set<HgChange> changes = statusCommand.execute(repo); + for (Map.Entry<VirtualFile, Collection<VirtualFile>> entry : sortedSourceFilesByRepos.entrySet()) { + Set<HgChange> changes = + statusCommand.execute(entry.getKey(), ContainerUtil.map(entry.getValue(), new Function<VirtualFile, FilePath>() { + @Override + public FilePath fun(VirtualFile virtualFile) { + return new FilePathImpl(virtualFile); + } + })); for (HgChange change : changes) { unversionedAndIgnoredFiles.add(change.afterFile().toFilePath().getVirtualFile()); } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractFilesAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractFilesAction.java index 82e8489074a9..4856f6ee7eb8 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractFilesAction.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractFilesAction.java @@ -40,8 +40,8 @@ abstract class HgAbstractFilesAction extends AnAction { public final void actionPerformed(AnActionEvent event) { final DataContext dataContext = event.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); - final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); + final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); if (project == null || files == null || files.length == 0) { return; } @@ -73,13 +73,13 @@ abstract class HgAbstractFilesAction extends AnAction { Presentation presentation = e.getPresentation(); final DataContext dataContext = e.getDataContext(); - Project project = PlatformDataKeys.PROJECT.getData(dataContext); + Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null) { presentation.setEnabled(false); return; } - VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); + VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); if (files == null || files.length == 0) { presentation.setEnabled(false); return; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java index 0d10c44fe237..5f75011929d6 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java @@ -14,6 +14,7 @@ package org.zmlx.hg4idea.action; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; @@ -42,11 +43,11 @@ abstract class HgAbstractGlobalAction extends AnAction { public void actionPerformed(AnActionEvent event) { final DataContext dataContext = event.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null) { return; } - VirtualFile file = event.getData(PlatformDataKeys.VIRTUAL_FILE); + VirtualFile file = event.getData(CommonDataKeys.VIRTUAL_FILE); VirtualFile repo = file != null ? HgUtil.getHgRootOrNull(project, file) : null; List<VirtualFile> repos = HgUtil.getHgRepositories(project); if (!repos.isEmpty()) { @@ -87,7 +88,7 @@ abstract class HgAbstractGlobalAction extends AnAction { } public static boolean isEnabled(AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) { return false; } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAction.java index 1e90bb5b2a3e..6660d104f49e 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAction.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAction.java @@ -17,6 +17,7 @@ package org.zmlx.hg4idea.action; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; @@ -40,11 +41,11 @@ public abstract class HgAction extends AnAction { @Override public void actionPerformed(AnActionEvent event) { final DataContext dataContext = event.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null) { return; } - VirtualFile file = event.getData(PlatformDataKeys.VIRTUAL_FILE); + VirtualFile file = event.getData(CommonDataKeys.VIRTUAL_FILE); VirtualFile repo = file != null ? HgUtil.getHgRootOrNull(project, file) : null; execute(project, repo); } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgInit.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgInit.java index 882a72a9c645..27346660015b 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgInit.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgInit.java @@ -1,6 +1,7 @@ package org.zmlx.hg4idea.action; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; @@ -34,7 +35,7 @@ public class HgInit extends DumbAwareAction { @Override public void actionPerformed(AnActionEvent e) { - myProject = e.getData(PlatformDataKeys.PROJECT); + myProject = e.getData(CommonDataKeys.PROJECT); if (myProject == null) { myProject = ProjectManager.getInstance().getDefaultProject(); } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgLogCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgLogCommand.java index c25a93f68155..2e98bcba2063 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgLogCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgLogCommand.java @@ -14,6 +14,7 @@ package org.zmlx.hg4idea.command; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.changes.ChangeListManager; @@ -29,7 +30,9 @@ import org.zmlx.hg4idea.execution.HgCommandExecutor; import org.zmlx.hg4idea.execution.HgCommandResult; import org.zmlx.hg4idea.util.HgChangesetUtil; import org.zmlx.hg4idea.util.HgUtil; +import org.zmlx.hg4idea.util.HgVersion; +import java.io.File; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; @@ -66,6 +69,8 @@ public class HgLogCommand { private boolean myIncludeRemoved; private boolean myFollowCopies; private boolean myLogFile = true; + private boolean myBuiltInSupported = false; + private boolean myLargeFilesWithFollowSupported = false; public void setIncludeRemoved(boolean includeRemoved) { myIncludeRemoved = includeRemoved; @@ -81,6 +86,14 @@ public class HgLogCommand { public HgLogCommand(@NotNull Project project) { myProject = project; + HgVcs vcs = HgVcs.getInstance(myProject); + if (vcs == null) { + LOG.info("Vcs couldn't be null for project"); + return; + } + HgVersion version = vcs.getVersion(); + myBuiltInSupported = version.isBuiltInFunctionSupported(); + myLargeFilesWithFollowSupported = version.isLargeFilesWithFollowSupported(); } /** @@ -101,16 +114,12 @@ public class HgLogCommand { String template; boolean shouldParseOldTemplate = false; - HgVcs vcs = HgVcs.getInstance(myProject); - if (vcs == null) { - LOG.info("Vcs couldn't be null for project"); - return Collections.emptyList(); - } + if (!includeFiles) { template = HgChangesetUtil.makeTemplate(SHORT_TEMPLATE_ITEMS); } else { - if (!vcs.getVersion().isBuildInFunctionSupported()) { + if (!myBuiltInSupported) { template = HgChangesetUtil.makeTemplate(LONG_TEMPLATE_FOR_OLD_VERSIONS); shouldParseOldTemplate = true; } @@ -123,8 +132,7 @@ public class HgLogCommand { FilePath originalFileName = HgUtil.getOriginalFileName(hgFile.toFilePath(), ChangeListManager.getInstance(myProject)); HgFile originalHgFile = new HgFile(hgFile.getRepo(), originalFileName); - HgCommandResult result = - execute(hgFile.getRepo(), template, limit, originalHgFile, argsForCmd, vcs.getVersion().isLargeFilesWithFollowSupported()); + HgCommandResult result = execute(hgFile.getRepo(), template, limit, originalHgFile, argsForCmd); final List<HgFileRevision> revisions = new LinkedList<HgFileRevision>(); if (result == null) { @@ -231,7 +239,7 @@ public class HgLogCommand { @Nullable private HgCommandResult execute(@NotNull VirtualFile repo, @NotNull String template, int limit, HgFile hgFile, - @Nullable List<String> argsForCmd, boolean largeFilesWithFollowSupported) { + @Nullable List<String> argsForCmd) { List<String> arguments = new LinkedList<String>(); if (myIncludeRemoved) { // There is a bug in mercurial that causes --follow --removed <file> to cause @@ -245,7 +253,7 @@ public class HgLogCommand { arguments.add("--follow"); //workaround: --follow options doesn't work with largefiles extension, so we need to switch off this extension in log command //see http://selenic.com/pipermail/mercurial-devel/2013-May/051209.html fixed since 2.7 - if (!largeFilesWithFollowSupported) { + if (!myLargeFilesWithFollowSupported) { arguments.add("--config"); arguments.add("extensions.largefiles=!"); } @@ -343,4 +351,50 @@ public class HgLogCommand { LOG.info("Unexpected output during parse copied files in log command " + str); return -1; } + + @NotNull + public HgFile getNameThroughCopies(@NotNull final HgFile hgFile, @NotNull HgRevisionNumber vcsRevisionNumber) throws HgCommandException { + String targetName = FileUtil.toSystemIndependentName(hgFile.getRelativePath()); + String revNumber = vcsRevisionNumber.getRevisionNumber(); + if (StringUtil.isEmptyOrSpaces(revNumber)) { + LOG.info("Revision Number shouldn't be empty, may be vcsDirectory mapping problem for: " + hgFile.getRepo().getPath()); + return hgFile; + } + int targetRevNumber = Integer.valueOf(revNumber); + String[] COPIES_TEMPLATE = + myBuiltInSupported + ? new String[]{"{rev}", "{join(file_copies,'" + HgChangesetUtil.FILE_SEPARATOR + "')}"} + : new String[]{"{rev}", "{file_copies}"}; + String template = HgChangesetUtil.makeTemplate(COPIES_TEMPLATE); + HgCommandResult result = execute(hgFile.getRepo(), template, -1, hgFile, Arrays.asList("-r", ".:0")); + if (result == null) { + throw new HgCommandException("Could not execute log command."); + } + + List<String> errors = result.getErrorLines(); + if (errors != null && !errors.isEmpty()) { + throw new HgCommandException(errors.toString()); + } + String output = result.getRawOutput(); + String[] changeSets = output.split(HgChangesetUtil.CHANGESET_SEPARATOR); + for (String line : changeSets) { + String[] attributes = line.split(HgChangesetUtil.ITEM_SEPARATOR); + if (attributes.length != 2) { + continue; + } + + if (Integer.valueOf(attributes[0]) <= targetRevNumber) { + break; + } + Map<String, String> copies = myBuiltInSupported ? parseCopiesFileList(attributes[1]) : parseCopiesFileListAsOldVersion(attributes[1]); + for (Map.Entry<String, String> entry : copies.entrySet()) { + if (entry.getValue().equals(targetName)) { + targetName = entry.getKey(); + break; + } + } + } + VirtualFile root = hgFile.getRepo(); + return new HgFile(root, new File(root.getPath(), targetName)); + } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java index 77e6339e86dd..a0a41ca2744a 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java @@ -23,9 +23,11 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.HgRevisionNumber; +import org.zmlx.hg4idea.action.HgCommandResultNotifier; import org.zmlx.hg4idea.execution.HgCommandExecutor; import org.zmlx.hg4idea.execution.HgCommandResult; import org.zmlx.hg4idea.util.HgChangesetUtil; +import org.zmlx.hg4idea.util.HgErrorUtil; import org.zmlx.hg4idea.util.HgUtil; import java.util.ArrayList; @@ -70,7 +72,7 @@ public class HgWorkingCopyRevisionsCommand { * is the latest parent (i.e. having greater revision number), second one is the earlier parent (having smaller revision number). * @param repo repository to work on. * @param file file which revision's parents we are interested in. If null, the history of the whole repository is considered. - * @param revision revision number which parent is wanted. If null, the last revision is taken. + * @param revision revision number which parent is wanted. If null, the last revision is taken. * @return One or two (in case of a merge commit) parents of the given revision. Or even zero in case of a fresh repository. * So one should check pair elements for null. */ @@ -78,7 +80,7 @@ public class HgWorkingCopyRevisionsCommand { public Pair<HgRevisionNumber, HgRevisionNumber> parents(@NotNull VirtualFile repo, @Nullable VirtualFile file, @Nullable HgRevisionNumber revision) { return parents(repo, ObjectsConvertor.VIRTUAL_FILEPATH.convert(file), revision); } - + /** * @see #parents(VirtualFile, FilePath, HgRevisionNumber) */ @@ -86,13 +88,13 @@ public class HgWorkingCopyRevisionsCommand { public Pair<HgRevisionNumber, HgRevisionNumber> parents(@NotNull VirtualFile repo, @Nullable FilePath file) { return parents(repo, file, null); } - + /** * Parent(s) of the given revision of the given file. If there are two of them (in the case of merge) the first element of the pair * is the latest parent (i.e. having greater revision number), second one is the earlier parent (having smaller revision number). * @param repo repository to work on. * @param file filepath which revision's parents we are interested in. If null, the history of the whole repository is considered. - * @param revision revision number which parent is wanted. If null, the last revision is taken. + * @param revision revision number which parent is wanted. If null, the last revision is taken. * @return One or two (in case of a merge commit) parents of the given revision. Or even zero in case of a fresh repository. * So one should check pair elements for null. */ @@ -161,6 +163,10 @@ public class HgWorkingCopyRevisionsCommand { } } } + if (!result.getRawError().isEmpty() && !HgErrorUtil.isAuthorizationError(result)) { + new HgCommandResultNotifier(myProject).notifyError(result, "identify command failure", HgErrorUtil.MAPPING_ERROR_MASSAGE, + HgErrorUtil.getMappingErrorNotificationListener(myProject)); + } return Pair.create(HgRevisionNumber.NULL_REVISION_NUMBER, null); } @@ -219,8 +225,10 @@ public class HgWorkingCopyRevisionsCommand { } revisions.add(HgRevisionNumber.getInstance(parts.get(0), parts.get(1))); } - + if (!result.getRawError().isEmpty() && !HgErrorUtil.isAuthorizationError(result)) { + new HgCommandResultNotifier(myProject).notifyError(result, "identify command failure", HgErrorUtil.MAPPING_ERROR_MASSAGE, + HgErrorUtil.getMappingErrorNotificationListener(myProject)); + } return revisions; } - } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java index 8d3fc2cd509b..ca3020f06cf0 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java @@ -239,8 +239,9 @@ public final class HgCommandExecutor { final int lastSlashIndex = settings.getHgExecutable().lastIndexOf(File.separator); exeName = settings.getHgExecutable().substring(lastSlashIndex + 1); - final String cmdString = String.format("%s %s %s", exeName, operation, arguments == null ? "" : StringUtil.join(arguments, " ")); - + String str = String.format("%s %s %s", exeName, operation, arguments == null ? "" : StringUtil.join(arguments, " ")); + //remove password from path before log + final String cmdString = myDestination != null ? HgUtil.removePasswordIfNeeded(str) : str; final boolean isUnitTestMode = ApplicationManager.getApplication().isUnitTestMode(); // log command if (isUnitTestMode) { diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryManager.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryManager.java index 3be9436369cd..85bead5d614f 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryManager.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryManager.java @@ -1,7 +1,6 @@ package org.zmlx.hg4idea.repo; import com.intellij.dvcs.repo.AbstractRepositoryManager; -import com.intellij.dvcs.repo.RepositoryManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vfs.VirtualFile; @@ -12,7 +11,7 @@ import org.zmlx.hg4idea.util.HgUtil; /** * @author Nadya Zabrodina */ -public class HgRepositoryManager extends AbstractRepositoryManager<HgRepository> implements RepositoryManager<HgRepository> { +public class HgRepositoryManager extends AbstractRepositoryManager<HgRepository> { public HgRepositoryManager(@NotNull Project project, @NotNull ProjectLevelVcsManager vcsManager) { diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java index 4cadfc86a552..243d1ee82dde 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java @@ -12,14 +12,27 @@ // limitations under the License. package org.zmlx.hg4idea.util; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationListener; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vcs.VcsBundle; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.execution.HgCommandResult; +import javax.swing.event.HyperlinkEvent; import java.util.List; public final class HgErrorUtil { + public static final String SETTINGS_LINK = "settings"; + public static final String MAPPING_ERROR_MASSAGE = String.format( + "Please, ensure that your project base dir is hg root directory or specify full repository path in <a href='" + + SETTINGS_LINK + + "'>directory mappings panel</a>."); + private HgErrorUtil() { } public static boolean isAbort(@Nullable HgCommandResult result) { @@ -66,4 +79,18 @@ public final class HgErrorUtil { } return HgUtil.URL_WITH_PASSWORD.matcher(destinationPath).matches(); } + + @NotNull + public static NotificationListener getMappingErrorNotificationListener(@NotNull final Project project) { + return new NotificationListener.Adapter() { + @Override + protected void hyperlinkActivated(@NotNull Notification notification, + @NotNull HyperlinkEvent e) { + if (SETTINGS_LINK.equals(e.getDescription())) { + ShowSettingsUtil.getInstance() + .showSettingsDialog(project, VcsBundle.message("version.control.main.configurable.name")); + } + } + }; + } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java index ef9cc0188a84..970263ce9170 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java @@ -62,8 +62,6 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static java.util.Map.Entry; - /** * HgUtil is a collection of static utility methods for Mercurial. */ @@ -352,12 +350,12 @@ public abstract class HgUtil { return map; } + @NotNull public static HgFile getFileNameInTargetRevision(@NotNull Project project, @NotNull HgRevisionNumber vcsRevisionNumber, @NotNull HgFile localHgFile) { //change status command execution to log command because the last one is faster, // but need to find file renames manually. - //if virtualFile is null - our parent revision does not contain this file, // so this selected localHgFile comes from selected revision from history and his name is result filename if (localHgFile.toFilePath().getVirtualFile() == null) { @@ -366,37 +364,20 @@ public abstract class HgUtil { HgLogCommand logCommand = new HgLogCommand(project); //--follow could be changed to --branch filter, but the last one is slower logCommand.setFollowCopies(true); - List<HgFileRevision> revisions = Collections.emptyList(); - //mercurial returns file paths depends on command and os. for log command hg uses portable format, so all file path should be with '/'. - //localHgFile have system dependent path, so it should be converted - String targetName = FileUtil.toSystemIndependentName(localHgFile.getRelativePath()); - int targetRevNumber = Integer.valueOf(vcsRevisionNumber.getRevision()); try { //usually when 'compare' 2 revision or 'compare with local' performed the localHgFile - is really local copy, //so we need to get all previous revision from current. // But when 'compare with' called from "get Affected path -> compare with..." then localHgFile is hgFile from selected revision, //so if this name was changed then file is not in parent revision and log command could not follow history. - revisions = logCommand.execute(localHgFile, -1, true, Arrays.asList("-r", ".:0")); + return logCommand.getNameThroughCopies(localHgFile, vcsRevisionNumber); } catch (HgCommandException e) { LOG.warn("Could not find filename in target revision: " + localHgFile.toString(), e); } - for (HgFileRevision revision : revisions) { - if (Integer.valueOf(revision.getRevisionNumber().getRevision()) <= targetRevNumber) { - break; - } - for (Entry<String, String> entry : revision.getCopiedFiles().entrySet()) { - if (entry.getValue().equals(targetName)) { - targetName = entry.getKey(); - } - } - } //todo: fix: when filename comes from another revision and working copy contains another file with the same name, //then 'show diff with local' produce inconvenient behaviour. // todo: fix: If performed 'show diff with local' but there are no selected filename in currant working copy - nothing shows. - - VirtualFile root = localHgFile.getRepo(); - return new HgFile(root, new File(root.getPath(), targetName)); + return localHgFile; } @NotNull diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java index caa32c73fc70..5e758f5465be 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java @@ -47,7 +47,7 @@ public final class HgVersion implements Comparable<HgVersion> { // before 2.3 build in func not supported // since 2.3 - 2.5.3 hg has bug with join function with file_copies // see http://mercurial.808500.n3.nabble.com/Bug-3887-New-hg-log-template-quot-rev-join-file-copies-n-quot-prints-literal-quot-sourcename-quot-fos-td4000129.html - public static final HgVersion BUILD_IN_FUNCTION_SUPPORTED = new HgVersion(2, 6, 0); + public static final HgVersion BUILT_IN_FUNCTION_SUPPORTED = new HgVersion(2, 6, 0); //see http://selenic.com/pipermail/mercurial-devel/2013-May/051209.html fixed since 2.7 private static final HgVersion LARGEFILES_WITH_FOLLOW_SUPPORTED = new HgVersion(2, 7, 0); @@ -116,8 +116,8 @@ public final class HgVersion implements Comparable<HgVersion> { return !isNull() && compareTo(AMEND_SUPPORTED) >= 0; } - public boolean isBuildInFunctionSupported() { - return !isNull() && compareTo(BUILD_IN_FUNCTION_SUPPORTED) >= 0; + public boolean isBuiltInFunctionSupported() { + return !isNull() && compareTo(BUILT_IN_FUNCTION_SUPPORTED) >= 0; } public boolean isLargeFilesWithFollowSupported() { diff --git a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/I18nizeAction.java b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/I18nizeAction.java index 43a649181141..af459ace8b97 100644 --- a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/I18nizeAction.java +++ b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/I18nizeAction.java @@ -56,7 +56,7 @@ public class I18nizeAction extends AnAction { final Editor editor = getEditor(e); if (editor == null) return null; - PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE); + PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE); if (psiFile == null) return null; TextRange range = JavaI18nUtil.getSelectedRange(editor, psiFile); @@ -93,7 +93,7 @@ public class I18nizeAction extends AnAction { } private static Editor getEditor(final AnActionEvent e) { - return PlatformDataKeys.EDITOR.getData(e.getDataContext()); + return CommonDataKeys.EDITOR.getData(e.getDataContext()); } public static void doI18nSelectedString(final @NotNull Project project, @@ -144,7 +144,7 @@ public class I18nizeAction extends AnAction { final Editor editor = getEditor(e); final Project project = editor.getProject(); assert project != null; - final PsiFile psiFile = LangDataKeys.PSI_FILE.getData(e.getDataContext()); + final PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(e.getDataContext()); if (psiFile == null) return; final I18nQuickFixHandler handler = getHandler(e); if (handler == null) return; diff --git a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml index af48a120a277..2d953b7e9539 100644 --- a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml +++ b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml @@ -50,9 +50,7 @@ <renamePsiElementProcessor implementation="org.jetbrains.plugins.javaFX.JavaFxRenameAttributeProcessor" order="before xmlAttribute"/> <completion.contributor implementationClass="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxCompletionContributor" language="XML" order="before xmlNonFirst"/> <manifest.parser.provider implementation="org.jetbrains.plugins.javaFX.manifest.JavaFxManifestHeaderParsers"/> - <!-- <projectWizard.projectCategory implementation="org.jetbrains.plugins.javaFX.JavaFxProjectType"/> - --> </extensions> <actions> diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/actions/OpenInSceneBuilderAction.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/actions/OpenInSceneBuilderAction.java index 061e63714e7a..f41b9be4c614 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/actions/OpenInSceneBuilderAction.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/actions/OpenInSceneBuilderAction.java @@ -22,6 +22,7 @@ import com.intellij.execution.configurations.PathEnvironmentVariableUtil; import com.intellij.execution.process.OSProcessHandler; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.diagnostic.Logger; @@ -56,7 +57,7 @@ public class OpenInSceneBuilderAction extends AnAction { @Override public void actionPerformed(AnActionEvent e) { - final VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE); + final VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE); LOG.assertTrue(virtualFile != null); final String path = virtualFile.getPath(); @@ -150,7 +151,7 @@ public class OpenInSceneBuilderAction extends AnAction { final Presentation presentation = e.getPresentation(); presentation.setEnabled(false); presentation.setVisible(false); - final VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE); + final VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE); if (virtualFile != null && JavaFxFileTypeFactory.isFxml(virtualFile) && e.getProject() != null) { diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxAnnotator.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxAnnotator.java index a348d38c2fdd..0261bd81d421 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxAnnotator.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxAnnotator.java @@ -23,6 +23,7 @@ import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.Annotator; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.markup.GutterIconRenderer; @@ -175,7 +176,7 @@ public class JavaFxAnnotator implements Annotator { return new AnAction() { @Override public void actionPerformed(AnActionEvent e) { - final Editor editor = PlatformDataKeys.EDITOR.getData(e.getDataContext()); + final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); if (editor != null) { XmlChooseColorIntentionAction.chooseColor(editor.getComponent(), myElement, "Color Chooser", true); } diff --git a/plugins/junit/src/com/intellij/execution/junit/AddToTestsPatternAction.java b/plugins/junit/src/com/intellij/execution/junit/AddToTestsPatternAction.java index 3dad8e9d8302..6ac30d98e11d 100644 --- a/plugins/junit/src/com/intellij/execution/junit/AddToTestsPatternAction.java +++ b/plugins/junit/src/com/intellij/execution/junit/AddToTestsPatternAction.java @@ -41,20 +41,20 @@ public class AddToTestsPatternAction extends AnAction { public void actionPerformed(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); final PsiElement[] psiElements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext); - final Set<PsiMember> classes = PatternConfigurationProducer.collectTestMembers(psiElements); + final Set<PsiElement> classes = PatternConfigurationProducer.collectTestMembers(psiElements); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); final List<JUnitConfiguration> patternConfigurations = collectPatternConfigurations(classes, project); if (patternConfigurations.size() == 1) { final JUnitConfiguration configuration = patternConfigurations.get(0); - for (PsiMember aClass : classes) { + for (PsiElement aClass : classes) { configuration.getPersistentData().getPatterns().add(PatternConfigurationProducer.getQName(aClass)); } } else { JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<JUnitConfiguration>("Choose suite to add", patternConfigurations) { @Override public PopupStep onChosen(JUnitConfiguration configuration, boolean finalChoice) { - for (PsiMember aClass : classes) { + for (PsiElement aClass : classes) { configuration.getPersistentData().getPatterns().add(PatternConfigurationProducer.getQName(aClass)); } return FINAL_CHOICE; @@ -81,9 +81,9 @@ public class AddToTestsPatternAction extends AnAction { final DataContext dataContext = e.getDataContext(); final PsiElement[] psiElements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext); if (psiElements != null) { - final Set<PsiMember> foundMembers = PatternConfigurationProducer.collectTestMembers(psiElements); + final Set<PsiElement> foundMembers = PatternConfigurationProducer.collectTestMembers(psiElements); if (foundMembers.isEmpty()) return; - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project != null) { final List<JUnitConfiguration> foundConfigurations = collectPatternConfigurations(foundMembers, project); if (!foundConfigurations.isEmpty()) { @@ -96,7 +96,7 @@ public class AddToTestsPatternAction extends AnAction { } } - private static List<JUnitConfiguration> collectPatternConfigurations(Set<PsiMember> foundClasses, Project project) { + private static List<JUnitConfiguration> collectPatternConfigurations(Set<PsiElement> foundClasses, Project project) { final List<RunConfiguration> configurations = RunManager.getInstance(project).getConfigurationsList( JUnitConfigurationType.getInstance()); final List<JUnitConfiguration> foundConfigurations = new ArrayList<JUnitConfiguration>(); diff --git a/plugins/junit/src/com/intellij/execution/junit/AllInPackageConfigurationProducer.java b/plugins/junit/src/com/intellij/execution/junit/AllInPackageConfigurationProducer.java index d7fc2821a287..4958c15ee4f2 100644 --- a/plugins/junit/src/com/intellij/execution/junit/AllInPackageConfigurationProducer.java +++ b/plugins/junit/src/com/intellij/execution/junit/AllInPackageConfigurationProducer.java @@ -43,6 +43,6 @@ public class AllInPackageConfigurationProducer extends JUnitConfigurationProduce @Override public boolean isPreferredConfiguration(ConfigurationFromContext self, ConfigurationFromContext other) { - return !other.isProducedBy(AllInDirectoryConfigurationProducer.class); + return !other.isProducedBy(AllInDirectoryConfigurationProducer.class) && !other.isProducedBy(PatternConfigurationProducer.class); } } diff --git a/plugins/junit/src/com/intellij/execution/junit/ExcludeFromRunAction.java b/plugins/junit/src/com/intellij/execution/junit/ExcludeFromRunAction.java index 3188508da3d0..c799b4888336 100644 --- a/plugins/junit/src/com/intellij/execution/junit/ExcludeFromRunAction.java +++ b/plugins/junit/src/com/intellij/execution/junit/ExcludeFromRunAction.java @@ -38,7 +38,7 @@ public class ExcludeFromRunAction extends AnAction{ @Override public void actionPerformed(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); LOG.assertTrue(project != null); final JUnitConfiguration configuration = (JUnitConfiguration)RunConfiguration.DATA_KEY.getData(dataContext); LOG.assertTrue(configuration != null); @@ -54,7 +54,7 @@ public class ExcludeFromRunAction extends AnAction{ final Presentation presentation = e.getPresentation(); presentation.setVisible(false); final DataContext dataContext = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project != null) { final RunConfiguration configuration = RunConfiguration.DATA_KEY.getData(dataContext); if (configuration instanceof JUnitConfiguration) { diff --git a/plugins/junit/src/com/intellij/execution/junit/PatternConfigurationProducer.java b/plugins/junit/src/com/intellij/execution/junit/PatternConfigurationProducer.java index 93cad47668a4..633f31adca37 100644 --- a/plugins/junit/src/com/intellij/execution/junit/PatternConfigurationProducer.java +++ b/plugins/junit/src/com/intellij/execution/junit/PatternConfigurationProducer.java @@ -19,9 +19,9 @@ package com.intellij.execution.junit; import com.intellij.execution.JavaExecutionUtil; import com.intellij.execution.actions.ConfigurationContext; import com.intellij.execution.configurations.ModuleBasedConfiguration; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.module.Module; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; @@ -66,8 +66,8 @@ public class PatternConfigurationProducer extends JUnitConfigurationProducer { }); } - static Set<PsiMember> collectTestMembers(PsiElement[] psiElements) { - final Set<PsiMember> foundMembers = new LinkedHashSet<PsiMember>(); + static Set<PsiElement> collectTestMembers(PsiElement[] psiElements) { + final Set<PsiElement> foundMembers = new LinkedHashSet<PsiElement>(); for (PsiElement psiElement : psiElements) { if (psiElement instanceof PsiClassOwner) { final PsiClass[] classes = ((PsiClassOwner)psiElement).getClasses(); @@ -78,11 +78,16 @@ public class PatternConfigurationProducer extends JUnitConfigurationProducer { } } else if (psiElement instanceof PsiClass) { if (JUnitUtil.isTestClass((PsiClass)psiElement)) { - foundMembers.add((PsiClass)psiElement); + foundMembers.add(psiElement); } } else if (psiElement instanceof PsiMethod) { if (JUnitUtil.getTestMethod(psiElement) != null) { - foundMembers.add((PsiMethod)psiElement); + foundMembers.add(psiElement); + } + } else if (psiElement instanceof PsiDirectory) { + final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory)psiElement); + if (aPackage != null) { + foundMembers.add(aPackage); } } } @@ -102,19 +107,19 @@ public class PatternConfigurationProducer extends JUnitConfigurationProducer { final DataContext dataContext = context.getDataContext(); PsiElement[] elements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext); if (elements != null) { - for (PsiMember psiClass : collectTestMembers(elements)) { + for (PsiElement psiClass : collectTestMembers(elements)) { classes.add(getQName(psiClass)); } return elements; } else { - final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); + final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); if (files != null) { final List<PsiFile> psiFiles = new ArrayList<PsiFile>(); final PsiManager psiManager = PsiManager.getInstance(context.getProject()); for (VirtualFile file : files) { final PsiFile psiFile = psiManager.findFile(file); if (psiFile instanceof PsiClassOwner) { - for (PsiMember psiMember : collectTestMembers(((PsiClassOwner)psiFile).getClasses())) { + for (PsiElement psiMember : collectTestMembers(((PsiClassOwner)psiFile).getClasses())) { classes.add(((PsiClass)psiMember).getQualifiedName()); } psiFiles.add(psiFile); @@ -126,13 +131,17 @@ public class PatternConfigurationProducer extends JUnitConfigurationProducer { return null; } - public static String getQName(PsiMember psiMember) { + public static String getQName(PsiElement psiMember) { if (psiMember instanceof PsiClass) { return ((PsiClass)psiMember).getQualifiedName(); } - else { - return psiMember.getContainingClass().getQualifiedName() + "," + psiMember.getName(); + else if (psiMember instanceof PsiMember) { + return ((PsiMember)psiMember).getContainingClass().getQualifiedName() + "," + ((PsiMember)psiMember).getName(); + } else if (psiMember instanceof PsiPackage) { + return ((PsiPackage)psiMember).getQualifiedName(); } + assert false; + return null; } @Override diff --git a/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java b/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java index 6a8b52809b6a..bffa0403e26c 100644 --- a/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java +++ b/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java @@ -328,8 +328,12 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven try { // copied from DefaultMavenProjectBuilder.buildWithDependencies ProjectBuilder builder = getComponent(ProjectBuilder.class); - ProjectBuildingResult buildingResult = builder.build(new File(file.getPath()), request.getProjectBuildingRequest()); - //builder.calculateConcreteState(project, config, false); + + // Don't use build(File projectFile, ProjectBuildingRequest request) , because it don't use cache !!!!!!!! (see http://devnet.jetbrains.com/message/5500218) + List<ProjectBuildingResult> results = + builder.build(Collections.singletonList(new File(file.getPath())), false, request.getProjectBuildingRequest()); + + ProjectBuildingResult buildingResult = results.get(0); MavenProject project = buildingResult.getProject(); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenPomXmlCompletionTagListenerContributor.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenPomXmlCompletionTagListenerContributor.java index 142e47a93552..c0880648f470 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenPomXmlCompletionTagListenerContributor.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenPomXmlCompletionTagListenerContributor.java @@ -1,9 +1,11 @@ package org.jetbrains.idea.maven.dom.model.completion; import com.google.common.collect.ImmutableSet; +import com.intellij.codeInsight.actions.ReformatCodeProcessor; import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementDecorator; +import com.intellij.openapi.editor.CaretModel; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; @@ -26,16 +28,6 @@ public class MavenPomXmlCompletionTagListenerContributor extends CompletionContr private final Set<String> myHandledTags = ImmutableSet.of("dependency"); - //private final MultiMap<String, TagInsertListener> myListenersMap; - //{ - // MultiMap<String, TagInsertListener> listenersMap = new MultiMap<String, TagInsertListener>(); - // for (TagInsertListener listener : new TagInsertListener[]{}) { - // - // } - // - // myListenersMap = listenersMap; - //} - @Override public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) { PsiFile psiFile = parameters.getOriginalFile(); @@ -64,17 +56,20 @@ public class MavenPomXmlCompletionTagListenerContributor extends CompletionContr && "maven-4.0.0.xsd".equals(((XmlTag)object).getContainingFile().getName())) { context.commitDocument(); - PsiElement psiElement = context.getFile().findElementAt(context.getEditor().getCaretModel().getOffset()); + CaretModel caretModel = context.getEditor().getCaretModel(); + + PsiElement psiElement = context.getFile().findElementAt(caretModel.getOffset()); XmlTag xmlTag = PsiTreeUtil.getParentOfType(psiElement, XmlTag.class); if (xmlTag != null) { DomElement domElement = DomManager.getDomManager(context.getProject()).getDomElement(xmlTag); if (domElement instanceof MavenDomDependency) { - context.setLaterRunnable(new Runnable() { - @Override - public void run() { - new CodeCompletionHandlerBase(CompletionType.BASIC).invokeCompletion(context.getProject(), context.getEditor()); - } - }); + String s = "\n<groupId></groupId>\n<artifactId></artifactId>\n"; + context.getDocument().insertString(caretModel.getOffset(), s); + caretModel.moveToOffset(caretModel.getOffset() + s.length() - "</artifactId>\n".length()); + + context.commitDocument(); + + new ReformatCodeProcessor(context.getProject(), context.getFile(), xmlTag.getTextRange(), true).run(); } } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/MavenPropertyRenameHandler.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/MavenPropertyRenameHandler.java index 87de799bc1d8..c5aa13f1c289 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/MavenPropertyRenameHandler.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/MavenPropertyRenameHandler.java @@ -15,6 +15,7 @@ */ package org.jetbrains.idea.maven.dom.refactorings; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -45,7 +46,7 @@ public class MavenPropertyRenameHandler extends PsiElementRenameHandler { PsiElement element = elements.length == 1 ? elements[0] : null; if (element == null) element = findTarget(dataContext); - RenameDialog dialog = new RenameDialog(project, element, null, PlatformDataKeys.EDITOR.getData(dataContext)); + RenameDialog dialog = new RenameDialog(project, element, null, CommonDataKeys.EDITOR.getData(dataContext)); if (ApplicationManager.getApplication().isUnitTestMode()) { String name = DEFAULT_NAME.getData(dataContext); dialog.performRename(name); @@ -57,6 +58,6 @@ public class MavenPropertyRenameHandler extends PsiElementRenameHandler { } private static PsiElement findTarget(DataContext context) { - return MavenTargetUtil.getRefactorTarget(PlatformDataKeys.EDITOR.getData(context), LangDataKeys.PSI_FILE.getData(context)); + return MavenTargetUtil.getRefactorTarget(CommonDataKeys.EDITOR.getData(context), CommonDataKeys.PSI_FILE.getData(context)); } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java index be9ebda42a54..837c19e0b8f8 100755 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java @@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.impl.ModifiableModelCommitter; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.util.ArrayUtil; import com.intellij.util.PairConsumer; import com.intellij.util.containers.LinkedMultiMap; @@ -153,8 +154,8 @@ public class MavenFoldersImporter { private void addSourceFolderIfNotOverlap(String path, JpsModuleSourceRootType<?> type, List<String> addedPaths) { String canonicalPath = myModel.toPath(path).getPath(); for (String existing : addedPaths) { - if (MavenRootModelAdapter.isEqualOrAncestor(existing, canonicalPath) - || MavenRootModelAdapter.isEqualOrAncestor(canonicalPath, existing)) { + if (VfsUtilCore.isEqualOrAncestor(existing, canonicalPath) + || VfsUtilCore.isEqualOrAncestor(canonicalPath, existing)) { return; } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java index 87d5f5e64abe..e3a42a5b036d 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java @@ -25,8 +25,8 @@ import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.pom.java.LanguageLevel; import com.intellij.util.Processor; @@ -81,7 +81,7 @@ public class MavenRootModelAdapter { private ContentEntry getContentRootFor(Url url) { for (ContentEntry e : myRootModel.getContentEntries()) { - if (isEqualOrAncestor(e.getUrl(), url.getUrl())) return e; + if (VfsUtilCore.isEqualOrAncestor(e.getUrl(), url.getUrl())) return e; } return null; } @@ -155,7 +155,7 @@ public class MavenRootModelAdapter { String url = toUrl(f.getPath()).getUrl(); for (ContentEntry eachEntry : myRootModel.getContentEntries()) { for (SourceFolder eachFolder : eachEntry.getSourceFolders()) { - if (isEqualOrAncestor(url, eachFolder.getUrl())) return true; + if (VfsUtilCore.isEqualOrAncestor(url, eachFolder.getUrl())) return true; } } return false; @@ -165,16 +165,12 @@ public class MavenRootModelAdapter { String url = toUrl(f.getPath()).getUrl(); for (ContentEntry eachEntry : myRootModel.getContentEntries()) { for (ExcludeFolder eachFolder : eachEntry.getExcludeFolders()) { - if (isEqualOrAncestor(eachFolder.getUrl(), url)) return true; + if (VfsUtilCore.isEqualOrAncestor(eachFolder.getUrl(), url)) return true; } } return false; } - public static boolean isEqualOrAncestor(String ancestor, String child) { - return ancestor.equals(child) || StringUtil.startsWithConcatenation(child, ancestor, "/"); - } - private boolean exists(String path) { return new File(toPath(path).getPath()).exists(); } @@ -196,7 +192,7 @@ public class MavenRootModelAdapter { for (SourceFolder eachFolder : eachEntry.getSourceFolders()) { String ancestor = under ? url.getUrl() : eachFolder.getUrl(); String child = under ? eachFolder.getUrl() : url.getUrl(); - if (isEqualOrAncestor(ancestor, child)) { + if (VfsUtilCore.isEqualOrAncestor(ancestor, child)) { eachEntry.removeSourceFolder(eachFolder); } } @@ -206,7 +202,7 @@ public class MavenRootModelAdapter { String ancestor = under ? url.getUrl() : eachFolder.getUrl(); String child = under ? eachFolder.getUrl() : url.getUrl(); - if (isEqualOrAncestor(ancestor, child)) { + if (VfsUtilCore.isEqualOrAncestor(ancestor, child)) { if (eachFolder.isSynthetic()) { getCompilerExtension().setExcludeOutput(false); } @@ -225,7 +221,7 @@ public class MavenRootModelAdapter { for (SourceFolder eachFolder : eachEntry.getSourceFolders()) { String ancestor = url.getUrl(); String child = eachFolder.getUrl(); - if (isEqualOrAncestor(ancestor, child) || isEqualOrAncestor(child, ancestor)) { + if (VfsUtilCore.isEqualOrAncestor(ancestor, child) || VfsUtilCore.isEqualOrAncestor(child, ancestor)) { return true; } } @@ -234,7 +230,7 @@ public class MavenRootModelAdapter { String ancestor = url.getUrl(); String child = eachFolder.getUrl(); - if (isEqualOrAncestor(ancestor, child) || isEqualOrAncestor(child, ancestor)) { + if (VfsUtilCore.isEqualOrAncestor(ancestor, child) || VfsUtilCore.isEqualOrAncestor(child, ancestor)) { return true; } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndicesManager.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndicesManager.java index 5ede2581b2cd..4ac8b34168c4 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndicesManager.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndicesManager.java @@ -24,8 +24,6 @@ import com.intellij.openapi.progress.BackgroundTaskQueue; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; @@ -48,7 +46,7 @@ import java.io.File; import java.io.IOException; import java.util.*; -public class MavenIndicesManager { +public class MavenIndicesManager implements Disposable { private static final String ELEMENT_ARCHETYPES = "archetypes"; private static final String ELEMENT_ARCHETYPE = "archetype"; private static final String ELEMENT_GROUP_ID = "groupId"; @@ -112,12 +110,6 @@ public class MavenIndicesManager { } }); - Disposer.register(ApplicationManager.getApplication(), new Disposable() { - public void dispose() { - doShutdown(); - } - }); - loadUserArchetypes(); } @@ -127,7 +119,7 @@ public class MavenIndicesManager { : myTestIndicesDir; } - public void disposeComponent() { + public void dispose() { doShutdown(); if (ApplicationManager.getApplication().isUnitTestMode()) { FileUtil.delete(getIndicesDir()); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigator.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigator.java index 03135609730f..d7438b22f03c 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigator.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigator.java @@ -15,11 +15,15 @@ */ package org.jetbrains.idea.maven.navigator; +import com.intellij.execution.RunManager; import com.intellij.execution.RunManagerAdapter; import com.intellij.execution.RunManagerEx; +import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.ide.util.treeView.TreeState; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.CommonShortcuts; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.PersistentStateComponent; @@ -40,6 +44,7 @@ import com.intellij.ui.treeStructure.SimpleTree; import com.intellij.util.containers.ContainerUtil; import icons.MavenIcons; import org.jdom.Element; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.TestOnly; import org.jetbrains.idea.maven.execution.MavenRunner; import org.jetbrains.idea.maven.execution.MavenRunnerSettings; @@ -236,12 +241,42 @@ public class MavenProjectsNavigator extends MavenSimpleProjectComponent implemen }); } }); + + ((RunManagerEx)RunManager.getInstance(myProject)).addRunManagerListener(new RunManagerAdapter() { + private void changed() { + scheduleStructureRequest(new Runnable() { + public void run() { + myStructure.updateRunConfigurations(); + } + }); + } + + @Override + public void runConfigurationAdded(@NotNull RunnerAndConfigurationSettings settings) { + changed(); + } + + @Override + public void runConfigurationRemoved(@NotNull RunnerAndConfigurationSettings settings) { + changed(); + } + + @Override + public void runConfigurationChanged(@NotNull RunnerAndConfigurationSettings settings) { + changed(); + } + }); } private void initToolWindow() { initTree(); JPanel panel = new MavenProjectsNavigatorPanel(myProject, myTree); + AnAction removeAction = ActionManager.getInstance().getAction("Maven.RemoveRunConfiguration"); + removeAction.registerCustomShortcutSet(CommonShortcuts.getDelete(), myTree, myProject); + AnAction editSource = ActionManager.getInstance().getAction("Maven.EditRunConfiguration"); + editSource.registerCustomShortcutSet(CommonShortcuts.getEditSource(), myTree, myProject); + final ToolWindowManagerEx manager = ToolWindowManagerEx.getInstanceEx(myProject); myToolWindow = (ToolWindowEx)manager.registerToolWindow(TOOL_WINDOW_ID, panel, ToolWindowAnchor.RIGHT, myProject, true); myToolWindow.setIcon(MavenIcons.ToolWindowMaven); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java index 69cd93efab2a..525f0e74b3d7 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java @@ -16,6 +16,7 @@ package org.jetbrains.idea.maven.navigator; import com.intellij.execution.Location; +import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.ide.dnd.FileCopyPasteUtil; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.Project; @@ -28,6 +29,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.ui.PopupHandler; import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.treeStructure.SimpleNode; import com.intellij.ui.treeStructure.SimpleTree; import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashMap; @@ -125,15 +127,16 @@ public class MavenProjectsNavigatorPanel extends SimpleToolWindowPanel implement public Object getData(@NonNls String dataId) { if (PlatformDataKeys.HELP_ID.is(dataId)) return "reference.toolWindows.mavenProjects"; - if (PlatformDataKeys.PROJECT.is(dataId)) return myProject; + if (CommonDataKeys.PROJECT.is(dataId)) return myProject; - if (PlatformDataKeys.VIRTUAL_FILE.is(dataId)) return extractVirtualFile(); - if (PlatformDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) return extractVirtualFiles(); + if (CommonDataKeys.VIRTUAL_FILE.is(dataId)) return extractVirtualFile(); + if (CommonDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) return extractVirtualFiles(); if (Location.DATA_KEY.is(dataId)) return extractLocation(); - if (PlatformDataKeys.NAVIGATABLE_ARRAY.is(dataId)) return extractNavigatables(); + if (CommonDataKeys.NAVIGATABLE_ARRAY.is(dataId)) return extractNavigatables(); if (MavenDataKeys.MAVEN_GOALS.is(dataId)) return extractGoals(true); + if (MavenDataKeys.RUN_CONFIGURATION.is(dataId)) return extractRunSettings(); if (MavenDataKeys.MAVEN_PROFILES.is(dataId)) return extractProfiles(); if (MavenDataKeys.MAVEN_DEPENDENCIES.is(dataId)) { @@ -188,6 +191,14 @@ public class MavenProjectsNavigatorPanel extends SimpleToolWindowPanel implement return psiFile == null ? null : new MavenGoalLocation(myProject, psiFile, goals); } + @Nullable + private RunnerAndConfigurationSettings extractRunSettings() { + SimpleNode node = myTree.getSelectedNode(); + if (!(node instanceof MavenProjectsStructure.RunConfigurationNode)) return null; + + return ((MavenProjectsStructure.RunConfigurationNode)node).getSettings(); + } + private List<String> extractGoals(boolean qualifiedGoals) { final MavenProjectsStructure.ProjectNode projectNode = getSelectedProjectNode(); if (projectNode != null) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsStructure.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsStructure.java index 667b82338b1d..68974c58b6b7 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsStructure.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsStructure.java @@ -15,6 +15,10 @@ */ package org.jetbrains.idea.maven.navigator; +import com.intellij.execution.ProgramRunnerUtil; +import com.intellij.execution.RunManager; +import com.intellij.execution.RunnerAndConfigurationSettings; +import com.intellij.execution.executors.DefaultRunExecutor; import com.intellij.icons.AllIcons; import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.project.Project; @@ -26,6 +30,7 @@ import com.intellij.pom.Navigatable; import com.intellij.ui.JBColor; import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.treeStructure.*; +import com.intellij.util.PathUtil; import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashMap; import icons.MavenIcons; @@ -33,6 +38,8 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; +import org.jetbrains.idea.maven.execution.MavenRunConfiguration; +import org.jetbrains.idea.maven.execution.MavenRunConfigurationType; import org.jetbrains.idea.maven.execution.MavenRunner; import org.jetbrains.idea.maven.model.*; import org.jetbrains.idea.maven.project.MavenProject; @@ -232,6 +239,12 @@ public class MavenProjectsStructure extends SimpleTreeStructure { } } + public void updateRunConfigurations() { + for (ProjectNode each : myProjectToNodeMapping.values()) { + each.updateRunConfigurations(); + } + } + public void select(MavenProject project) { ProjectNode node = findNodeFor(project); if (node != null) select(node); @@ -645,6 +658,7 @@ public class MavenProjectsStructure extends SimpleTreeStructure { private final PluginsNode myPluginsNode; private final DependenciesNode myDependenciesNode; private final ModulesNode myModulesNode; + private final RunConfigurationsNode myRunConfigurationsNode; private String myTooltipCache; @@ -656,6 +670,7 @@ public class MavenProjectsStructure extends SimpleTreeStructure { myPluginsNode = new PluginsNode(this); myDependenciesNode = new DependenciesNode(this, mavenProject); myModulesNode = new ModulesNode(this); + myRunConfigurationsNode = new RunConfigurationsNode(this); setUniformIcon(MavenIcons.MavenProject); updateProject(); @@ -677,10 +692,9 @@ public class MavenProjectsStructure extends SimpleTreeStructure { @Override protected List<? extends MavenSimpleNode> doGetChildren() { - return Arrays.asList(myLifecycleNode, myPluginsNode, myDependenciesNode, myModulesNode); + return Arrays.asList(myLifecycleNode, myPluginsNode, myRunConfigurationsNode, myDependenciesNode, myModulesNode); } - public ModulesNode getModulesNode() { return myModulesNode; } @@ -694,6 +708,8 @@ public class MavenProjectsStructure extends SimpleTreeStructure { myDependenciesNode.updateDependencies(); } + myRunConfigurationsNode.updateRunConfigurations(myMavenProject); + myTooltipCache = makeDescription(); updateFrom(getParent()); @@ -708,6 +724,11 @@ public class MavenProjectsStructure extends SimpleTreeStructure { updateFrom(myPluginsNode); } + public void updateRunConfigurations() { + myRunConfigurationsNode.updateRunConfigurations(myMavenProject); + updateFrom(myRunConfigurationsNode); + } + @Override public String getName() { if (myProjectsNavigator.getAlwaysShowArtifactId()) { @@ -987,12 +1008,14 @@ public class MavenProjectsStructure extends SimpleTreeStructure { public void updatePlugins(MavenProject mavenProject) { List<MavenPlugin> plugins = mavenProject.getDeclaredPlugins(); - for (PluginNode each : myPluginNodes.toArray(new PluginNode[myPluginNodes.size()])) { + for (Iterator<PluginNode> itr = myPluginNodes.iterator(); itr.hasNext(); ) { + PluginNode each = itr.next(); + if (plugins.contains(each.getPlugin())) { each.updatePlugin(); } else { - myPluginNodes.remove(each); + itr.remove(); } } for (MavenPlugin each : plugins) { @@ -1000,6 +1023,7 @@ public class MavenProjectsStructure extends SimpleTreeStructure { myPluginNodes.add(new PluginNode(this, each)); } } + sort(myPluginNodes); childrenChanged(); } @@ -1222,4 +1246,108 @@ public class MavenProjectsStructure extends SimpleTreeStructure { return getDisplayKind() != DisplayKind.NEVER; } } -} + + public class RunConfigurationsNode extends GroupNode { + + private final List<RunConfigurationNode> myChildren = new ArrayList<RunConfigurationNode>(); + + public RunConfigurationsNode(ProjectNode parent) { + super(parent); + setUniformIcon(MavenIcons.Phase); + } + + @Override + public String getName() { + return message("view.node.run.configurations"); + } + + @Override + protected List<? extends MavenSimpleNode> doGetChildren() { + return myChildren; + } + + public void updateRunConfigurations(MavenProject mavenProject) { + boolean childChanged = false; + + List<RunnerAndConfigurationSettings> + list = RunManager.getInstance(myProject).getConfigurationSettingsList(MavenRunConfigurationType.getInstance()); + + Set<RunnerAndConfigurationSettings> cfgs = new HashSet<RunnerAndConfigurationSettings>(((Collection<RunnerAndConfigurationSettings>)((Collection)list))); + + for (Iterator<RunConfigurationNode> itr = myChildren.iterator(); itr.hasNext(); ) { + RunConfigurationNode node = itr.next(); + + if (cfgs.remove(node.getSettings())) { + node.updateRunConfiguration(); + } + else { + itr.remove(); + childChanged = true; + } + } + + String directory = PathUtil.getCanonicalPath(mavenProject.getDirectory()); + + int oldSize = myChildren.size(); + + for (RunnerAndConfigurationSettings cfg : cfgs) { + MavenRunConfiguration mavenRunConfiguration = (MavenRunConfiguration)cfg.getConfiguration(); + + if (directory.equals(PathUtil.getCanonicalPath(mavenRunConfiguration.getRunnerParameters().getWorkingDirPath()))) { + myChildren.add(new RunConfigurationNode(this, cfg)); + } + } + + if (oldSize != myChildren.size()) { + childChanged = true; + sort(myChildren); + } + + if (childChanged) { + childrenChanged(); + } + } + } + + public class RunConfigurationNode extends MavenSimpleNode { + + private RunnerAndConfigurationSettings mySettings; + + public RunConfigurationNode(RunConfigurationsNode parent, RunnerAndConfigurationSettings settings) { + super(parent); + mySettings = settings; + setUniformIcon(ProgramRunnerUtil.getConfigurationIcon(settings, false)); + } + + public RunnerAndConfigurationSettings getSettings() { + return mySettings; + } + + @Override + public String getName() { + return mySettings.getName(); + } + + @Override + protected void doUpdate() { + setNameAndTooltip(getName(), + null, + StringUtil.join(((MavenRunConfiguration)mySettings.getConfiguration()).getRunnerParameters().getGoals(), " ")); + } + + @Nullable + @Override + String getMenuId() { + return "Maven.RunConfigurationMenu"; + } + + public void updateRunConfiguration() { + + } + + @Override + public void handleDoubleClickOrEnter(SimpleTree tree, InputEvent inputEvent) { + ProgramRunnerUtil.executeConfiguration(myProject, mySettings, DefaultRunExecutor.getRunExecutorInstance()); + } + } +}
\ No newline at end of file diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/EditMavenRunConfigurationAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/EditMavenRunConfigurationAction.java new file mode 100644 index 000000000000..807f671b5d97 --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/EditMavenRunConfigurationAction.java @@ -0,0 +1,37 @@ +package org.jetbrains.idea.maven.navigator.actions; + +import com.intellij.execution.RunManager; +import com.intellij.execution.RunnerAndConfigurationSettings; +import com.intellij.execution.impl.EditConfigurationsDialog; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.project.Project; +import org.jetbrains.idea.maven.utils.MavenDataKeys; + +/** + * @author Sergey Evdokimov + */ +public class EditMavenRunConfigurationAction extends AnAction { + @Override + public void actionPerformed(AnActionEvent e) { + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); + RunnerAndConfigurationSettings settings = MavenDataKeys.RUN_CONFIGURATION.getData(e.getDataContext()); + + assert settings != null && project != null; + + RunManager.getInstance(project).setSelectedConfiguration(settings); + + EditConfigurationsDialog dialog = new EditConfigurationsDialog(project); + dialog.show(); + } + + @Override + public void update(AnActionEvent e) { + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); + RunnerAndConfigurationSettings settings = MavenDataKeys.RUN_CONFIGURATION.getData(e.getDataContext()); + + boolean enabled = settings != null && project != null; + e.getPresentation().setEnabledAndVisible(enabled); + } +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenExecuteGoalAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenExecuteGoalAction.java index 0c32b906ee89..99289a194ad4 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenExecuteGoalAction.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenExecuteGoalAction.java @@ -21,6 +21,7 @@ import com.intellij.notification.NotificationListener; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.DumbAwareAction; @@ -45,7 +46,7 @@ import java.util.List; public class MavenExecuteGoalAction extends DumbAwareAction { @Override public void actionPerformed(final AnActionEvent e) { - final Project project = e.getRequiredData(PlatformDataKeys.PROJECT); + final Project project = e.getRequiredData(CommonDataKeys.PROJECT); ExecuteMavenGoalHistoryService historyService = ExecuteMavenGoalHistoryService.getInstance(project); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenRunConfigurationMenu.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenRunConfigurationMenu.java new file mode 100644 index 000000000000..4566689ed55e --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenRunConfigurationMenu.java @@ -0,0 +1,71 @@ +package org.jetbrains.idea.maven.navigator.actions; + +import com.intellij.execution.*; +import com.intellij.execution.runners.ProgramRunner; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import org.jetbrains.idea.maven.utils.MavenDataKeys; + +/** + * @author Sergey Evdokimov + */ +public class MavenRunConfigurationMenu extends DefaultActionGroup implements DumbAware { + + @Override + public void update(AnActionEvent e) { + for (AnAction action : getChildActionsOrStubs()) { + if (action instanceof ExecuteMavenRunConfigurationAction) { + remove(action); + } + } + + final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); + + final RunnerAndConfigurationSettings settings = MavenDataKeys.RUN_CONFIGURATION.getData(e.getDataContext()); + + if (settings == null || project == null) return; + + Executor[] executors = ExecutorRegistry.getInstance().getRegisteredExecutors(); + for (int i = executors.length; --i >= 0; ) { + final ProgramRunner runner = RunnerRegistry.getInstance().getRunner(executors[i].getId(), settings.getConfiguration()); + + AnAction action = new ExecuteMavenRunConfigurationAction(executors[i], runner != null, project, settings); + + addAction(action, Constraints.FIRST); + } + + super.update(e); + } + + private static class ExecuteMavenRunConfigurationAction extends AnAction { + private final Executor myExecutor; + private final boolean myEnabled; + private final Project myProject; + private final RunnerAndConfigurationSettings mySettings; + + public ExecuteMavenRunConfigurationAction(Executor executor, + boolean enabled, + Project project, + RunnerAndConfigurationSettings settings) { + super(executor.getActionName(), null, executor.getIcon()); + myExecutor = executor; + myEnabled = enabled; + myProject = project; + mySettings = settings; + } + + @Override + public void actionPerformed(AnActionEvent event) { + if (!myEnabled) return; + + ProgramRunnerUtil.executeConfiguration(myProject, mySettings, myExecutor); + } + + @Override + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled(myEnabled); + } + } +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/RemoveMavenRunConfigurationAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/RemoveMavenRunConfigurationAction.java new file mode 100644 index 000000000000..f9aacbcba809 --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/RemoveMavenRunConfigurationAction.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.maven.navigator.actions; + +import com.intellij.execution.RunManager; +import com.intellij.execution.RunManagerEx; +import com.intellij.execution.RunnerAndConfigurationSettings; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import org.jetbrains.idea.maven.utils.MavenDataKeys; + +/** + * @author Sergey Evdokimov + */ +public class RemoveMavenRunConfigurationAction extends AnAction { + @Override + public void actionPerformed(AnActionEvent e) { + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); + RunnerAndConfigurationSettings settings = MavenDataKeys.RUN_CONFIGURATION.getData(e.getDataContext()); + + assert settings != null && project != null; + + int res = Messages.showYesNoDialog(project, "Delete \"" + settings.getName() + "\"?", "Confirmation", Messages.getQuestionIcon()); + if (res == Messages.YES) { + ((RunManagerEx)RunManager.getInstance(project)).removeConfiguration(settings); + } + } + + @Override + public void update(AnActionEvent e) { + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); + RunnerAndConfigurationSettings settings = MavenDataKeys.RUN_CONFIGURATION.getData(e.getDataContext()); + + boolean enabled = settings != null && project != null; + e.getPresentation().setEnabledAndVisible(enabled); + } +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddFileAsMavenProjectAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddFileAsMavenProjectAction.java index c2980a0bfc15..ce05cccd5352 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddFileAsMavenProjectAction.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddFileAsMavenProjectAction.java @@ -16,6 +16,7 @@ package org.jetbrains.idea.maven.project.actions; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.vfs.VirtualFile; @@ -55,6 +56,6 @@ public class AddFileAsMavenProjectAction extends MavenAction { @Nullable private static VirtualFile getSelectedFile(DataContext context) { - return PlatformDataKeys.VIRTUAL_FILE.getData(context); + return CommonDataKeys.VIRTUAL_FILE.getData(context); } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddManagedFilesAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddManagedFilesAction.java index 4ebf81b1aaca..33cbf026699d 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddManagedFilesAction.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddManagedFilesAction.java @@ -16,6 +16,7 @@ package org.jetbrains.idea.maven.project.actions; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; @@ -45,7 +46,7 @@ public class AddManagedFilesAction extends MavenAction { }; Project project = MavenActionUtil.getProject(e.getDataContext()); - VirtualFile fileToSelect = e.getData(PlatformDataKeys.VIRTUAL_FILE); + VirtualFile fileToSelect = e.getData(CommonDataKeys.VIRTUAL_FILE); VirtualFile[] files = FileChooser.chooseFiles(singlePomSelection, project, fileToSelect); if (files.length == 0) return; diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/MavenShowEffectivePom.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/MavenShowEffectivePom.java index 55e9f52fe551..7e1bd642c06b 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/MavenShowEffectivePom.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/MavenShowEffectivePom.java @@ -89,7 +89,7 @@ public class MavenShowEffectivePom extends AnAction implements DumbAware { @Nullable private static VirtualFile findPomXml(@NotNull DataContext dataContext) { - VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + VirtualFile file = CommonDataKeys.VIRTUAL_FILE.getData(dataContext); if (file == null) return null; if (file.isDirectory()) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java index 46579b30f30c..17eadb667652 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java @@ -20,38 +20,50 @@ import com.intellij.notification.NotificationType; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.idea.maven.project.MavenProject; import org.jetbrains.idea.maven.project.MavenProjectsManager; import org.jetbrains.idea.maven.utils.MavenUtil; import org.jetbrains.idea.maven.utils.actions.MavenAction; import org.jetbrains.idea.maven.utils.actions.MavenActionUtil; +import java.util.List; + public class RemoveManagedFilesAction extends MavenAction { @Override protected boolean isAvailable(AnActionEvent e) { if (!super.isAvailable(e)) return false; - return !MavenActionUtil.getMavenProjectsFiles(e.getDataContext()).isEmpty(); + return MavenActionUtil.getMavenProjectsFiles(e.getDataContext()).size() == 1; } @Override public void actionPerformed(AnActionEvent e) { final DataContext context = e.getDataContext(); - boolean hasManagedFiles = false; - MavenProjectsManager projectsManager = MavenActionUtil.getProjectsManager(context); - for (VirtualFile each : MavenActionUtil.getMavenProjectsFiles(context)) { - if (projectsManager.isManagedFile(each)) { - hasManagedFiles = true; - break; + List<VirtualFile> selectedFiles = MavenActionUtil.getMavenProjectsFiles(context); + if (selectedFiles.size() != 1) return; + + VirtualFile pomXml = selectedFiles.get(0); + + if (!projectsManager.isManagedFile(pomXml)) { + MavenProject mavenProject = projectsManager.findProject(pomXml); + assert mavenProject != null; + + String aggregatorDescription = ""; + + MavenProject aggregator = projectsManager.findAggregator(mavenProject); + + if (aggregator != null) { + aggregatorDescription = " (" + aggregator.getMavenId().getDisplayString() + ')'; } - } - if (!hasManagedFiles) { Notification notification = new Notification(MavenUtil.MAVEN_NOTIFICATION_GROUP, "Failed to remove project", "You can not remove selected project because it's " + - "imported as module of other project. You can ignore it. Only root project can be removed.", + "imported as a module of another project" + + aggregatorDescription + +". You can use Ignore action. Only root project can be removed.", NotificationType.ERROR); notification.setImportant(true); @@ -59,6 +71,6 @@ public class RemoveManagedFilesAction extends MavenAction { return; } - projectsManager.removeManagedFiles(MavenActionUtil.getMavenProjectsFiles(context)); + projectsManager.removeManagedFiles(selectedFiles); } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenBeforeRunTasksProvider.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenBeforeRunTasksProvider.java index 33f69817a22f..b98fff5cd5d7 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenBeforeRunTasksProvider.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenBeforeRunTasksProvider.java @@ -18,6 +18,7 @@ package org.jetbrains.idea.maven.tasks; import com.intellij.execution.BeforeRunTaskProvider; import com.intellij.execution.configurations.RunConfiguration; import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; @@ -154,7 +155,7 @@ public class MavenBeforeRunTasksProvider extends BeforeRunTaskProvider<MavenBefo try { ApplicationManager.getApplication().invokeAndWait(new Runnable() { public void run() { - final Project project = PlatformDataKeys.PROJECT.getData(context); + final Project project = CommonDataKeys.PROJECT.getData(context); final MavenProject mavenProject = getMavenProject(task); if (project == null || project.isDisposed() || mavenProject == null) return; diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenDataKeys.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenDataKeys.java index 70ea789a65aa..397447c44393 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenDataKeys.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenDataKeys.java @@ -15,6 +15,7 @@ */ package org.jetbrains.idea.maven.utils; +import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.openapi.actionSystem.DataKey; import org.jetbrains.idea.maven.model.MavenArtifact; @@ -25,6 +26,7 @@ import java.util.List; public class MavenDataKeys { public static final DataKey<List<String>> MAVEN_GOALS = DataKey.create("MAVEN_GOALS"); + public static final DataKey<RunnerAndConfigurationSettings> RUN_CONFIGURATION = DataKey.create("MAVEN_RUN_CONFIGURATION"); public static final DataKey<List<String>> MAVEN_PROFILES = DataKey.create("MAVEN_PROFILES"); public static final DataKey<Collection<MavenArtifact>> MAVEN_DEPENDENCIES = DataKey.create("MAVEN_DEPENDENCIES"); public static final DataKey<JTree> MAVEN_PROJECTS_TREE = DataKey.create("MAVEN_PROJECTS_TREE"); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/actions/MavenActionUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/actions/MavenActionUtil.java index 4658fd49b803..dc624d88df28 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/actions/MavenActionUtil.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/actions/MavenActionUtil.java @@ -15,6 +15,7 @@ */ package org.jetbrains.idea.maven.utils.actions; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.DataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -37,16 +38,16 @@ public class MavenActionUtil { } public static boolean hasProject(DataContext context) { - return PlatformDataKeys.PROJECT.getData(context) != null; + return CommonDataKeys.PROJECT.getData(context) != null; } @NotNull public static Project getProject(DataContext context) { - return PlatformDataKeys.PROJECT.getData(context); + return CommonDataKeys.PROJECT.getData(context); } public static boolean isMavenizedProject(DataContext context) { - Project project = PlatformDataKeys.PROJECT.getData(context); + Project project = CommonDataKeys.PROJECT.getData(context); return project != null && MavenProjectsManager.getInstance(project).isMavenizedProject(); } @@ -55,7 +56,7 @@ public class MavenActionUtil { MavenProject result; final MavenProjectsManager manager = getProjectsManager(context); - final VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(context); + final VirtualFile file = CommonDataKeys.VIRTUAL_FILE.getData(context); if (file != null) { result = manager.findProject(file); if (result != null) return result; @@ -88,10 +89,10 @@ public class MavenActionUtil { } public static List<MavenProject> getMavenProjects(DataContext context) { - Project project = PlatformDataKeys.PROJECT.getData(context); + Project project = CommonDataKeys.PROJECT.getData(context); if (project == null) return Collections.emptyList(); - VirtualFile[] virtualFiles = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(context); + VirtualFile[] virtualFiles = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(context); if (virtualFiles == null || virtualFiles.length == 0) return Collections.emptyList(); MavenProjectsManager projectsManager = MavenProjectsManager.getInstance(project); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java index 2d0752ad5104..7d4e31a7fe95 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java @@ -94,7 +94,7 @@ public class MavenModuleBuilder extends ModuleBuilder implements SourcePathsBuil @Override public String getPresentableName() { - return "Maven Module"; + return "Maven"; } @Override diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.java index ede845ae3874..cc33fae4c6a2 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleWizardStep.java @@ -20,6 +20,7 @@ import com.intellij.ide.util.projectWizard.ModuleWizardStep; import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.Nullable; @@ -293,5 +294,12 @@ public class MavenModuleWizardStep extends ModuleWizardStep { public String getHelpId() { return "reference.dialogs.new.project.fromScratch.maven"; } + + @Override + public void disposeUIResources() { + if (myArchetypes != null) { + Disposer.dispose(myArchetypes); + } + } } diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml index 491fad10c367..bf2da5ad500d 100644 --- a/plugins/maven/src/main/resources/META-INF/plugin.xml +++ b/plugins/maven/src/main/resources/META-INF/plugin.xml @@ -579,5 +579,16 @@ class="org.jetbrains.idea.maven.dom.refactorings.extract.ExtractManagedDependenciesAction" use-shortcut-of="ExtractMethod"/> </group> + + <group id="Maven.RunConfigurationMenu" popup="true" class="org.jetbrains.idea.maven.navigator.actions.MavenRunConfigurationMenu"> + <separator/> + <action id="Maven.EditRunConfiguration" + text="Edit Run Configuration..." icon="AllIcons.Actions.Edit" + class="org.jetbrains.idea.maven.navigator.actions.EditMavenRunConfigurationAction" /> + <action id="Maven.RemoveRunConfiguration" + text="Remove Run Configuration" icon="AllIcons.General.Remove" + class="org.jetbrains.idea.maven.navigator.actions.RemoveMavenRunConfigurationAction" /> + </group> + </actions> </idea-plugin> diff --git a/plugins/maven/src/main/resources/ProjectBundle.properties b/plugins/maven/src/main/resources/ProjectBundle.properties index af2bf52bf76a..5a1a80c2ab3d 100644 --- a/plugins/maven/src/main/resources/ProjectBundle.properties +++ b/plugins/maven/src/main/resources/ProjectBundle.properties @@ -86,5 +86,6 @@ maven.file.type.descr=Maven project files view.node.lifecycle=Lifecycle view.node.profiles=Profiles view.node.plugins=Plugins +view.node.run.configurations=Run Configurations view.node.dependencies=Dependencies view.node.modules=Modules diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java index 94ca15bcb909..6d5ec4971874 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java @@ -89,6 +89,7 @@ public abstract class MavenImportingTestCase extends MavenTestCase { myProjectsManager.projectClosed(); removeFromLocalRepository("test"); if (useJps()) { + CompilerTestUtil.disableExternalCompiler(myProject); FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory()); } super.tearDown(); diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDomTestCase.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDomTestCase.java index f47b6e152bdf..5ab6163e6796 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDomTestCase.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDomTestCase.java @@ -24,6 +24,7 @@ import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter; import com.intellij.lang.documentation.DocumentationProvider; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -352,9 +353,9 @@ public abstract class MavenDomTestCase extends MavenImportingTestCase { private MapDataContext createDataContext(VirtualFile f) throws IOException { MapDataContext context = new MapDataContext(); - context.put(PlatformDataKeys.EDITOR, getEditor(f)); - context.put(LangDataKeys.PSI_FILE, getTestPsiFile(f)); - context.put(LangDataKeys.PSI_ELEMENT, TargetElementUtil.findTargetElement(getEditor(f), + context.put(CommonDataKeys.EDITOR, getEditor(f)); + context.put(CommonDataKeys.PSI_FILE, getTestPsiFile(f)); + context.put(CommonDataKeys.PSI_ELEMENT, TargetElementUtil.findTargetElement(getEditor(f), TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED | TargetElementUtilBase.ELEMENT_NAME_ACCEPTED)); return context; diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/ArtifactsDownloadingTestCase.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/ArtifactsDownloadingTestCase.java index ecf48c16e991..f5ef0ff52b2d 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/ArtifactsDownloadingTestCase.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/ArtifactsDownloadingTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.jetbrains.idea.maven.importing; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.testFramework.PlatformTestUtil; import org.jetbrains.idea.maven.MavenCustomRepositoryHelper; import org.jetbrains.idea.maven.MavenImportingTestCase; @@ -35,6 +36,6 @@ public abstract class ArtifactsDownloadingTestCase extends MavenImportingTestCas protected void createDummyArtifact(String remoteRepo, String name) throws IOException { FileUtil.writeToFile(new File(remoteRepo, name), PlatformTestUtil.EMPTY_JAR_BYTES); - FileUtil.writeToFile(new File(remoteRepo, name + ".sha1"), ("6216f8a75fd5bb3d5f22b6f9958cdede3fc086c2 " + name).getBytes()); + FileUtil.writeToFile(new File(remoteRepo, name + ".sha1"), ("b04f3ee8f5e43fa3b162981b50bb72fe1acabb33 " + name).getBytes(CharsetToolkit.UTF8_CHARSET)); } } diff --git a/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java b/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java index e0c0bbf58c82..4b6a574c2024 100644 --- a/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java +++ b/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java @@ -26,6 +26,7 @@ import com.intellij.lang.properties.ResourceBundle; import com.intellij.lang.properties.ResourceBundleImpl; import com.intellij.lang.properties.projectView.ResourceBundleNode; import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; @@ -44,7 +45,7 @@ public class ResourcesFavoriteNodeProvider extends FavoriteNodeProvider { } public Collection<AbstractTreeNode> getFavoriteNodes(final DataContext context, final ViewSettings viewSettings) { - final Project project = PlatformDataKeys.PROJECT.getData(context); + final Project project = CommonDataKeys.PROJECT.getData(context); if (project == null) { return null; } diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java index ab734504e3ba..9289eb24a4cb 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java @@ -16,6 +16,7 @@ package com.intellij.lang.properties.editor; import com.intellij.lang.properties.ResourceBundle; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; @@ -31,7 +32,7 @@ class ResourceBundleStructureViewComponent extends PropertiesGroupingStructureVi } public Object getData(String dataId) { - if (PlatformDataKeys.VIRTUAL_FILE.is(dataId)) { + if (CommonDataKeys.VIRTUAL_FILE.is(dataId)) { return new ResourceBundleAsVirtualFile(myResourceBundle); } return super.getData(dataId); diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java index d87e60af640d..d0d7e4db8928 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java @@ -18,6 +18,7 @@ package com.intellij.lang.properties.editor; import com.intellij.lang.properties.IProperty; import com.intellij.lang.properties.ResourceBundle; import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -63,18 +64,18 @@ public class ResourceBundleUtil { */ @Nullable public static ResourceBundle getResourceBundleFromDataContext(@NotNull DataContext dataContext) { - PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext); + PsiElement element = CommonDataKeys.PSI_ELEMENT.getData(dataContext); if (element instanceof IProperty) return null; //rename property final ResourceBundle[] bundles = ResourceBundle.ARRAY_DATA_KEY.getData(dataContext); if (bundles != null && bundles.length == 1) return bundles[0]; - VirtualFile virtualFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext); if (virtualFile == null) { return null; } if (virtualFile instanceof ResourceBundleAsVirtualFile) { return ((ResourceBundleAsVirtualFile)virtualFile).getResourceBundle(); } - Project project = PlatformDataKeys.PROJECT.getData(dataContext); + Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project != null) { final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); if (psiFile instanceof PropertiesFile) { @@ -92,12 +93,12 @@ public class ResourceBundleUtil { */ @Nullable public static ResourceBundleEditor getEditor(@NotNull DataContext dataContext) { - Project project = PlatformDataKeys.PROJECT.getData(dataContext); + Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null) { return null; } - VirtualFile virtualFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext); if (virtualFile == null) { return null; } diff --git a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleDeleteProvider.java b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleDeleteProvider.java index 52306669fa93..7ba44a86c2bd 100644 --- a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleDeleteProvider.java +++ b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleDeleteProvider.java @@ -18,6 +18,7 @@ package com.intellij.lang.properties.projectView; import com.intellij.ide.DeleteProvider; import com.intellij.lang.properties.ResourceBundle; import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; @@ -46,14 +47,14 @@ class ResourceBundleDeleteProvider implements DeleteProvider { } public void deleteElement(@NotNull DataContext dataContext) { - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles(project); assert project != null; new SafeDeleteHandler().invoke(project, ContainerUtil.map2Array(propertiesFiles, PsiElement.class, MAPPER), dataContext); } public boolean canDeleteElement(@NotNull DataContext dataContext) { - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); return project != null; } } diff --git a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleMoveProvider.java b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleMoveProvider.java index 9d96e1333497..a2b1b621f068 100644 --- a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleMoveProvider.java +++ b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleMoveProvider.java @@ -17,6 +17,7 @@ package com.intellij.lang.properties.projectView; import com.intellij.lang.properties.ResourceBundle; import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; @@ -56,7 +57,7 @@ public class ResourceBundleMoveProvider extends MoveHandlerDelegate { final ResourceBundle[] bundles = ResourceBundle.ARRAY_DATA_KEY.getData(dataContext); LOG.assertTrue(bundles != null); for (ResourceBundle bundle : bundles) { - List<PropertiesFile> propertiesFiles = bundle.getPropertiesFiles(PlatformDataKeys.PROJECT.getData(dataContext)); + List<PropertiesFile> propertiesFiles = bundle.getPropertiesFiles(CommonDataKeys.PROJECT.getData(dataContext)); for (PropertiesFile propertiesFile : propertiesFiles) { filesOrDirs.add(propertiesFile.getContainingFile()); } diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java index 2eb402aa23a6..31c821c15959 100644 --- a/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java +++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java @@ -26,6 +26,7 @@ import com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile; import com.intellij.lang.properties.editor.ResourceBundleEditor; import com.intellij.lang.properties.editor.ResourceBundleUtil; import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; @@ -48,7 +49,7 @@ public class ResourceBundleRenameHandler implements RenameHandler { private static final Logger LOG = Logger.getInstance("#" + ResourceBundleRenameHandler.class.getName()); public boolean isAvailableOnDataContext(DataContext dataContext) { - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null) { return false; } @@ -57,7 +58,7 @@ public class ResourceBundleRenameHandler implements RenameHandler { return false; } - final VirtualFile virtualFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + final VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext); ResourceBundleEditor editor = ResourceBundleUtil.getEditor(dataContext); return (editor == null || editor.getState(FileEditorStateLevel.NAVIGATION).getPropertyName() == null /* user selected non-bundle key element */) diff --git a/plugins/properties/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewComponent.java b/plugins/properties/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewComponent.java index 178851f4a01f..390098270409 100644 --- a/plugins/properties/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewComponent.java +++ b/plugins/properties/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewComponent.java @@ -18,6 +18,7 @@ package com.intellij.lang.properties.structureView; import com.intellij.lang.properties.editor.PropertiesGroupingStructureViewComponent; import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.lang.properties.psi.impl.PropertiesFileImpl; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.fileEditor.FileEditor; @@ -35,10 +36,10 @@ public class PropertiesFileStructureViewComponent extends PropertiesGroupingStru } public Object getData(String dataId) { - if (PlatformDataKeys.VIRTUAL_FILE.is(dataId)) { + if (CommonDataKeys.VIRTUAL_FILE.is(dataId)) { return myPropertiesFile.getVirtualFile(); } - if (LangDataKeys.PSI_ELEMENT.is(dataId)) { + if (CommonDataKeys.PSI_ELEMENT.is(dataId)) { return myPropertiesFile; } return super.getData(dataId); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties index bbb8e54c6704..65de1e5bc8d3 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties @@ -330,6 +330,7 @@ progress.text2.exported=Exported {1} files, exporting {0} progress.text2.checked.out.revision=Checked out revision {0}. progress.text2.exported.revision=Exported revision {0}. status.text.checked.out.revision=Checked out revision {0}. +message.text.cannot.load.supported.formats=Cannot load supported formats: {0} message.text.cannot.checkout=Cannot checkout from svn: {0} message.text.cannot.export=Cannot export from svn: {0} message.title.check.out=Check Out from Subversion diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java index b28ebd53dde2..2f193f723584 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java @@ -54,7 +54,7 @@ import java.util.*; */ public class SvnChangeProvider implements ChangeProvider { private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnChangeProvider"); - public static final String ourDefaultListName = VcsBundle.message("changes.default.changlist.name"); + public static final String ourDefaultListName = VcsBundle.message("changes.default.changelist.name"); public static final String PROPERTY_LAYER = "Property"; private final SvnVcs myVcs; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java index 2595631bac4b..12513893c5af 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java @@ -17,12 +17,7 @@ package org.jetbrains.idea.svn; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Ref; -import com.intellij.util.WaitForProgressToShow; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.idea.svn.dialogs.UpgradeFormatDialog; import org.tmatesoft.svn.core.SVNErrorCode; import org.tmatesoft.svn.core.SVNErrorMessage; import org.tmatesoft.svn.core.SVNException; @@ -136,22 +131,6 @@ public class SvnFormatSelector implements ISVNAdminAreaFactorySelector { return result; } - public static WorkingCopyFormat showUpgradeDialog(final File path, - final Project project, - final boolean display13format, - @NotNull final WorkingCopyFormat defaultSelection, - @NotNull final Ref<Boolean> wasOk) { - assert ! ApplicationManager.getApplication().isUnitTestMode(); - final Ref<WorkingCopyFormat> format = new Ref<WorkingCopyFormat>(defaultSelection); - WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(new Runnable() { - public void run() { - wasOk.set(displayUpgradeDialog(project, path, display13format, format)); - } - }); - ApplicationManager.getApplication().getMessageBus().syncPublisher(SvnVcs.WC_CONVERTED).run(); - return format.get(); - } - public static WorkingCopyFormat findRootAndGetFormat(final File path) { File root = SvnUtil.getWorkingCopyRootNew(path); @@ -189,14 +168,4 @@ public class SvnFormatSelector implements ISVNAdminAreaFactorySelector { return WorkingCopyFormat.getInstance(format); } - - private static boolean displayUpgradeDialog(Project project, File path, final boolean dispay13format, Ref<WorkingCopyFormat> format) { - UpgradeFormatDialog dialog = new UpgradeFormatDialog(project, path, false); - dialog.setData(format.get()); - dialog.show(); - if (dialog.isOK()) { - format.set(dialog.getUpgradeMode()); - } - return dialog.isOK(); - } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java index 07301c0829f1..083bb7840cdf 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java @@ -647,6 +647,7 @@ public class SvnUtil { } public static boolean remoteFolderIsEmpty(final SvnVcs vcs, final String url) throws SVNException { + // TODO: Implement with command line client SVNRepository repository = null; try { repository = vcs.createRepository(url); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java index 041ee2811a63..26069480a341 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java @@ -100,4 +100,27 @@ public enum WorkingCopyFormat { public int getFormat() { return myFormat; } + + public boolean isOrGreater(@NotNull WorkingCopyFormat format) { + return myVersion.isOrGreaterThan(format.getVersion().major, format.getVersion().minor); + } + + @NotNull + public static WorkingCopyFormat from(@NotNull Version version) { + WorkingCopyFormat result = UNKNOWN; + + for (WorkingCopyFormat format : WorkingCopyFormat.values()) { + if (format.getVersion().is(version.major, version.minor)) { + result = format; + break; + } + } + + return result; + } + + @Override + public String toString() { + return getName(); + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractIntegrateChangesAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractIntegrateChangesAction.java index 4d274b413405..ff0f158f32a8 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractIntegrateChangesAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractIntegrateChangesAction.java @@ -41,7 +41,7 @@ public abstract class AbstractIntegrateChangesAction<T extends SelectedCommitted protected abstract T createChecker(); public final void update(final AnActionEvent e) { - final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); final CommittedChangesBrowserUseCase useCase = CommittedChangesBrowserUseCase.DATA_KEY.getData(e.getDataContext()); final Presentation presentation = e.getPresentation(); @@ -80,7 +80,7 @@ public abstract class AbstractIntegrateChangesAction<T extends SelectedCommitted public void actionPerformed(final AnActionEvent e) { final DataContext dataContext = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); final T checker = createChecker(); checker.execute(e); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractShowPropertiesDiffAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractShowPropertiesDiffAction.java index 0a46ed5048c4..223c69ab1c6f 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractShowPropertiesDiffAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractShowPropertiesDiffAction.java @@ -69,7 +69,7 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen @Override public void update(final AnActionEvent e) { final DataContext dataContext = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); final Presentation presentation = e.getPresentation(); final Change[] data = VcsDataKeys.CHANGES.getData(dataContext); @@ -123,7 +123,7 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen public void actionPerformed(final AnActionEvent e) { final DataContext dataContext = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); final Change[] changes = e.getData(getChangesKey()); if (! checkThatChangesAreUnderSvn(changes)) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/BasicAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/BasicAction.java index 35f360f4755a..8555f276f0a9 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/BasicAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/BasicAction.java @@ -40,9 +40,9 @@ public abstract class BasicAction extends AnAction implements DumbAware { LOG.debug("enter: actionPerformed(id='" + ActionManager.getInstance().getId(this) + "')"); } final DataContext dataContext = event.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); - final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); + final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); if (LOG.isDebugEnabled() && files != null) { LOG.debug("files='" + Arrays.asList(files) + "'"); } @@ -106,7 +106,7 @@ public abstract class BasicAction extends AnAction implements DumbAware { Presentation presentation = e.getPresentation(); final DataContext dataContext = e.getDataContext(); - Project project = PlatformDataKeys.PROJECT.getData(dataContext); + Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project == null) { presentation.setEnabled(false); presentation.setVisible(false); @@ -120,7 +120,7 @@ public abstract class BasicAction extends AnAction implements DumbAware { return; } - VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); + VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); if (files == null || files.length == 0) { presentation.setEnabled(false); presentation.setVisible(true); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CleanupProjectAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CleanupProjectAction.java index 390407d7510e..40906992486b 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CleanupProjectAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CleanupProjectAction.java @@ -18,6 +18,7 @@ package org.jetbrains.idea.svn.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; @@ -30,13 +31,13 @@ import org.jetbrains.idea.svn.SvnVcs; */ public class CleanupProjectAction extends AnAction implements DumbAware { public void actionPerformed(final AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); final VirtualFile[] roots = ProjectLevelVcsManager.getInstance(project).getRootsUnderVcs(SvnVcs.getInstance(project)); new CleanupWorker(roots, project, "action.Subversion.cleanup.project.title").execute(); } public void update(final AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); e.getPresentation().setVisible(isEnabled(project)); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CompareWithBranchAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CompareWithBranchAction.java index 1bfe1733c06a..544bbc7beda8 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CompareWithBranchAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CompareWithBranchAction.java @@ -18,6 +18,7 @@ package org.jetbrains.idea.svn.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.DiffManager; @@ -69,9 +70,9 @@ public class CompareWithBranchAction extends AnAction implements DumbAware { private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.actions.CompareWithBranchAction"); public void actionPerformed(AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); assert project != null; - final VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE); + final VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE); SelectBranchPopup.show(project, virtualFile, new SelectBranchPopup.BranchSelectedCallback() { public void branchSelected(final Project project, final SvnBranchConfigurationNew configuration, final String url, final long revision) { @@ -82,8 +83,8 @@ public class CompareWithBranchAction extends AnAction implements DumbAware { @Override public void update(final AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); - VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE); + Project project = e.getData(CommonDataKeys.PROJECT); + VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE); e.getPresentation().setEnabled(isEnabled(project, virtualFile)); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ConfigureBranchesAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ConfigureBranchesAction.java index 36a5d3cdd27f..1993a1caa0fe 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ConfigureBranchesAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ConfigureBranchesAction.java @@ -17,6 +17,7 @@ package org.jetbrains.idea.svn.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.project.DumbAware; @@ -32,7 +33,7 @@ import org.jetbrains.idea.svn.history.SvnChangeList; public class ConfigureBranchesAction extends AnAction implements DumbAware { public void update(final AnActionEvent e) { - final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); final Presentation presentation = e.getPresentation(); if (project == null) { @@ -54,7 +55,7 @@ public class ConfigureBranchesAction extends AnAction implements DumbAware { } public void actionPerformed(final AnActionEvent e) { - final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); final ChangeList[] cls = e.getData(VcsDataKeys.CHANGE_LISTS); if ((cls == null) || (cls.length == 0) || (! SvnVcs.getInstance(project).getName().equals(((CommittedChangeList) cls[0]).getVcs().getName())) || diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java index 337a045caed1..490c093b26dc 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java @@ -16,6 +16,7 @@ package org.jetbrains.idea.svn.actions; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.progress.ProgressIndicator; @@ -68,8 +69,8 @@ public class CreateExternalAction extends DumbAwareAction { if (! helper.isOk()) return; final DataContext dc = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dc); - final VirtualFile vf = PlatformDataKeys.VIRTUAL_FILE.getData(dc); + final Project project = CommonDataKeys.PROJECT.getData(dc); + final VirtualFile vf = CommonDataKeys.VIRTUAL_FILE.getData(dc); //1 select target final SelectCreateExternalTargetDialog dialog = new SelectCreateExternalTargetDialog(project, vf); @@ -165,15 +166,15 @@ public class CreateExternalAction extends DumbAwareAction { private void checkState(AnActionEvent e, final ActionStateConsumer sc) { final DataContext dc = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dc); + final Project project = CommonDataKeys.PROJECT.getData(dc); final ProjectLevelVcsManager manager = ProjectLevelVcsManager.getInstance(project); if (project == null || ! manager.checkVcsIsActive(SvnVcs.getKey().getName())) { sc.hide(); return; } - final VirtualFile vf = PlatformDataKeys.VIRTUAL_FILE.getData(dc); - final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dc); + final VirtualFile vf = CommonDataKeys.VIRTUAL_FILE.getData(dc); + final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dc); if (vf == null || files == null || files.length != 1 || ! vf.isDirectory()) { sc.disable(); return; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/IgnoreActionGroup.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/IgnoreActionGroup.java index b3d672cc648d..e24c101c23c3 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/IgnoreActionGroup.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/IgnoreActionGroup.java @@ -16,6 +16,7 @@ package org.jetbrains.idea.svn.actions; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -76,7 +77,7 @@ public class IgnoreActionGroup extends DefaultActionGroup implements DumbAware { removeAll(); if (myHelperAction.allAreIgnored()) { final DataContext dataContext = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); SvnVcs vcs = SvnVcs.getInstance(project); final Ref<Boolean> filesOk = new Ref<Boolean>(Boolean.FALSE); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ImportToRepositoryAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ImportToRepositoryAction.java index dd61104e0fed..defa7bcdc12b 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ImportToRepositoryAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ImportToRepositoryAction.java @@ -17,6 +17,7 @@ package org.jetbrains.idea.svn.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.project.DumbAware; @@ -32,14 +33,14 @@ public class ImportToRepositoryAction extends AnAction implements DumbAware { @Override public void update(final AnActionEvent e) { super.update(e); - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); final Presentation presentation = e.getPresentation(); presentation.setEnabled(presentation.isEnabled() && (project == null || (! ProjectLevelVcsManager.getInstance(project).isBackgroundVcsOperationRunning()))); } public void actionPerformed(AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) { project = ProjectManager.getInstance().getDefaultProject(); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/MarkLocallyDeletedTreeConflictResolvedAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/MarkLocallyDeletedTreeConflictResolvedAction.java index e7c148cb3d79..461c202dbae3 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/MarkLocallyDeletedTreeConflictResolvedAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/MarkLocallyDeletedTreeConflictResolvedAction.java @@ -17,6 +17,7 @@ package org.jetbrains.idea.svn.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.progress.ProgressIndicator; @@ -108,7 +109,7 @@ public class MarkLocallyDeletedTreeConflictResolvedAction extends AnAction { public MyLocallyDeletedChecker(final AnActionEvent e) { final DataContext dc = e.getDataContext(); - myProject = PlatformDataKeys.PROJECT.getData(dc); + myProject = CommonDataKeys.PROJECT.getData(dc); if (myProject == null) { myPath = null; myEnabled = false; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShareProjectAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShareProjectAction.java index 975a1641b0c5..e4c14693f6eb 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShareProjectAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShareProjectAction.java @@ -16,6 +16,7 @@ package org.jetbrains.idea.svn.actions; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; @@ -31,18 +32,19 @@ import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.svn.*; +import org.jetbrains.idea.svn.api.ClientFactory; import org.jetbrains.idea.svn.checkout.SvnCheckoutProvider; import org.jetbrains.idea.svn.dialogs.ShareDialog; import org.tmatesoft.svn.core.SVNCommitInfo; import org.tmatesoft.svn.core.SVNDepth; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; -import org.tmatesoft.svn.core.internal.wc2.SvnWcGeneration; import org.tmatesoft.svn.core.wc.SVNRevision; -import org.tmatesoft.svn.core.wc.SVNUpdateClient; -import org.tmatesoft.svn.core.wc.SVNWCClient; +import org.tmatesoft.svn.core.wc2.SvnTarget; import java.io.File; @@ -56,14 +58,14 @@ public class ShareProjectAction extends BasicAction { Presentation presentation = e.getPresentation(); final DataContext dataContext = e.getDataContext(); - Project project = PlatformDataKeys.PROJECT.getData(dataContext); + Project project = CommonDataKeys.PROJECT.getData(dataContext); if ((project == null) || (ProjectLevelVcsManager.getInstance(project).isBackgroundVcsOperationRunning())) { presentation.setEnabled(false); presentation.setVisible(false); return; } - VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); + VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); if (files == null || files.length == 0) { presentation.setEnabled(false); presentation.setVisible(false); @@ -104,7 +106,7 @@ public class ShareProjectAction extends BasicAction { final String parent = shareDialog.getSelectedURL(); if (shareDialog.isOK() && parent != null) { final Ref<Boolean> actionStarted = new Ref<Boolean>(Boolean.TRUE); - final SVNException[] error = new SVNException[1]; + final Exception[] error = new Exception[1]; final ShareDialog.ShareTarget shareTarget = shareDialog.getShareTarget(); final ProgressManager progressManager = ProgressManager.getInstance(); @@ -120,19 +122,23 @@ public class ShareProjectAction extends BasicAction { } } + final WorkingCopyFormat format = SvnCheckoutProvider.promptForWCopyFormat(VfsUtilCore.virtualToIoFile(file), project); + actionStarted.set(format != WorkingCopyFormat.UNKNOWN); + // means operation cancelled + if (format == WorkingCopyFormat.UNKNOWN) { + return true; + } + ExclusiveBackgroundVcsAction.run(project, new Runnable() { public void run() { progressManager.runProcessWithProgressSynchronously(new Runnable() { public void run() { try { final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); - final File path = new File(file.getPath()); - if (! SvnCheckoutProvider.promptForWCFormatAndSelect(path, project)) { - // action cancelled - actionStarted.set(Boolean.FALSE); - return; - } + + SvnWorkingCopyFormatHolder.setPresetFormat(format); + final SVNURL parenUrl = SVNURL.parseURIEncoded(parent); final SVNURL checkoutUrl; final SVNRevision revision; @@ -160,16 +166,17 @@ public class ShareProjectAction extends BasicAction { indicator.checkCanceled(); indicator.setText(SvnBundle.message("share.directory.checkout.back.progress.text", checkoutUrl.toString())); } - final SVNUpdateClient client = activeVcs.createUpdateClient(); - if (! WorkingCopyFormat.ONE_DOT_SEVEN.equals(SvnWorkingCopyFormatHolder.getPresetFormat())) { - client.getOperationsFactory().setPrimaryWcGeneration(SvnWcGeneration.V16); - } - client.doCheckout(checkoutUrl, path, SVNRevision.UNDEFINED, revision, SVNDepth.INFINITY, false); - SvnWorkingCopyFormatHolder.setPresetFormat(null); - addRecursively(activeVcs, file); + final ClientFactory factory = activeVcs.getFactoryFromSettings(); + + factory.createCheckoutClient() + .checkout(SvnTarget.fromURL(checkoutUrl), path, revision, SVNDepth.INFINITY, false, false, format, null); + addRecursively(activeVcs, factory, file); } catch (SVNException e) { error[0] = e; + } + catch (VcsException e) { + error[0] = e; } finally { activeVcs.invokeRefreshSvnRoots(); SvnWorkingCopyFormatHolder.setPresetFormat(null); @@ -226,6 +233,7 @@ public class ShareProjectAction extends BasicAction { indicator.checkCanceled(); indicator.setText(SvnBundle.message("share.directory.create.dir.progress.text", urlText)); } + // TODO: Implement with command line client final SVNCommitInfo info = vcs.createCommitClient().doMkDir(new SVNURL[]{url}, SvnBundle.message("share.directory.commit.message", folderName, ApplicationNamesInfo.getInstance().getFullProductName(), commitText)); @@ -237,17 +245,17 @@ public class ShareProjectAction extends BasicAction { VcsDirtyScopeManager.getInstance(project).dirDirtyRecursively(file); } - private static void addRecursively(final SvnVcs activeVcs, final VirtualFile file) throws SVNException { - final SVNWCClient wcClient = activeVcs.createWCClient(); + private static void addRecursively(@NotNull final SvnVcs activeVcs, @NotNull final ClientFactory factory, final VirtualFile file) + throws VcsException { final SvnExcludingIgnoredOperation operation = new SvnExcludingIgnoredOperation(activeVcs.getProject(), new SvnExcludingIgnoredOperation.Operation() { - public void doOperation(final VirtualFile virtualFile) throws SVNException { + public void doOperation(final VirtualFile virtualFile) throws VcsException { final File ioFile = new File(virtualFile.getPath()); final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); if (indicator != null) { indicator.checkCanceled(); indicator.setText(SvnBundle.message("share.or.import.add.progress.text", virtualFile.getPath())); } - wcClient.doAdd(ioFile, true, false, false, SVNDepth.EMPTY, false, false); + factory.createAddClient().add(ioFile, SVNDepth.EMPTY, false, false, true, null); } }, SVNDepth.INFINITY); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShareWholeProject.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShareWholeProject.java index 46e9710b10e8..8aaf8a3548b1 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShareWholeProject.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShareWholeProject.java @@ -57,7 +57,7 @@ public class ShareWholeProject extends AnAction implements DumbAware { public void execute(final AnActionEvent e) { final DataContext dataContext = e.getDataContext(); - myProject = PlatformDataKeys.PROJECT.getData(dataContext); + myProject = CommonDataKeys.PROJECT.getData(dataContext); if (myProject == null || myProject.isDefault()) { // remain false return; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShowAllSubmittedFilesAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShowAllSubmittedFilesAction.java index c1835d501875..611bff6e452b 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShowAllSubmittedFilesAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShowAllSubmittedFilesAction.java @@ -17,6 +17,7 @@ package org.jetbrains.idea.svn.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; @@ -56,7 +57,7 @@ public class ShowAllSubmittedFilesAction extends AnAction implements DumbAware { public void update(AnActionEvent e) { super.update(e); - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) { e.getPresentation().setEnabled(false); return; @@ -66,7 +67,7 @@ public class ShowAllSubmittedFilesAction extends AnAction implements DumbAware { } public void actionPerformed(AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) return; final VcsFileRevision revision = e.getData(VcsDataKeys.VCS_FILE_REVISION); final VirtualFile revisionVirtualFile = e.getData(VcsDataKeys.VCS_VIRTUAL_FILE); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShowSvnMapAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShowSvnMapAction.java index 2d6efc338cba..bb564d0afa03 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShowSvnMapAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShowSvnMapAction.java @@ -17,6 +17,7 @@ package org.jetbrains.idea.svn.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.project.DumbAware; @@ -40,7 +41,7 @@ public class ShowSvnMapAction extends AnAction implements DumbAware { @Override public void update(final AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); final Presentation presentation = e.getPresentation(); presentation.setVisible(project != null); @@ -51,7 +52,7 @@ public class ShowSvnMapAction extends AnAction implements DumbAware { } public void actionPerformed(final AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) { return; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnExcludingIgnoredOperation.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnExcludingIgnoredOperation.java index f60e553332e3..49fdc0279dd5 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnExcludingIgnoredOperation.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnExcludingIgnoredOperation.java @@ -20,13 +20,13 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileVisitor; import org.jetbrains.annotations.NotNull; import org.tmatesoft.svn.core.SVNDepth; -import org.tmatesoft.svn.core.SVNException; public class SvnExcludingIgnoredOperation { private final Operation myImportAction; @@ -79,28 +79,28 @@ public class SvnExcludingIgnoredOperation { } } - private boolean operation(final VirtualFile file) throws SVNException { + private boolean operation(final VirtualFile file) throws VcsException { if (! myFilter.accept(file)) return false; myImportAction.doOperation(file); return true; } - private void executeDown(final VirtualFile file) throws SVNException { + private void executeDown(final VirtualFile file) throws VcsException { VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() { @Override public boolean visitFile(@NotNull VirtualFile file) { try { return operation(file); } - catch (SVNException e) { + catch (VcsException e) { throw new VisitorException(e); } } - }, SVNException.class); + }, VcsException.class); } - public void execute(final VirtualFile file) throws SVNException { + public void execute(final VirtualFile file) throws VcsException { if (SVNDepth.INFINITY.equals(myDepth)) { executeDown(file); return; @@ -123,6 +123,6 @@ public class SvnExcludingIgnoredOperation { } public interface Operation { - void doOperation(final VirtualFile file) throws SVNException; + void doOperation(final VirtualFile file) throws VcsException; } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java index 133bc6489c4e..4076a729d88a 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java @@ -1,9 +1,21 @@ package org.jetbrains.idea.svn.api; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vcs.VcsException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.SvnVcs; +import org.jetbrains.idea.svn.WorkingCopyFormat; +import org.jetbrains.idea.svn.commandLine.SvnBindException; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.wc.ISVNEventHandler; +import org.tmatesoft.svn.core.wc.SVNEvent; +import org.tmatesoft.svn.core.wc.SVNEventAction; import org.tmatesoft.svn.core.wc2.SvnTarget; +import java.io.File; +import java.util.Collection; + /** * @author Konstantin Kolosovsky. */ @@ -44,4 +56,27 @@ public abstract class BaseSvnClient implements SvnClient { throw new IllegalArgumentException("Target should be file " + target); } } + + protected void validateFormat(@NotNull WorkingCopyFormat format, @NotNull Collection<WorkingCopyFormat> supported) throws VcsException { + if (!supported.contains(format)) { + throw new VcsException( + String.format("%s format is not supported. Supported formats are: %s.", format.getName(), StringUtil.join(supported, ","))); + } + } + + protected static void callHandler(@Nullable ISVNEventHandler handler, @NotNull SVNEvent event) throws VcsException { + if (handler != null) { + try { + handler.handleEvent(event, 0); + } + catch (SVNException e) { + throw new SvnBindException(e); + } + } + } + + @NotNull + protected static SVNEvent createEvent(@NotNull File path, @Nullable SVNEventAction action) { + return new SVNEvent(path, null, null, 0, null, null, null, null, action, null, null, null, null, null, null); + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java index 27c0d1e30885..7f16724806b2 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java @@ -22,6 +22,7 @@ import org.jetbrains.idea.svn.portable.SvnWcClientI; import org.jetbrains.idea.svn.properties.PropertyClient; import org.jetbrains.idea.svn.revert.RevertClient; import org.jetbrains.idea.svn.update.RelocateClient; +import org.jetbrains.idea.svn.upgrade.UpgradeClient; /** * @author Konstantin Kolosovsky. @@ -51,6 +52,7 @@ public abstract class ClientFactory { protected VersionClient myVersionClient; protected ImportClient myImportClient; protected ExportClient myExportClient; + protected UpgradeClient myUpgradeClient; protected ClientFactory(@NotNull SvnVcs vcs) { myVcs = vcs; @@ -167,6 +169,11 @@ public abstract class ClientFactory { } @NotNull + public UpgradeClient createUpgradeClient() { + return prepare(myUpgradeClient); + } + + @NotNull protected <T extends SvnClient> T prepare(@NotNull T client) { client.setVcs(myVcs); client.setFactory(this); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java index 8b73377b6f9f..de5c33e2b9eb 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java @@ -23,6 +23,7 @@ import org.jetbrains.idea.svn.update.UpdateClient; import org.jetbrains.idea.svn.properties.CmdPropertyClient; import org.jetbrains.idea.svn.revert.CmdRevertClient; import org.jetbrains.idea.svn.update.CmdRelocateClient; +import org.jetbrains.idea.svn.upgrade.CmdUpgradeClient; /** * @author Konstantin Kolosovsky. @@ -53,6 +54,7 @@ public class CmdClientFactory extends ClientFactory { myVersionClient = new CmdVersionClient(); myImportClient = new CmdImportClient(); myExportClient = new CmdExportClient(); + myUpgradeClient = new CmdUpgradeClient(); statusClient = new SvnCommandLineStatusClient(myVcs); infoClient = new SvnCommandLineInfoClient(myVcs); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/Repository.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/Repository.java new file mode 100644 index 000000000000..4a697c2d7f34 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/Repository.java @@ -0,0 +1,21 @@ +package org.jetbrains.idea.svn.api; + +import org.jetbrains.annotations.NotNull; +import org.tmatesoft.svn.core.SVNURL; + +/** + * @author Konstantin Kolosovsky. + */ +public class Repository { + + @NotNull private final SVNURL myUrl; + + public Repository(@NotNull SVNURL url) { + myUrl = url; + } + + @NotNull + public SVNURL getUrl() { + return myUrl; + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java index 002820d47f9a..27e025cc57f3 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java @@ -23,6 +23,7 @@ import org.jetbrains.idea.svn.portable.SvnkitSvnWcClient; import org.jetbrains.idea.svn.properties.SvnKitPropertyClient; import org.jetbrains.idea.svn.revert.SvnKitRevertClient; import org.jetbrains.idea.svn.update.SvnKitRelocateClient; +import org.jetbrains.idea.svn.upgrade.SvnKitUpgradeClient; /** * @author Konstantin Kolosovsky. @@ -53,6 +54,7 @@ public class SvnKitClientFactory extends ClientFactory { myVersionClient = new SvnKitVersionClient(); myImportClient = new SvnKitImportClient(); myExportClient = new SvnKitExportClient(); + myUpgradeClient = new SvnKitUpgradeClient(); statusClient = new SvnkitSvnStatusClient(myVcs, null); infoClient = new SvnkitSvnWcClient(myVcs); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutClient.java index e7aa0299a00d..b31d0da1dc48 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutClient.java @@ -11,6 +11,7 @@ import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; import java.io.File; +import java.util.List; /** * @author Konstantin Kolosovsky. @@ -22,6 +23,9 @@ public interface CheckoutClient extends SvnClient { @Nullable SVNRevision revision, @Nullable SVNDepth depth, boolean ignoreExternals, - @Nullable WorkingCopyFormat format, + boolean force, + @NotNull WorkingCopyFormat format, @Nullable ISVNEventHandler handler) throws VcsException; + + List<WorkingCopyFormat> getSupportedFormats() throws VcsException; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CmdCheckoutClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CmdCheckoutClient.java index fe22fc817182..6e151e4a6ae8 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CmdCheckoutClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CmdCheckoutClient.java @@ -1,5 +1,6 @@ package org.jetbrains.idea.svn.checkout; +import com.intellij.openapi.util.Version; import com.intellij.openapi.vcs.VcsException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,22 +28,33 @@ public class CmdCheckoutClient extends BaseSvnClient implements CheckoutClient { @Nullable SVNRevision revision, @Nullable SVNDepth depth, boolean ignoreExternals, - @Nullable WorkingCopyFormat format, + boolean force, + @NotNull WorkingCopyFormat format, @Nullable ISVNEventHandler handler) throws VcsException { - List<String> parameters = new ArrayList<String>(); + validateFormat(format, getSupportedFormats()); - // TODO: check format + List<String> parameters = new ArrayList<String>(); CommandUtil.put(parameters, source); CommandUtil.put(parameters, destination, false); CommandUtil.put(parameters, depth); CommandUtil.put(parameters, revision); CommandUtil.put(parameters, ignoreExternals, "--ignore-externals"); - parameters.add("--force"); // this is to conform to currently used SVNKit behavior - allowUnversionedObstructions + CommandUtil.put(parameters, force, "--force"); // corresponds to "allowUnversionedObstructions" in SVNKit run(source, destination, handler, parameters); } + @Override + public List<WorkingCopyFormat> getSupportedFormats() throws VcsException { + ArrayList<WorkingCopyFormat> result = new ArrayList<WorkingCopyFormat>(); + + Version version = myFactory.createVersionClient().getVersion(); + result.add(WorkingCopyFormat.from(version)); + + return result; + } + private void run(@NotNull SvnTarget source, @NotNull File destination, @Nullable ISVNEventHandler handler, diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java index ff415a0c116f..891471e291c1 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java @@ -17,6 +17,7 @@ package org.jetbrains.idea.svn.checkout; import com.intellij.lifecycle.PeriodicalTasksCloser; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; @@ -26,6 +27,7 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vcs.CalledInAwt; import com.intellij.openapi.vcs.CheckoutProvider; import com.intellij.openapi.vcs.VcsConfiguration; import com.intellij.openapi.vcs.VcsException; @@ -34,6 +36,8 @@ import com.intellij.openapi.vcs.update.RefreshVFsSynchronously; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.StatusBar; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.*; @@ -42,6 +46,7 @@ import org.jetbrains.idea.svn.actions.SvnExcludingIgnoredOperation; import org.jetbrains.idea.svn.checkin.IdeaCommitHandler; import org.jetbrains.idea.svn.commandLine.CommitEventHandler; import org.jetbrains.idea.svn.dialogs.CheckoutDialog; +import org.jetbrains.idea.svn.dialogs.UpgradeFormatDialog; import org.tmatesoft.svn.core.SVNCancelException; import org.tmatesoft.svn.core.SVNDepth; import org.tmatesoft.svn.core.SVNException; @@ -51,10 +56,14 @@ import org.tmatesoft.svn.core.wc2.SvnTarget; import javax.swing.*; import java.io.File; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; public class SvnCheckoutProvider implements CheckoutProvider { public void doCheckout(@NotNull final Project project, Listener listener) { + // TODO: Several dialogs is invoked while dialog.show() - seems code should be rewritten to be more transparent CheckoutDialog dialog = new CheckoutDialog(project, listener); dialog.show(); } @@ -84,19 +93,16 @@ public class SvnCheckoutProvider implements CheckoutProvider { final Task.Backgroundable checkoutBackgroundTask = new Task.Backgroundable(project, SvnBundle.message("message.title.check.out"), true, VcsConfiguration.getInstance(project).getCheckoutOption()) { public void run(@NotNull final ProgressIndicator indicator) { - SvnWorkingCopyFormatHolder.setPresetFormat(selectedFormat); + final WorkingCopyFormat format = selectedFormat == null ? WorkingCopyFormat.UNKNOWN : selectedFormat; + + SvnWorkingCopyFormatHolder.setPresetFormat(format); SvnVcs vcs = SvnVcs.getInstance(project); - // TODO: made this way to preserve existing logic, but probably this check could be omitted as setPresetFormat(selectedFormat) invoked above - WorkingCopyFormat format = !WorkingCopyFormat.ONE_DOT_SEVEN.equals(SvnWorkingCopyFormatHolder.getPresetFormat()) - ? WorkingCopyFormat.ONE_DOT_SIX - : selectedFormat; ISVNEventHandler handler = new CheckoutEventHandler(vcs, false, ProgressManager.getInstance().getProgressIndicator()); ProgressManager.progress(SvnBundle.message("progress.text.checking.out", target.getAbsolutePath())); try { - // TODO: probably rewrite some logic to force ClientFactory provide supported versions (or create special client for that) vcs.getFactoryFromSettings().createCheckoutClient() - .checkout(SvnTarget.fromURL(SVNURL.parseURIEncoded(url)), target, revision, depth, ignoreExternals, format, handler); + .checkout(SvnTarget.fromURL(SVNURL.parseURIEncoded(url)), target, revision, depth, ignoreExternals, true, format, handler); ProgressManager.checkCanceled(); checkoutSuccessful.set(Boolean.TRUE); } @@ -168,22 +174,10 @@ public class SvnCheckoutProvider implements CheckoutProvider { } } - public static boolean promptForWCFormatAndSelect(final File target, final Project project) { - final WorkingCopyFormat result = promptForWCopyFormat(target, project); - if (result != WorkingCopyFormat.UNKNOWN) { - SvnWorkingCopyFormatHolder.setPresetFormat(result); - } - return result != WorkingCopyFormat.UNKNOWN; - } - + @CalledInAwt @NotNull - private static WorkingCopyFormat promptForWCopyFormat(final File target, final Project project) { - WorkingCopyFormat format = WorkingCopyFormat.UNKNOWN; - final Ref<Boolean> wasOk = new Ref<Boolean>(); - while ((format == WorkingCopyFormat.UNKNOWN) && (! Boolean.FALSE.equals(wasOk.get()))) { - format = SvnFormatSelector.showUpgradeDialog(target, project, true, WorkingCopyFormat.ONE_DOT_SEVEN, wasOk); - } - return Boolean.TRUE.equals(wasOk.get()) ? format : WorkingCopyFormat.UNKNOWN; + public static WorkingCopyFormat promptForWCopyFormat(final File target, final Project project) { + return new CheckoutFormatFromUserProvider(project, target).prompt(); } public static void doExport(final Project project, final File target, final SVNURL url, final SVNDepth depth, @@ -286,6 +280,80 @@ public class SvnCheckoutProvider implements CheckoutProvider { return "_Subversion"; } -} + public static class CheckoutFormatFromUserProvider { + @NotNull private final Project myProject; + @NotNull private final SvnVcs myVcs; + @NotNull private final File myPath; + + @NotNull private final AtomicReference<String> error; + + public CheckoutFormatFromUserProvider(@NotNull Project project, @NotNull File path) { + myProject = project; + myVcs = SvnVcs.getInstance(project); + myPath = path; + + error = new AtomicReference<String>(); + } + + @CalledInAwt + public WorkingCopyFormat prompt() { + assert !ApplicationManager.getApplication().isUnitTestMode(); + + final WorkingCopyFormat result = displayUpgradeDialog(WorkingCopyFormat.ONE_DOT_SEVEN); + + ApplicationManager.getApplication().getMessageBus().syncPublisher(SvnVcs.WC_CONVERTED).run(); + + return result; + } + + private WorkingCopyFormat displayUpgradeDialog(@NotNull WorkingCopyFormat defaultSelection) { + final UpgradeFormatDialog dialog = new UpgradeFormatDialog(myProject, myPath, false); + final ModalityState dialogState = ModalityState.any(); + + dialog.startLoading(); + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @Override + public void run() { + final List<WorkingCopyFormat> formats = loadSupportedFormats(); + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + final String errorMessage = error.get(); + + if (errorMessage != null) { + dialog.doCancelAction(); + Messages.showErrorDialog(SvnBundle.message("message.text.cannot.load.supported.formats", errorMessage), + SvnBundle.message("message.title.check.out")); + } + else { + dialog.setSupported(formats); + dialog.setData(ContainerUtil.getFirstItem(formats, WorkingCopyFormat.UNKNOWN)); + dialog.stopLoading(); + } + } + }, dialogState); + } + }); + + dialog.show(); + + return dialog.isOK() ? dialog.getUpgradeMode() : WorkingCopyFormat.UNKNOWN; + } + + private List<WorkingCopyFormat> loadSupportedFormats() { + List<WorkingCopyFormat> result; + + try { + result = myVcs.getFactoryFromSettings().createCheckoutClient().getSupportedFormats(); + } + catch (VcsException e) { + result = Collections.emptyList(); + error.set(e.getMessage()); + } + + return result; + } + } +}
\ No newline at end of file diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnKitCheckoutClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnKitCheckoutClient.java index ba46ec832b87..796d30a80a3a 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnKitCheckoutClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnKitCheckoutClient.java @@ -15,30 +15,41 @@ import org.tmatesoft.svn.core.wc.SVNUpdateClient; import org.tmatesoft.svn.core.wc2.SvnTarget; import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** * @author Konstantin Kolosovsky. */ public class SvnKitCheckoutClient extends BaseSvnClient implements CheckoutClient { + public static final List<WorkingCopyFormat> SUPPORTED_FORMATS; + + static { + List<WorkingCopyFormat> supportedFormats = new ArrayList<WorkingCopyFormat>(); + + supportedFormats.add(WorkingCopyFormat.ONE_DOT_SEVEN); + supportedFormats.add(WorkingCopyFormat.ONE_DOT_SIX); + + SUPPORTED_FORMATS = Collections.unmodifiableList(supportedFormats); + } + @Override public void checkout(@NotNull SvnTarget source, @NotNull File destination, @Nullable SVNRevision revision, @Nullable SVNDepth depth, boolean ignoreExternals, - @Nullable WorkingCopyFormat format, + boolean force, + @NotNull WorkingCopyFormat format, @Nullable ISVNEventHandler handler) throws VcsException { assertUrl(source); - - if (WorkingCopyFormat.ONE_DOT_EIGHT.equals(format)) { - throw new IllegalArgumentException("could not check out 1.8 format with SVNKit"); - } + validateFormat(format, getSupportedFormats()); SVNUpdateClient client = myVcs.createUpdateClient(); - // TODO: most likely we should compare directly with WorkingCopyFormat.ONE_DOT_SIX - if (!WorkingCopyFormat.ONE_DOT_SEVEN.equals(format)) { + if (WorkingCopyFormat.ONE_DOT_SIX.equals(format)) { client.getOperationsFactory().setPrimaryWcGeneration(SvnWcGeneration.V16); } @@ -46,10 +57,15 @@ public class SvnKitCheckoutClient extends BaseSvnClient implements CheckoutClien client.setEventHandler(handler); try { - client.doCheckout(source.getURL(), destination, source.getPegRevision(), revision, depth, true); + client.doCheckout(source.getURL(), destination, source.getPegRevision(), revision, depth, force); } catch (SVNException e) { throw new SvnBindException(e); } } + + @Override + public List<WorkingCopyFormat> getSupportedFormats() throws VcsException { + return SUPPORTED_FORMATS; + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java index 0279ebaf3467..db82214b2b18 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.RootUrlInfo; import org.jetbrains.idea.svn.SvnVcs; +import org.jetbrains.idea.svn.api.Repository; import org.jetbrains.idea.svn.checkin.IdeaSvnkitBasedAuthenticationCallback; import org.tmatesoft.svn.core.SVNDepth; import org.tmatesoft.svn.core.SVNException; @@ -215,19 +216,15 @@ public class CommandUtil { } private static SVNURL resolveRepositoryUrl(@NotNull SvnVcs vcs, @NotNull SvnCommandName name, @NotNull SvnTarget target) { - RootUrlInfo rootInfo = target.isFile() - ? vcs.getSvnFileUrlMapping().getWcRootForFilePath(target.getFile()) - : vcs.getSvnFileUrlMapping().getWcRootForUrl(target.getURL().toDecodedString()); - SVNURL repositoryUrl = rootInfo != null ? rootInfo.getRepositoryUrlUrl() : null; + UrlMappingRepositoryProvider urlMappingProvider = new UrlMappingRepositoryProvider(vcs, target); + InfoCommandRepositoryProvider infoCommandProvider = new InfoCommandRepositoryProvider(vcs, target); - // resolve repository url using "svn info" command except the case when that command is executing right now. - if (repositoryUrl == null && !SvnCommandName.info.equals(name)) { - SVNInfo info = getInfo(vcs, target); - - repositoryUrl = info != null ? info.getRepositoryRootURL() : null; + Repository repository = urlMappingProvider.get(); + if (repository == null && !SvnCommandName.info.equals(name)) { + repository = infoCommandProvider.get(); } - return repositoryUrl; + return repository != null ? repository.getUrl() : null; } @NotNull @@ -296,4 +293,67 @@ public class CommandUtil { } return contentsStatus; } + + public interface RepositoryProvider { + + @Nullable + Repository get(); + } + + public static abstract class BaseRepositoryProvider implements RepositoryProvider { + + @NotNull protected final SvnVcs myVcs; + @NotNull protected final SvnTarget myTarget; + + protected BaseRepositoryProvider(@NotNull SvnVcs vcs, @NotNull SvnTarget target) { + myVcs = vcs; + myTarget = target; + } + } + + public static class UrlMappingRepositoryProvider extends BaseRepositoryProvider { + + public UrlMappingRepositoryProvider(@NotNull SvnVcs vcs, @NotNull SvnTarget target) { + super(vcs, target); + } + + @Nullable + @Override + public Repository get() { + RootUrlInfo rootInfo = null; + + if (!myVcs.getProject().isDefault()) { + rootInfo = myTarget.isFile() + ? myVcs.getSvnFileUrlMapping().getWcRootForFilePath(myTarget.getFile()) + : myVcs.getSvnFileUrlMapping().getWcRootForUrl(myTarget.getURL().toDecodedString()); + } + + return rootInfo != null ? new Repository(rootInfo.getRepositoryUrlUrl()) : null; + } + } + + public static class InfoCommandRepositoryProvider extends BaseRepositoryProvider { + + public InfoCommandRepositoryProvider(@NotNull SvnVcs vcs, @NotNull SvnTarget target) { + super(vcs, target); + } + + @Nullable + @Override + public Repository get() { + Repository result; + + if (myTarget.isURL()) { + // TODO: Also could still execute info when target is url - either to use info for authentication or to just get correct repository + // TODO: url in case of "read" operations are allowed anonymously. + result = new Repository(myTarget.getURL()); + } + else { + SVNInfo info = getInfo(myVcs, myTarget); + result = info != null ? new Repository(info.getRepositoryRootURL()) : null; + } + + return result; + } + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java index 2f667d363067..8ae61d51df22 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java @@ -42,6 +42,7 @@ public abstract class SvnCommand { private final File myConfigDir; private boolean myIsDestroyed; + private boolean myNeedsDestroy; private int myExitCode; protected final GeneralCommandLine myCommandLine; private final File myWorkingDirectory; @@ -210,13 +211,31 @@ public abstract class SvnCommand { public void destroyProcess() { synchronized (myLock) { - if (! myIsDestroyed) { + myNeedsDestroy = true; + } + } + + /** + * ProcessHandler.destroyProcess() implementations could acquire read lock in its implementation - like OSProcessManager.getInstance(). + * Some commands are called under write lock - which is generally bad idea, but such logic is not refactored yet. + * To prevent deadlocks this method should only be called from thread that started the process. + */ + public void doDestroyProcess() { + synchronized (myLock) { + if (!myIsDestroyed) { + LOG.info("Destroying process by command: " + getCommandText()); myIsDestroyed = true; myHandler.destroyProcess(); } } } + public boolean needsDestroy() { + synchronized (myLock) { + return myNeedsDestroy; + } + } + public String getCommandText() { synchronized (myLock) { return myCommandLine.getCommandLineString(); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java index 9182d9371c4e..1932d041c26c 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java @@ -49,7 +49,8 @@ public enum SvnCommandName { lock("lock", true), unlock("unlock", true), importFolder("import", false), - export("export", false); + export("export", false), + upgrade("upgrade", true); private final String myName; private final boolean myWriteable; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java index 9cf56bbd5500..75ff08525af4 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java @@ -62,7 +62,8 @@ public class SvnLineCommand extends SvnCommand { public static final String AUTHENTICATION_REALM = "Authentication realm:"; public static final String CERTIFICATE_ERROR = "Error validating server certificate for"; public static final String PASSPHRASE_FOR = "Passphrase for"; - public static final String UNABLE_TO_CONNECT = "svn: E170001:"; + public static final String UNABLE_TO_CONNECT_CODE = "svn: E170001:"; + public static final String UNABLE_TO_CONNECT_MESSAGE = "Unable to connect to a repository"; public static final String CANNOT_AUTHENTICATE_TO_PROXY = "Could not authenticate to proxy server"; public static final String AUTHENTICATION_FAILED_MESSAGE = "Authentication failed"; @@ -216,7 +217,7 @@ public class SvnLineCommand extends SvnCommand { if (errText.startsWith(PASSPHRASE_FOR)) { return new PassphraseCallback(callback, url); } - if (errText.startsWith(UNABLE_TO_CONNECT) && errText.contains(CANNOT_AUTHENTICATE_TO_PROXY)) { + if (errText.startsWith(UNABLE_TO_CONNECT_CODE) && errText.contains(CANNOT_AUTHENTICATE_TO_PROXY)) { return new ProxyCallback(callback, url); } // http/https protocol invalid credentials @@ -228,6 +229,10 @@ public class SvnLineCommand extends SvnCommand { // svn protocol invalid credentials return new UsernamePasswordCallback(callback, url); } + // http/https protocol, svn 1.7, non-interactive + if (errText.contains(UNABLE_TO_CONNECT_MESSAGE)) { + return new UsernamePasswordCallback(callback, url); + } // https one-way protocol untrusted server certificate if (errText.contains(UNTRUSTED_SERVER_CERTIFICATE)) { return new CertificateCallbackCase(callback, url); @@ -469,23 +474,13 @@ public class SvnLineCommand extends SvnCommand { final String trim = text.trim(); // should end in 1 second errorReceived.set(true); - // TODO: destroy process here is called despite --non-interactive flag (so it is called even for 1.8) and then unnecessary - // TODO: cleanup is invoked - fix this - if (trim.startsWith(UNABLE_TO_CONNECT)) { - // wait for 3 lines of text then - if (myErrCnt >= 3) { - destroyProcess(); - } - } else if (trim.startsWith(PASSPHRASE_FOR) || myErrCnt >= 2) { - destroyProcess(); - } } super.onTextAvailable(text, outputType); } }; - //command.addParameters("--non-interactive"); command.addParameters(parameters); + command.addParameters("--non-interactive"); final AtomicReference<Throwable> exceptionRef = new AtomicReference<Throwable>(); // several threads command.addLineListener(new LineProcessEventListener() { @@ -503,6 +498,7 @@ public class SvnLineCommand extends SvnCommand { } listener.onLineAvailable(line, outputType); if (listener.isCanceled()) { + LOG.info("Cancelling command: " + command.getCommandText()); command.destroyProcess(); return; } @@ -530,9 +526,9 @@ public class SvnLineCommand extends SvnCommand { boolean finished; do { finished = command.waitFor(500); - if (!finished && errorReceived.get()) { + if (!finished && (errorReceived.get() || command.needsDestroy())) { command.waitFor(1000); - command.destroyProcess(); + command.doDestroyProcess(); break; } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java index f88c8ebf13eb..1ec176990c87 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java @@ -17,12 +17,14 @@ package org.jetbrains.idea.svn.dialogs; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vcs.ObjectsConvertor; +import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFocusManager; @@ -61,11 +63,13 @@ import java.awt.event.FocusEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.File; -import java.util.Collections; -import java.util.Comparator; +import java.util.*; import java.util.List; public class CopiesPanel { + + private static final Logger LOG = Logger.getInstance(CopiesPanel.class); + private final Project myProject; private MessageBusConnection myConnection; private SvnVcs myVcs; @@ -98,6 +102,7 @@ public class CopiesPanel { @Override public void run() { final List<WCInfo> infoList = myVcs.getAllWcInfos(); + final List<WorkingCopyFormat> supportedFormats = getSupportedFormats(); Runnable runnable = new Runnable() { @Override public void run() { @@ -117,7 +122,7 @@ public class CopiesPanel { myCurrentInfoList = newList; } Collections.sort(infoList, WCComparator.getInstance()); - updateList(infoList); + updateList(infoList, supportedFormats); myRefreshLabel.setEnabled(true); SwingUtilities.invokeLater(focus); } @@ -178,7 +183,7 @@ public class CopiesPanel { return myRefreshLabel; } - private void updateList(final List<WCInfo> infoList) { + private void updateList(@NotNull final List<WCInfo> infoList, @NotNull final List<WorkingCopyFormat> supportedFormats) { myPanel.removeAll(); final Insets nullIndent = new Insets(1, 3, 1, 0); final GridBagConstraints gb = @@ -217,7 +222,7 @@ public class CopiesPanel { SVNDepth.INFINITY, false, null, wcInfo.getFormat()); } } else if (CHANGE_FORMAT.equals(e.getDescription())) { - changeFormat(wcInfo); + changeFormat(wcInfo, supportedFormats); } else if (MERGE_FROM.equals(e.getDescription())) { if (! checkRoot(root, wcInfo.getPath(), " invoke Merge From")) return; mergeFrom(wcInfo, root, editorPane); @@ -237,7 +242,7 @@ public class CopiesPanel { } }); editorPane.setBorder(null); - editorPane.setText(formatWc(wcInfo)); + editorPane.setText(formatWc(wcInfo, supportedFormats)); final JPanel copyPanel = new JPanel(new GridBagLayout()); @@ -263,14 +268,14 @@ public class CopiesPanel { } @SuppressWarnings("MethodMayBeStatic") - private String formatWc(WCInfo info) { + private String formatWc(@NotNull WCInfo info, @NotNull List<WorkingCopyFormat> supportedFormats) { final StringBuilder sb = new StringBuilder().append("<html><head>").append(UIUtil.getCssFontDeclaration(UIUtil.getLabelFont())) .append("</head><body><table bgColor=\"").append(ColorUtil.toHex(UIUtil.getPanelBackground())).append("\">"); sb.append("<tr valign=\"top\"><td colspan=\"3\"><b>").append(info.getPath()).append("</b></td></tr>"); sb.append("<tr valign=\"top\"><td>URL:</td><td colspan=\"2\">").append(info.getRootUrl()).append("</td></tr>"); - if (! WorkingCopyFormat.ONE_DOT_SEVEN.equals(info.getFormat())) { - // can convert + Collection<WorkingCopyFormat> upgradeFormats = getUpgradeFormats(info, supportedFormats); + if (upgradeFormats.size() > 1) { sb.append("<tr valign=\"top\"><td>Format:</td><td>").append(info.getFormat().getName()).append("</td><td><a href=\""). append(CHANGE_FORMAT).append("\">Change</a></td></tr>"); } else { @@ -302,6 +307,33 @@ public class CopiesPanel { return sb.toString(); } + @NotNull + private List<WorkingCopyFormat> getSupportedFormats() { + List<WorkingCopyFormat> result = Collections.emptyList(); + + try { + result = myVcs.getFactory().createUpgradeClient().getSupportedFormats(); + } + catch (VcsException e) { + LOG.info(e); + } + + return result; + } + + public static Set<WorkingCopyFormat> getUpgradeFormats(@NotNull WCInfo info, @NotNull List<WorkingCopyFormat> supportedFormats) { + Set<WorkingCopyFormat> canUpgradeTo = EnumSet.noneOf(WorkingCopyFormat.class); + + for (WorkingCopyFormat format : supportedFormats) { + if (format.isOrGreater(info.getFormat())) { + canUpgradeTo.add(format); + } + } + canUpgradeTo.add(info.getFormat()); + + return canUpgradeTo; + } + private void mergeFrom(@NotNull final WCInfo wcInfo, @NotNull final VirtualFile root, @Nullable final Component mergeLabel) { SelectBranchPopup.showForBranchRoot(myProject, root, new SelectBranchPopup.BranchSelectedCallback() { @Override @@ -338,8 +370,10 @@ public class CopiesPanel { }); } - private void changeFormat(final WCInfo wcInfo) { + private void changeFormat(@NotNull final WCInfo wcInfo, @NotNull final List<WorkingCopyFormat> supportedFormats) { ChangeFormatDialog dialog = new ChangeFormatDialog(myProject, new File(wcInfo.getPath()), false, ! wcInfo.isIsWcRoot()); + + dialog.setSupported(supportedFormats); dialog.setData(wcInfo.getFormat()); dialog.show(); if (! dialog.isOK()) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/IntersectingLocalChangesPanel.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/IntersectingLocalChangesPanel.java index 925192bdd06c..60a5d798abeb 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/IntersectingLocalChangesPanel.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/IntersectingLocalChangesPanel.java @@ -66,7 +66,7 @@ public class IntersectingLocalChangesPanel { } public void calcData(DataKey key, DataSink sink) { - if (PlatformDataKeys.NAVIGATABLE_ARRAY.equals(key)) { + if (CommonDataKeys.NAVIGATABLE_ARRAY.equals(key)) { final TreePath[] treePaths = myJTree.getSelectionModel().getSelectionPaths(); final List<Navigatable> navigatables = new ArrayList<Navigatable>(treePaths.length); for (TreePath treePath : treePaths) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/MergeFromAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/MergeFromAction.java index c4c63a2cee30..ce9cc5a298c5 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/MergeFromAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/MergeFromAction.java @@ -16,6 +16,7 @@ package org.jetbrains.idea.svn.dialogs; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAwareAction; @@ -39,7 +40,7 @@ public class MergeFromAction extends DumbAwareAction { public void actionPerformed(AnActionEvent e) { if (! isEnabled(e)) return; final DataContext dc = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dc); + final Project project = CommonDataKeys.PROJECT.getData(dc); if (project == null) return; final ToolWindowManager manager = ToolWindowManager.getInstance(project); if (manager != null) { @@ -58,14 +59,14 @@ public class MergeFromAction extends DumbAwareAction { @Override public void update(AnActionEvent e) { final DataContext dc = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dc); + final Project project = CommonDataKeys.PROJECT.getData(dc); if (project == null || project.isDefault()) return; e.getPresentation().setVisible(isEnabled(e)); } private boolean isEnabled(AnActionEvent e) { final DataContext dc = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dc); + final Project project = CommonDataKeys.PROJECT.getData(dc); if (project == null || project.isDefault()) return false; final VirtualFile[] files = ProjectLevelVcsManager.getInstance(project).getRootsUnderVcs(SvnVcs.getInstance(project)); return files != null && files.length > 0; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/PropertiesComponent.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/PropertiesComponent.java index b59e2b3a90ac..81116e669870 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/PropertiesComponent.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/PropertiesComponent.java @@ -246,7 +246,7 @@ public class PropertiesComponent extends JPanel { } public void actionPerformed(AnActionEvent e) { - Project p = e.getData(PlatformDataKeys.PROJECT); + Project p = e.getData(CommonDataKeys.PROJECT); ToolWindowManager.getInstance(p).unregisterToolWindow(ID); } } @@ -300,7 +300,7 @@ public class PropertiesComponent extends JPanel { } public void actionPerformed(AnActionEvent e) { - Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); SVNPropertyData propValue = null; try { propValue = myVcs.getFactory(myFile).createPropertyClient() @@ -348,7 +348,7 @@ public class PropertiesComponent extends JPanel { } public void actionPerformed(AnActionEvent e) { - Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); SetPropertyDialog dialog = new SetPropertyDialog(project, new File[] {myFile}, null, myFile.isDirectory()); dialog.show(); @@ -372,7 +372,7 @@ public class PropertiesComponent extends JPanel { } public void actionPerformed(AnActionEvent e) { - Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); SetPropertyDialog dialog = new SetPropertyDialog(project, new File[] {myFile}, getSelectedPropertyName(), myFile.isDirectory()); dialog.show(); boolean recursive = false; @@ -411,12 +411,12 @@ public class PropertiesComponent extends JPanel { if (myVcs == null) { return; } - VirtualFile vf = PlatformDataKeys.VIRTUAL_FILE.getData(e.getDataContext()); + VirtualFile vf = CommonDataKeys.VIRTUAL_FILE.getData(e.getDataContext()); if (vf != null) { File f = new File(vf.getPath()); if (!f.equals(myFile)) { setFile(myVcs, f); - Project p = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + Project p = CommonDataKeys.PROJECT.getData(e.getDataContext()); ToolWindowManager.getInstance(p).getToolWindow(ID).setTitle(f.getName()); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserComponent.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserComponent.java index bd0ee4098d5f..78acfe32cf53 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserComponent.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserComponent.java @@ -16,6 +16,7 @@ package org.jetbrains.idea.svn.dialogs; import com.intellij.openapi.Disposable; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.fileEditor.OpenFileDescriptor; @@ -261,14 +262,14 @@ public class RepositoryBrowserComponent extends JPanel implements Disposable, Da @Nullable public Object getData(@NonNls String dataId) { - if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { + if (CommonDataKeys.NAVIGATABLE.is(dataId)) { final Project project = myVCS.getProject(); if (project == null || project.isDefault()) { return null; } final VirtualFile vcsFile = getSelectedVcsFile(); return vcsFile != null ? new OpenFileDescriptor(project, vcsFile) : null; - } else if (PlatformDataKeys.PROJECT.is(dataId)) { + } else if (CommonDataKeys.PROJECT.is(dataId)) { return myVCS.getProject(); } return null; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SvnFormatWorker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SvnFormatWorker.java index f1310cdd7fd9..d6ccdcf13e7d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SvnFormatWorker.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SvnFormatWorker.java @@ -37,7 +37,6 @@ import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.wc.ISVNEventHandler; import org.tmatesoft.svn.core.wc.SVNEvent; import org.tmatesoft.svn.core.wc.SVNEventAction; -import org.tmatesoft.svn.core.wc.SVNWCClient; import java.io.File; import java.util.ArrayList; @@ -122,20 +121,7 @@ public class SvnFormatWorker extends Task.Backgroundable { if (supportsChangelists) { myBeforeChangeLists = ChangeListManager.getInstance(myProject).getChangeListsCopy(); } - final SVNWCClient wcClient = myVcs.createWCClient(); - wcClient.setEventHandler(new ISVNEventHandler() { - @Override - public void handleEvent(SVNEvent event, double progress) throws SVNException { - if (SVNEventAction.UPGRADED_PATH.equals(event.getAction()) && event.getFile() != null) { - indicator.setText2("Upgraded path " + VcsUtil.getPathForProgressPresentation(event.getFile())); - } - } - @Override - public void checkCancelled() throws SVNCancelException { - indicator.checkCanceled(); - } - }); try { for (WCInfo wcInfo : myWcInfos) { File path = new File(wcInfo.getPath()); @@ -143,13 +129,13 @@ public class SvnFormatWorker extends Task.Backgroundable { path = SvnUtil.getWorkingCopyRoot(path); } try { - if (WorkingCopyFormat.ONE_DOT_SEVEN.equals(myNewFormat)) { - indicator.setText(SvnBundle.message("action.Subversion.cleanup.progress.text", path.getAbsolutePath())); - wcClient.doCleanup(path); - } - indicator.setText(SvnBundle.message("action.change.wcopy.format.task.progress.text", path.getAbsolutePath(), - SvnUtil.formatRepresentation(wcInfo.getFormat()), SvnUtil.formatRepresentation(myNewFormat))); - wcClient.doSetWCFormat(path, myNewFormat.getFormat()); + String cleanupMessage = SvnBundle.message("action.Subversion.cleanup.progress.text", path.getAbsolutePath()); + String upgradeMessage = SvnBundle.message("action.change.wcopy.format.task.progress.text", path.getAbsolutePath(), + SvnUtil.formatRepresentation(wcInfo.getFormat()), + SvnUtil.formatRepresentation(myNewFormat)); + ISVNEventHandler handler = createUpgradeHandler(indicator, cleanupMessage, upgradeMessage); + + myVcs.getFactory(path).createUpgradeClient().upgrade(path, myNewFormat, handler); } catch (Throwable e) { myExceptions.add(e); } @@ -166,4 +152,32 @@ public class SvnFormatWorker extends Task.Backgroundable { ApplicationManager.getApplication().getMessageBus().syncPublisher(SvnVcs.WC_CONVERTED).run(); } } + + private static ISVNEventHandler createUpgradeHandler(@NotNull final ProgressIndicator indicator, + @NotNull final String cleanupMessage, + @NotNull final String upgradeMessage) { + return new ISVNEventHandler() { + @Override + public void handleEvent(SVNEvent event, double progress) throws SVNException { + if (event.getFile() != null) { + if (SVNEventAction.UPGRADED_PATH.equals(event.getAction())) { + indicator.setText2("Upgraded path " + VcsUtil.getPathForProgressPresentation(event.getFile())); + } + // fake event indicating cleanup start + if (SVNEventAction.UPDATE_STARTED.equals(event.getAction())) { + indicator.setText(cleanupMessage); + } + // fake event indicating upgrade start + if (SVNEventAction.UPDATE_COMPLETED.equals(event.getAction())) { + indicator.setText(upgradeMessage); + } + } + } + + @Override + public void checkCancelled() throws SVNCancelException { + indicator.checkCanceled(); + } + }; + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java index cb2fcdaba0f1..28645fd623eb 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java @@ -19,6 +19,7 @@ import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.MultiLineLabelUI; +import com.intellij.ui.components.JBLoadingPanel; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,6 +31,7 @@ import javax.swing.*; import java.awt.*; import java.io.File; import java.util.ArrayList; +import java.util.Collection; import java.util.List; public class UpgradeFormatDialog extends DialogWrapper { @@ -37,6 +39,8 @@ public class UpgradeFormatDialog extends DialogWrapper { private ButtonGroup formatGroup = new ButtonGroup(); private List<JRadioButton> formatButtons = new ArrayList<JRadioButton>(); + private JBLoadingPanel myLoadingPanel; + protected File myPath; public UpgradeFormatDialog(Project project, File path, boolean canBeParent) { @@ -64,7 +68,7 @@ public class UpgradeFormatDialog extends DialogWrapper { return "svn.upgradeDialog"; } - public void setData(final WorkingCopyFormat selectedFormat) { + public void setData(@NotNull final WorkingCopyFormat selectedFormat) { for (JRadioButton button : formatButtons) { if (selectedFormat == getFormat(button)) { button.setSelected(true); @@ -73,6 +77,29 @@ public class UpgradeFormatDialog extends DialogWrapper { } } + public void setSupported(@NotNull Collection<WorkingCopyFormat> supported) { + for (JRadioButton button : formatButtons) { + button.setEnabled(supported.contains(getFormat(button))); + } + } + + public void startLoading() { + enableFormatButtons(false); + getOKAction().setEnabled(false); + myLoadingPanel.startLoading(); + } + + private void enableFormatButtons(boolean enabled) { + for (JRadioButton button : formatButtons) { + button.setEnabled(enabled); + } + } + + public void stopLoading() { + getOKAction().setEnabled(true); + myLoadingPanel.stopLoading(); + } + protected String getTopMessage(final String label) { return SvnBundle.message("label.configure." + label + ".label", ApplicationNamesInfo.getInstance().getFullProductName()); } @@ -115,7 +142,10 @@ public class UpgradeFormatDialog extends DialogWrapper { gb.gridy += 1; } - return panel; + myLoadingPanel = new JBLoadingPanel(new BorderLayout(), getDisposable()); + myLoadingPanel.add(panel, BorderLayout.CENTER); + + return myLoadingPanel; } private void registerFormat(@NotNull WorkingCopyFormat format, diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/MergeSourceDetailsAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/MergeSourceDetailsAction.java index 4c8766cc5135..6281aa0971a9 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/MergeSourceDetailsAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/MergeSourceDetailsAction.java @@ -17,6 +17,7 @@ package org.jetbrains.idea.svn.history; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.CustomShortcutSet; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAware; @@ -31,10 +32,12 @@ import java.awt.event.KeyEvent; public class MergeSourceDetailsAction extends AnAction implements DumbAware { + public MergeSourceDetailsAction() { + super("Show merge sources details", null, SvnIcons.MergeSourcesDetails); + } + @Override public void update(AnActionEvent e) { - e.getPresentation().setIcon(SvnIcons.MergeSourcesDetails); - e.getPresentation().setText("Show merge sources details"); e.getPresentation().setEnabled(enabled(e)); } @@ -43,7 +46,7 @@ public class MergeSourceDetailsAction extends AnAction implements DumbAware { } private boolean enabled(final AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) return false; final VirtualFile revisionVirtualFile = e.getData(VcsDataKeys.VCS_VIRTUAL_FILE); if (revisionVirtualFile == null) return false; @@ -56,7 +59,7 @@ public class MergeSourceDetailsAction extends AnAction implements DumbAware { public void actionPerformed(AnActionEvent e) { if (! enabled(e)) return; - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); final VcsFileRevision revision = e.getData(VcsDataKeys.VCS_FILE_REVISION); final VirtualFile revisionVirtualFile = e.getData(VcsDataKeys.VCS_VIRTUAL_FILE); SvnMergeSourceDetails.showMe(project, (SvnFileRevision) revision, revisionVirtualFile); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java index f45a2942b269..d2b820607ff4 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java @@ -17,6 +17,7 @@ package org.jetbrains.idea.svn.history; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.progress.ProgressIndicator; @@ -59,7 +60,7 @@ public class SvnEditCommitMessageAction extends AnAction { final boolean enabled = lists != null && lists.length == 1 && lists[0] instanceof SvnChangeList; if (! enabled) return; final SvnChangeList svnList = (SvnChangeList) lists[0]; - Project project = PlatformDataKeys.PROJECT.getData(dc); + Project project = CommonDataKeys.PROJECT.getData(dc); project = project == null ? ProjectManager.getInstance().getDefaultProject() : project; final Consumer<String> listener = VcsDataKeys.REMOTE_HISTORY_CHANGED_LISTENER.getData(dc); @@ -82,7 +83,7 @@ public class SvnEditCommitMessageAction extends AnAction { final ChangeList[] lists = VcsDataKeys.CHANGE_LISTS.getData(dc); final boolean enabled = lists != null && lists.length == 1 && lists[0] instanceof SvnChangeList; boolean visible = enabled; - Project project = PlatformDataKeys.PROJECT.getData(dc); + Project project = CommonDataKeys.PROJECT.getData(dc); if (project == null) { visible = VcsDataKeys.REMOTE_HISTORY_LOCATION.getData(dc) instanceof SvnRepositoryLocation; } else { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/CmdRevertClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/CmdRevertClient.java index 2548cecc9a5b..89626215fb1b 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/CmdRevertClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/CmdRevertClient.java @@ -60,8 +60,7 @@ public class CmdRevertClient extends BaseSvnClient implements RevertClient { String statusMessage = matcher.group(1); String path = matcher.group(2); - return new SVNEvent(new File(path), null, null, 0, null, null, null, null, createAction(statusMessage), null, null, null, null, null, - null); + return createEvent(new File(path), createAction(statusMessage)); } @Nullable diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/upgrade/CmdUpgradeClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/upgrade/CmdUpgradeClient.java new file mode 100644 index 000000000000..0e1a672bb1ef --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/upgrade/CmdUpgradeClient.java @@ -0,0 +1,118 @@ +package org.jetbrains.idea.svn.upgrade; + +import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vcs.VcsException; +import com.intellij.util.containers.Convertor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.WorkingCopyFormat; +import org.jetbrains.idea.svn.api.BaseSvnClient; +import org.jetbrains.idea.svn.api.FileStatusResultParser; +import org.jetbrains.idea.svn.commandLine.CommandUtil; +import org.jetbrains.idea.svn.commandLine.LineCommandListener; +import org.jetbrains.idea.svn.commandLine.SvnCommandName; +import org.tmatesoft.svn.core.wc.ISVNEventHandler; +import org.tmatesoft.svn.core.wc.SVNEvent; +import org.tmatesoft.svn.core.wc.SVNEventAction; +import org.tmatesoft.svn.core.wc2.SvnTarget; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author Konstantin Kolosovsky. + */ +public class CmdUpgradeClient extends BaseSvnClient implements UpgradeClient { + + private static final String STATUS = "\\s*(.+?)\\s*"; + private static final String PATH = "\\s*\'(.*?)\'\\s*"; + private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + PATH); + + @Override + public void upgrade(@NotNull File path, @NotNull WorkingCopyFormat format, @Nullable ISVNEventHandler handler) throws VcsException { + validateFormat(format, getSupportedFormats()); + + // fake event indicating upgrade start + callHandler(handler, createEvent(path, SVNEventAction.UPDATE_COMPLETED)); + + List<String> parameters = new ArrayList<String>(); + + CommandUtil.put(parameters, path); + + // TODO: Add general possibility to invoke "handler.checkCancelled" (process should be killed). But currently upgrade process is not + // TODO: cancellable from UI - and this makes sense. + // for 1.8 - no output + // for 1.7 - output in format "Upgraded '<path>'" + FileStatusResultParser parser = new FileStatusResultParser(CHANGED_PATH, handler, new UpgradeStatusConvertor()); + UpgradeLineCommandListener listener = new UpgradeLineCommandListener(parser); + + CommandUtil.execute(myVcs, SvnTarget.fromFile(path), SvnCommandName.upgrade, parameters, listener); + listener.throwIfException(); + } + + @Override + public List<WorkingCopyFormat> getSupportedFormats() throws VcsException { + List<WorkingCopyFormat> result = new ArrayList<WorkingCopyFormat>(); + + result.add(WorkingCopyFormat.from(myFactory.createVersionClient().getVersion())); + + return result; + } + + private static class UpgradeStatusConvertor implements Convertor<Matcher, SVNEvent> { + + public SVNEvent convert(@NotNull Matcher matcher) { + String statusMessage = matcher.group(1); + String path = matcher.group(2); + + return createEvent(new File(path), createAction(statusMessage)); + } + + @Nullable + public static SVNEventAction createAction(@NotNull String code) { + SVNEventAction result = null; + + if ("Upgraded".equals(code)) { + result = SVNEventAction.UPGRADED_PATH; + } + + return result; + } + } + + private static class UpgradeLineCommandListener extends LineCommandListener { + + @NotNull private final FileStatusResultParser parser; + @NotNull private final AtomicReference<VcsException> exception; + + private UpgradeLineCommandListener(@NotNull FileStatusResultParser parser) { + this.parser = parser; + exception = new AtomicReference<VcsException>(); + } + + @Override + public void onLineAvailable(String line, Key outputType) { + if (ProcessOutputTypes.STDOUT.equals(outputType)) { + try { + parser.onLine(line); + } + catch (VcsException e) { + exception.set(e); + } + } + } + + public void throwIfException() throws VcsException { + VcsException e = exception.get(); + + if (e != null) { + throw e; + } + } + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/upgrade/SvnKitUpgradeClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/upgrade/SvnKitUpgradeClient.java new file mode 100644 index 000000000000..1aa2ebd687ac --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/upgrade/SvnKitUpgradeClient.java @@ -0,0 +1,64 @@ +package org.jetbrains.idea.svn.upgrade; + +import com.intellij.openapi.vcs.VcsException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.WorkingCopyFormat; +import org.jetbrains.idea.svn.api.BaseSvnClient; +import org.jetbrains.idea.svn.checkout.SvnKitCheckoutClient; +import org.jetbrains.idea.svn.commandLine.SvnBindException; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.wc.ISVNEventHandler; +import org.tmatesoft.svn.core.wc.SVNEventAction; +import org.tmatesoft.svn.core.wc.SVNWCClient; + +import java.io.File; +import java.util.List; + +/** + * @author Konstantin Kolosovsky. + */ +public class SvnKitUpgradeClient extends BaseSvnClient implements UpgradeClient { + + @Override + public void upgrade(@NotNull File path, @NotNull WorkingCopyFormat format, @Nullable ISVNEventHandler handler) throws VcsException { + validateFormat(format, getSupportedFormats()); + + SVNWCClient client = myVcs.createWCClient(); + + client.setEventHandler(handler); + try { + cleanupIfNecessary(path, format, client, handler); + upgrade(path, format, client, handler); + } + catch (SVNException e) { + throw new SvnBindException(e); + } + } + + @Override + public List<WorkingCopyFormat> getSupportedFormats() throws VcsException { + return SvnKitCheckoutClient.SUPPORTED_FORMATS; + } + + private static void cleanupIfNecessary(@NotNull File path, + @NotNull WorkingCopyFormat format, + @NotNull SVNWCClient client, + @Nullable ISVNEventHandler handler) throws SVNException, VcsException { + // cleanup is executed only for SVNKit as it could handle both 1.6 and 1.7 formats + if (WorkingCopyFormat.ONE_DOT_SEVEN.equals(format)) { + // fake event indicating cleanup start + callHandler(handler, createEvent(path, SVNEventAction.UPDATE_STARTED)); + client.doCleanup(path); + } + } + + private static void upgrade(@NotNull File path, + @NotNull WorkingCopyFormat format, + @NotNull SVNWCClient client, + @Nullable ISVNEventHandler handler) throws SVNException, VcsException { + // fake event indicating upgrade start + callHandler(handler, createEvent(path, SVNEventAction.UPDATE_COMPLETED)); + client.doSetWCFormat(path, format.getFormat()); + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/upgrade/UpgradeClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/upgrade/UpgradeClient.java new file mode 100644 index 000000000000..2d22acf08c45 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/upgrade/UpgradeClient.java @@ -0,0 +1,21 @@ +package org.jetbrains.idea.svn.upgrade; + +import com.intellij.openapi.vcs.VcsException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.WorkingCopyFormat; +import org.jetbrains.idea.svn.api.SvnClient; +import org.tmatesoft.svn.core.wc.ISVNEventHandler; + +import java.io.File; +import java.util.List; + +/** + * @author Konstantin Kolosovsky. + */ +public interface UpgradeClient extends SvnClient { + + void upgrade(@NotNull File path, @NotNull WorkingCopyFormat format, @Nullable ISVNEventHandler handler) throws VcsException; + + List<WorkingCopyFormat> getSupportedFormats() throws VcsException; +} diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/SvnTestCase.java b/plugins/svn4idea/testSource/org/jetbrains/idea/SvnTestCase.java index d5a55520adae..00d96b882013 100644 --- a/plugins/svn4idea/testSource/org/jetbrains/idea/SvnTestCase.java +++ b/plugins/svn4idea/testSource/org/jetbrains/idea/SvnTestCase.java @@ -18,6 +18,7 @@ package org.jetbrains.idea; import com.intellij.execution.process.ProcessOutput; import com.intellij.ide.startup.impl.StartupManagerImpl; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; @@ -503,7 +504,7 @@ public abstract class SvnTestCase extends AbstractJunitVcsTestCase { @Nullable @Override public Object getData(@NonNls String dataId) { - if (PlatformDataKeys.PROJECT.is(dataId)) { + if (CommonDataKeys.PROJECT.is(dataId)) { return project; } return null; diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnAnnotationIsClosedTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnAnnotationIsClosedTest.java index c6795b034068..cc05bf67be0b 100644 --- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnAnnotationIsClosedTest.java +++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnAnnotationIsClosedTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,8 @@ package org.jetbrains.idea.svn; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsConfiguration; @@ -78,7 +78,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { checkin(); final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(tree.myS1File); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), tree.myS1File); annotation.setCloser(new Runnable() { @Override public void run() { @@ -117,7 +117,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { runInAndVerifyIgnoreOutput("up", "-r", "2"); final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(tree.myS1File); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), tree.myS1File); annotation.setCloser(new Runnable() { @Override public void run() { @@ -138,7 +138,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { @Nullable @Override public Object getData(@NonNls String dataId) { - if (PlatformDataKeys.PROJECT.is(dataId)) { + if (CommonDataKeys.PROJECT.is(dataId)) { return myProject; } return null; @@ -162,7 +162,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { runInAndVerifyIgnoreOutput("up", "-r", "2"); // take #2 final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(tree.myS1File); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), tree.myS1File); annotation.setCloser(new Runnable() { @Override public void run() { @@ -185,7 +185,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { @Nullable @Override public Object getData(@NonNls String dataId) { - if (PlatformDataKeys.PROJECT.is(dataId)) { + if (CommonDataKeys.PROJECT.is(dataId)) { return myProject; } return null; @@ -209,7 +209,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { runInAndVerifyIgnoreOutput("up", "-r", "2"); // take #2 final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(tree.myS1File); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), tree.myS1File); annotation.setCloser(new Runnable() { @Override public void run() { @@ -244,7 +244,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { checkin(); final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(tree.myS1File); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), tree.myS1File); annotation.setCloser(new Runnable() { @Override public void run() { @@ -276,7 +276,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { editFileInCommand(myProject, tree.myS1File, "1\n2\n3**\n4++\n"); final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(tree.myS1File); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), tree.myS1File); annotation.setCloser(new Runnable() { @Override public void run() { @@ -304,7 +304,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { checkin(); //#3 final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(tree.myS1File); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), tree.myS1File); annotation.setCloser(new Runnable() { @Override public void run() { @@ -375,7 +375,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { // then annotate both final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(vf1); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), vf1); annotation.setCloser(new Runnable() { @Override public void run() { @@ -385,7 +385,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { }); listener.registerAnnotation(vf1, annotation); - final FileAnnotation annotation1 = myVcs.getAnnotationProvider().annotate(vf2); + final FileAnnotation annotation1 = createTestAnnotation(myVcs.getAnnotationProvider(), vf2); annotation1.setCloser(new Runnable() { @Override public void run() { diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnConcurrentChangeListManagerTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnConcurrentChangeListManagerTest.java index 4d41c33d544d..8a672fddb061 100644 --- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnConcurrentChangeListManagerTest.java +++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnConcurrentChangeListManagerTest.java @@ -36,7 +36,7 @@ public class SvnConcurrentChangeListManagerTest extends Svn17TestCase { @Override public void setUp() throws Exception { super.setUp(); - myDefaulListName = VcsBundle.message("changes.default.changlist.name"); + myDefaulListName = VcsBundle.message("changes.default.changelist.name"); myScheme = new DuringChangeListManagerUpdateTestScheme(myProject, myTempDirFixture.getTempDirPath()); } diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnAnnotationIsClosedTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnAnnotationIsClosedTest.java index ee6de3928a44..ed5eb0b33c1a 100644 --- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnAnnotationIsClosedTest.java +++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnAnnotationIsClosedTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -74,7 +74,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { checkin(); final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(tree.myS1File); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), tree.myS1File); annotation.setCloser(new Runnable() { @Override public void run() { @@ -113,7 +113,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { runInAndVerifyIgnoreOutput("up", "-r", "2"); final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(tree.myS1File); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), tree.myS1File); annotation.setCloser(new Runnable() { @Override public void run() { @@ -141,7 +141,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { runInAndVerifyIgnoreOutput("up", "-r", "2"); // take #2 final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(tree.myS1File); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), tree.myS1File); annotation.setCloser(new Runnable() { @Override public void run() { @@ -171,7 +171,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { runInAndVerifyIgnoreOutput("up", "-r", "2"); // take #2 final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(tree.myS1File); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), tree.myS1File); annotation.setCloser(new Runnable() { @Override public void run() { @@ -206,7 +206,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { checkin(); final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(tree.myS1File); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), tree.myS1File); annotation.setCloser(new Runnable() { @Override public void run() { @@ -238,7 +238,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { editFileInCommand(myProject, tree.myS1File, "1\n2\n3**\n4++\n"); final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(tree.myS1File); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), tree.myS1File); annotation.setCloser(new Runnable() { @Override public void run() { @@ -266,7 +266,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { checkin(); //#3 final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(tree.myS1File); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), tree.myS1File); annotation.setCloser(new Runnable() { @Override public void run() { @@ -337,7 +337,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { // then annotate both final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener(); - final FileAnnotation annotation = myVcs.getAnnotationProvider().annotate(vf1); + final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), vf1); annotation.setCloser(new Runnable() { @Override public void run() { @@ -347,7 +347,7 @@ public class SvnAnnotationIsClosedTest extends Svn17TestCase { }); listener.registerAnnotation(vf1, annotation); - final FileAnnotation annotation1 = myVcs.getAnnotationProvider().annotate(vf2); + final FileAnnotation annotation1 = createTestAnnotation(myVcs.getAnnotationProvider(), vf2); annotation1.setCloser(new Runnable() { @Override public void run() { diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnConcurrentChangeListManagerTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnConcurrentChangeListManagerTest.java index d4f0a90510e7..2cc1c26c4b9e 100644 --- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnConcurrentChangeListManagerTest.java +++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnConcurrentChangeListManagerTest.java @@ -36,7 +36,7 @@ public class SvnConcurrentChangeListManagerTest extends Svn16TestCase { @Override public void setUp() throws Exception { super.setUp(); - myDefaulListName = VcsBundle.message("changes.default.changlist.name"); + myDefaulListName = VcsBundle.message("changes.default.changelist.name"); myScheme = new DuringChangeListManagerUpdateTestScheme(myProject, myTempDirFixture.getTempDirPath()); } diff --git a/plugins/tasks/tasks-core/src/META-INF/plugin.xml b/plugins/tasks/tasks-core/src/META-INF/plugin.xml index 60313b578bfc..328fc1d94fff 100644 --- a/plugins/tasks/tasks-core/src/META-INF/plugin.xml +++ b/plugins/tasks/tasks-core/src/META-INF/plugin.xml @@ -134,6 +134,14 @@ implementationClass="com.intellij.tasks.jira.jql.codeinsight.JqlCompletionContributor"/> <checkinHandlerFactory implementation="com.intellij.tasks.impl.TaskCheckinHandlerFactory"/> + + <!-- YouTrack support --> + <!--<annotator language="TEXT" implementationClass="com.intellij.tasks.youtrack.lang.YouTrackHighlightingAnnotator"/>--> + <fileTypeFactory implementation="com.intellij.tasks.youtrack.lang.YouTrackFileTypeFactory"/> + <lang.parserDefinition language="YouTrack" implementationClass="com.intellij.tasks.youtrack.lang.YouTrackParserDefinition"/> + <completion.contributor language="YouTrack" + implementationClass="com.intellij.tasks.youtrack.lang.codeinsight.YouTrackCompletionContributor"/> + <externalAnnotator language="YouTrack" implementationClass="com.intellij.tasks.youtrack.lang.YouTrackHighlightingAnnotator"/> </extensions> </idea-plugin> diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/AssociateWithTaskAction.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/AssociateWithTaskAction.java index bb96e1b2ebd7..35d72f57b2cb 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/AssociateWithTaskAction.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/AssociateWithTaskAction.java @@ -16,6 +16,7 @@ package com.intellij.tasks.actions; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.ToggleAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -46,7 +47,7 @@ public class AssociateWithTaskAction extends ToggleAction implements DumbAware { if (lists == null) { return false; } - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); TaskManager manager = TaskManager.getManager(project); for (ChangeList list : lists) { if (list instanceof LocalChangeList && manager.getAssociatedTask((LocalChangeList)list) == null) { @@ -62,7 +63,7 @@ public class AssociateWithTaskAction extends ToggleAction implements DumbAware { if (lists == null) { return; } - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); TaskManager manager = TaskManager.getManager(project); for (ChangeList list : lists) { if (list instanceof LocalChangeList) { diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/BaseTaskAction.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/BaseTaskAction.java index e616a17b0823..726fa61c244a 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/BaseTaskAction.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/BaseTaskAction.java @@ -18,6 +18,7 @@ package com.intellij.tasks.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; @@ -49,7 +50,7 @@ public abstract class BaseTaskAction extends AnAction implements DumbAware { @Nullable public static Project getProject(@Nullable AnActionEvent event) { - return event == null ? null : PlatformDataKeys.PROJECT.getData(event.getDataContext()); + return event == null ? null : CommonDataKeys.PROJECT.getData(event.getDataContext()); } @Nullable diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/CloseTaskAction.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/CloseTaskAction.java index d984f7efc0cb..a3f15037a6c6 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/CloseTaskAction.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/CloseTaskAction.java @@ -17,6 +17,7 @@ package com.intellij.tasks.actions; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.project.Project; @@ -35,7 +36,7 @@ import java.util.ArrayList; public class CloseTaskAction extends BaseTaskAction { public void actionPerformed(AnActionEvent e) { - Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); assert project != null; TaskManagerImpl taskManager = (TaskManagerImpl)TaskManager.getManager(project); LocalTask task = taskManager.getActiveTask(); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskInBrowserAction.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskInBrowserAction.java index a6fba225323b..9ec20128e9f6 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskInBrowserAction.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskInBrowserAction.java @@ -18,6 +18,7 @@ package com.intellij.tasks.actions; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.project.Project; @@ -54,7 +55,7 @@ public class OpenTaskInBrowserAction extends BaseTaskAction { @Nullable private static String getIssueUrl(AnActionEvent event) { - Project project = PlatformDataKeys.PROJECT.getData(event.getDataContext()); + Project project = CommonDataKeys.PROJECT.getData(event.getDataContext()); return project == null ? null : TaskManager.getManager(project).getActiveTask().getIssueUrl(); } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SwitchTaskAction.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SwitchTaskAction.java index ca473ff2e047..cf8b257dc810 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SwitchTaskAction.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SwitchTaskAction.java @@ -53,7 +53,7 @@ public class SwitchTaskAction extends BaseTaskAction { @Override public void actionPerformed(AnActionEvent e) { DataContext dataContext = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); assert project != null; ListPopupImpl popup = createPopup(dataContext, null, true); popup.showCenteredInCurrentWindow(project); @@ -62,7 +62,7 @@ public class SwitchTaskAction extends BaseTaskAction { public static ListPopupImpl createPopup(final DataContext dataContext, @Nullable final Runnable onDispose, boolean withTitle) { - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); final Ref<Boolean> shiftPressed = Ref.create(false); final Ref<JComponent> componentRef = Ref.create(); List<TaskListItem> items = project == null ? Collections.<TaskListItem>emptyList() : diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SwitchTaskCombo.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SwitchTaskCombo.java index 989a5e607ac0..f053f5012969 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SwitchTaskCombo.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SwitchTaskCombo.java @@ -79,7 +79,7 @@ public class SwitchTaskCombo extends ComboBoxAction implements DumbAware { @Override public void update(AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); Presentation presentation = e.getPresentation(); if (project == null || project.isDisposed() || (ActionPlaces.MAIN_MENU.equals(e.getPlace()) && findFrame(e) == null)) { presentation.setEnabled(false); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.java index e021c949891d..2d294e5b4acc 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.java @@ -13,10 +13,9 @@ import com.intellij.openapi.roots.ui.configuration.actions.IconWithTextAction; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.wm.IdeFocusManager; -import com.intellij.tasks.TaskRepositorySubtype; import com.intellij.tasks.TaskManager; import com.intellij.tasks.TaskRepository; +import com.intellij.tasks.TaskRepositorySubtype; import com.intellij.tasks.TaskRepositoryType; import com.intellij.tasks.impl.TaskManagerImpl; import com.intellij.ui.*; @@ -196,7 +195,7 @@ public class TaskRepositoriesConfigurable extends BaseConfigurable implements Co myRepositoryEditor.doLayout(); JComponent preferred = editor.getPreferredFocusedComponent(); if (preferred != null && requestFocus) { - IdeFocusManager.getInstance(myProject).requestFocus(preferred, false); +// IdeFocusManager.getInstance(myProject).requestFocus(preferred, false); } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java index 5c5f181de97a..4270254efd4a 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java @@ -142,6 +142,8 @@ public class JiraRepository extends BaseRepositoryImpl { throw e; } JsonObject object = JiraUtil.GSON.fromJson(responseBody, JsonObject.class); + // when JIRA 4.x support will be dropped 'versionNumber' array in response + // may be used instead version string parsing return JiraRestApi.fromJiraVersion(object.get("version").getAsString(), this); } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraVersion.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraVersion.java index 41e69820c183..83519590cd33 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraVersion.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraVersion.java @@ -1,6 +1,7 @@ package com.intellij.tasks.jira; +import com.intellij.util.text.VersionComparatorUtil; import org.jetbrains.annotations.NotNull; import java.util.regex.Matcher; @@ -9,10 +10,11 @@ import java.util.regex.Pattern; /** * @author Mikhail Golubev */ -public class JiraVersion { - private static final Pattern VERSION_PATTERN = Pattern.compile("(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?"); +public class JiraVersion implements Comparable<JiraVersion> { + // Fix for IDEA-113944 + private static final Pattern VERSION_PATTERN = Pattern.compile("(\\d+)(?:[^\\d]+(\\d+))?(?:[^\\d]+(\\d+))?.*"); - private final int myMajorNumber, myMinorNumber, myBuildNumber; + private final int myMajorNumber, myMinorNumber, myMicroNumber; public JiraVersion(int majorNumber) { this(majorNumber, 0, 0); @@ -22,10 +24,10 @@ public class JiraVersion { this(majorNumber, minorNumber, 0); } - public JiraVersion(int majorNumber, int minorNumber, int buildNumber) { + public JiraVersion(int majorNumber, int minorNumber, int microNumber) { myMajorNumber = majorNumber; myMinorNumber = minorNumber; - myBuildNumber = buildNumber; + myMicroNumber = microNumber; } public JiraVersion(@NotNull String version) { @@ -35,7 +37,7 @@ public class JiraVersion { } myMajorNumber = m.group(1) == null ? 0 : Integer.parseInt(m.group(1)); myMinorNumber = m.group(2) == null ? 0 : Integer.parseInt(m.group(2)); - myBuildNumber = m.group(3) == null ? 0 : Integer.parseInt(m.group(3)); + myMicroNumber = m.group(3) == null ? 0 : Integer.parseInt(m.group(3)); } public int getMajorNumber() { @@ -46,12 +48,17 @@ public class JiraVersion { return myMinorNumber; } - public int getBuildNumber() { - return myBuildNumber; + public int getMicroNumber() { + return myMicroNumber; } @Override public String toString() { - return String.format("%d.%d.%d", myMajorNumber, myMinorNumber, myBuildNumber); + return String.format("%d.%d.%d", myMajorNumber, myMinorNumber, myMicroNumber); + } + + @Override + public int compareTo(@NotNull JiraVersion o) { + return VersionComparatorUtil.compare(toString(), o.toString()); } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackIntellisense.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackIntellisense.java new file mode 100644 index 000000000000..0b803eb68130 --- /dev/null +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackIntellisense.java @@ -0,0 +1,285 @@ +package com.intellij.tasks.youtrack; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; +import com.intellij.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.TextRange; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.hash.LinkedHashMap; +import org.jdom.Element; +import org.jdom.input.SAXBuilder; +import org.jdom.output.Format; +import org.jdom.output.XMLOutputter; +import org.jetbrains.annotations.NotNull; + +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * Auxiliary class for extracting data from YouTrack intellisense responses. + * See http://confluence.jetbrains.com/display/YTD5/Intellisense+for+issue+search for format details. + * <p/> + * It also provides two additional classes to represent tokens highlighting and + * available completion items from response: {@link com.intellij.tasks.youtrack.YouTrackIntellisense.HighlightRange} + * and {@link com.intellij.tasks.youtrack.YouTrackIntellisense.CompletionItem}. + * + * @author Mikhail Golubev + */ +public class YouTrackIntellisense { + + /** + * Key used to bind YouTrackIntellisense instance to specific PsiFile + */ + public static final Key<YouTrackIntellisense> INTELLISENSE_KEY = Key.create("youtrack.intellisense"); + + private static final Logger LOG = Logger.getInstance(YouTrackIntellisense.class); + + public static final String INTELLISENSE_RESOURCE = "/rest/issue/intellisense"; + private static final Map<String, TextAttributes> TEXT_ATTRIBUTES = ContainerUtil.newHashMap( + Pair.create("field", DefaultLanguageHighlighterColors.CONSTANT.getDefaultAttributes()), + Pair.create("keyword", DefaultLanguageHighlighterColors.KEYWORD.getDefaultAttributes()), + Pair.create("string", DefaultLanguageHighlighterColors.STRING.getDefaultAttributes()), + Pair.create("error", HighlighterColors.BAD_CHARACTER.getDefaultAttributes()) + ); + private static final int CACHE_SIZE = 30; + + private static class SizeLimitedCache<K, V> extends LinkedHashMap<K, V> { + private final int myMaxSize; + + private SizeLimitedCache(int max) { + super((int)(max / 0.75) + 1); + myMaxSize = max; + } + + @Override + protected boolean removeEldestEntry(Map.Entry<K, V> eldest, K key, V value) { + return size() > myMaxSize; + } + } + + private static final Map<Pair<String, Integer>, Response> ourCache = + Collections.synchronizedMap(new SizeLimitedCache<Pair<String, Integer>, Response>(CACHE_SIZE)); + + @NotNull + private static TextAttributes getAttributeByStyleClass(@NotNull String styleClass) { + final TextAttributes attr = TEXT_ATTRIBUTES.get(styleClass); + return attr == null ? HighlighterColors.TEXT.getDefaultAttributes() : attr; + } + + @NotNull + public List<HighlightRange> fetchHighlighting(@NotNull String query, int caret) throws Exception { + LOG.debug("Requesting highlighting"); + return fetch(query, caret, true).getHighlightRanges(); + } + + @NotNull + public List<CompletionItem> fetchCompletion(@NotNull String query, int caret) throws Exception { + LOG.debug("Requesting completion"); + return fetch(query, caret, false).getCompletionItems(); + } + + private final YouTrackRepository myRepository; + + public YouTrackIntellisense(@NotNull YouTrackRepository repository) { + myRepository = repository; + } + + @NotNull + private Response fetch(@NotNull String query, int caret, boolean ignoreCaret) throws Exception { + LOG.debug("Query: '" + query + "' caret at: " + caret); + final Pair<String, Integer> lookup = Pair.create(query, caret); + Response response = null; + if (ignoreCaret) { + for (Pair<String, Integer> pair : ourCache.keySet()) { + if (pair.getFirst().equals(query)) { + response = ourCache.get(pair); + break; + } + } + } + else { + response = ourCache.get(lookup); + } + LOG.debug("Cache " + (response != null? "hit" : "miss")); + if (response == null) { + final String url = String.format("%s?filter=%s&caret=%d", INTELLISENSE_RESOURCE, URLEncoder.encode(query, "utf-8"), caret); + final long startTime = System.currentTimeMillis(); + response = new Response(myRepository.doREST(url, false).getResponseBodyAsStream()); + LOG.debug(String.format("Intellisense request to YouTrack took %d ms to complete", System.currentTimeMillis() - startTime)); + ourCache.put(lookup, response); + } + return response; + } + + public YouTrackRepository getRepository() { + return myRepository; + } + + /** + * Main wrapper around "IntelliSense" element in YouTrack response. It delegates further parsing + * to {@link com.intellij.tasks.youtrack.YouTrackIntellisense.HighlightRange} and + * {@link com.intellij.tasks.youtrack.YouTrackIntellisense.CompletionItem} + */ + public static class Response { + + private List<HighlightRange> myHighlightRanges; + private List<CompletionItem> myCompletionItems; + + public Response(@NotNull InputStream stream) throws Exception { + final Element root = new SAXBuilder().build(stream).getRootElement(); + if (LOG.isDebugEnabled()) { + LOG.debug("Response content: \n" + new XMLOutputter(Format.getPrettyFormat()).outputString(root)); + } + @NotNull final Element highlight = root.getChild("highlight"); + //assert highlight != null : "no '/IntelliSense/highlight' element in YouTrack response"; + myHighlightRanges = ContainerUtil.map(highlight.getChildren("range"), new Function<Element, HighlightRange>() { + @Override + public HighlightRange fun(Element range) { + return new HighlightRange(range); + } + }); + + @NotNull final Element suggest = root.getChild("suggest"); + //assert suggest != null : "no '/IntelliSense/suggest' element in YouTrack response"; + myCompletionItems = ContainerUtil.map(suggest.getChildren("item"), new Function<Element, CompletionItem>() { + @Override + public CompletionItem fun(Element item) { + return new CompletionItem(item); + } + }); + } + + @NotNull + public List<HighlightRange> getHighlightRanges() { + return myHighlightRanges; + } + + @NotNull + public List<CompletionItem> getCompletionItems() { + return myCompletionItems; + } + } + + /** + * Wrapper around content of "highlight/range" element of YouTrack response + */ + public static class HighlightRange { + private int myStart, myEnd; + private String myStyleClass; + + public HighlightRange(@NotNull Element rangeElement) { + //assert "range".equals(rangeElement.getName()); + myStart = Integer.valueOf(rangeElement.getChildText("start")); + myEnd = Integer.valueOf(rangeElement.getChildText("end")); + myStyleClass = rangeElement.getChildText("styleClass"); + } + + public int getStart() { + return myStart; + } + + public int getEnd() { + return myEnd; + } + + @NotNull + public String getStyleClass() { + return myStyleClass; + } + + @NotNull + public TextRange getRange() { + return new TextRange(myStart, myEnd); + } + + @NotNull + public TextRange getTextRange() { + return TextRange.create(myStart, myEnd); + } + + @NotNull + public TextAttributes getTextAttributes() { + return getAttributeByStyleClass(myStyleClass); + } + } + + /** + * Wrapper around content of "suggest/item" element in YouTrack response + */ + public static class CompletionItem { + private TextRange myMatchRange, myCompletionRange; + private int myCaretPosition; + private String myDescription; + private String mySuffix; + private String myPrefix; + private String myOption; + private String myStyleClass; + + public CompletionItem(@NotNull Element item) { + //assert "item".equals(item.getName()) + final Element match = item.getChild("match"); + myMatchRange = new TextRange(Integer.parseInt(match.getAttributeValue("start")), + Integer.parseInt(match.getAttributeValue("end"))); + final Element completion = item.getChild("completion"); + myCompletionRange = new TextRange(Integer.parseInt(completion.getAttributeValue("start")), + Integer.parseInt(completion.getAttributeValue("end"))); + myDescription = item.getChildText("description"); + myOption = item.getChildText("option"); + mySuffix = item.getChildText("suffix"); + myPrefix = item.getChildText("prefix"); + myStyleClass = item.getChildText("styleClass"); + myCaretPosition = Integer.valueOf(item.getChildText("caret")); + } + + @NotNull + public TextRange getMatchRange() { + return myMatchRange; + } + + @NotNull + public TextRange getCompletionRange() { + return myCompletionRange; + } + + public int getCaretPosition() { + return myCaretPosition; + } + + @NotNull + public String getDescription() { + return myDescription; + } + + @NotNull + public String getSuffix() { + return mySuffix == null ? "" : mySuffix; + } + + @NotNull + public String getPrefix() { + return myPrefix == null? "" : myPrefix; + } + + @NotNull + public String getOption() { + return myOption; + } + + @NotNull + public String getStyleClass() { + return myStyleClass; + } + + @NotNull + TextAttributes getTextAttributes() { + return getAttributeByStyleClass(myStyleClass); + } + } +} diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java index 44fa5931e555..b8a180235475 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java @@ -152,7 +152,7 @@ public class YouTrackRepository extends BaseRepositoryImpl { } - private HttpMethod doREST(String request, boolean post) throws Exception { + HttpMethod doREST(String request, boolean post) throws Exception { HttpClient client = login(new PostMethod(getUrl() + "/rest/user/login")); String uri = getUrl() + request; HttpMethod method = post ? new PostMethod(uri) : new GetMethod(uri); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepositoryEditor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepositoryEditor.java index f187e43a1462..10e98cedf41d 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepositoryEditor.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepositoryEditor.java @@ -1,7 +1,13 @@ package com.intellij.tasks.youtrack; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; import com.intellij.tasks.config.BaseRepositoryEditor; +import com.intellij.tasks.youtrack.lang.YouTrackLanguage; +import com.intellij.ui.EditorTextField; +import com.intellij.ui.LanguageTextField; import com.intellij.ui.components.JBLabel; import com.intellij.util.Consumer; import com.intellij.util.ui.FormBuilder; @@ -13,12 +19,16 @@ import javax.swing.*; * @author Dmitry Avdeev */ public class YouTrackRepositoryEditor extends BaseRepositoryEditor<YouTrackRepository> { - private JTextField myDefaultSearch; + private static final Logger LOG = Logger.getInstance(YouTrackRepository.class); + + private EditorTextField myDefaultSearch; private JBLabel mySearchLabel; public YouTrackRepositoryEditor(final Project project, final YouTrackRepository repository, Consumer<YouTrackRepository> changeListener) { super(project, repository, changeListener); - myDefaultSearch.setText(repository.getDefaultSearch()); + final PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(myDefaultSearch.getDocument()); + assert file != null; + file.putUserData(YouTrackIntellisense.INTELLISENSE_KEY, new YouTrackIntellisense(myRepository)); } @Override @@ -31,7 +41,7 @@ public class YouTrackRepositoryEditor extends BaseRepositoryEditor<YouTrackRepos @Override protected JComponent createCustomPanel() { mySearchLabel = new JBLabel("Search:", SwingConstants.RIGHT); - myDefaultSearch = new JTextField(); + myDefaultSearch = new LanguageTextField(YouTrackLanguage.INSTANCE, myProject, myRepository.getDefaultSearch()); installListener(myDefaultSearch); return FormBuilder.createFormBuilder().addLabeledComponent(mySearchLabel, myDefaultSearch).getPanel(); } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackFile.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackFile.java new file mode 100644 index 000000000000..4390c801887d --- /dev/null +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackFile.java @@ -0,0 +1,21 @@ +package com.intellij.tasks.youtrack.lang; + +import com.intellij.extapi.psi.PsiFileBase; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.psi.FileViewProvider; +import org.jetbrains.annotations.NotNull; + +/** + * @author Mikhail Golubev + */ +public class YouTrackFile extends PsiFileBase { + public YouTrackFile(@NotNull FileViewProvider viewProvider) { + super(viewProvider, YouTrackLanguage.INSTANCE); + } + + @NotNull + @Override + public FileType getFileType() { + return YouTrackFileType.INSTANCE; + } +} diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackFileType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackFileType.java new file mode 100644 index 000000000000..01e0888018cc --- /dev/null +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackFileType.java @@ -0,0 +1,44 @@ +package com.intellij.tasks.youtrack.lang; + +import com.intellij.openapi.fileTypes.LanguageFileType; +import icons.TasksIcons; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** + * @author Mikhail Golubev + */ +public class YouTrackFileType extends LanguageFileType { + public static final YouTrackFileType INSTANCE = new YouTrackFileType(); + public static final String DEFAULT_EXTENSION = "youtrack"; + + public YouTrackFileType() { + super(YouTrackLanguage.INSTANCE); + } + + @NotNull + @Override + public String getName() { + return "YouTrack"; + } + + @NotNull + @Override + public String getDescription() { + return "YouTrack Query Language"; + } + + @NotNull + @Override + public String getDefaultExtension() { + return DEFAULT_EXTENSION; + } + + @Nullable + @Override + public Icon getIcon() { + return TasksIcons.Youtrack; + } +} diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackFileTypeFactory.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackFileTypeFactory.java new file mode 100644 index 000000000000..dd87968df809 --- /dev/null +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackFileTypeFactory.java @@ -0,0 +1,15 @@ +package com.intellij.tasks.youtrack.lang; + +import com.intellij.openapi.fileTypes.FileTypeConsumer; +import com.intellij.openapi.fileTypes.FileTypeFactory; +import org.jetbrains.annotations.NotNull; + +/** + * @author Mikhail Golubev + */ +public class YouTrackFileTypeFactory extends FileTypeFactory { + @Override + public void createFileTypes(@NotNull FileTypeConsumer consumer) { + consumer.consume(YouTrackFileType.INSTANCE, YouTrackFileType.DEFAULT_EXTENSION); + } +} diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackHighlightingAnnotator.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackHighlightingAnnotator.java new file mode 100644 index 000000000000..09af6363c19b --- /dev/null +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackHighlightingAnnotator.java @@ -0,0 +1,78 @@ +package com.intellij.tasks.youtrack.lang; + +import com.intellij.lang.annotation.Annotation; +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.lang.annotation.ExternalAnnotator; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.PsiFile; +import com.intellij.tasks.youtrack.YouTrackIntellisense; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; + +import static com.intellij.tasks.youtrack.YouTrackIntellisense.HighlightRange; +import static com.intellij.tasks.youtrack.lang.YouTrackHighlightingAnnotator.QueryInfo; + +/** + * @author Mikhail Golubev + */ +public class YouTrackHighlightingAnnotator extends ExternalAnnotator<QueryInfo, List<HighlightRange>> { + private static Logger LOG = Logger.getInstance(YouTrackHighlightingAnnotator.class); + + @Nullable + @Override + public QueryInfo collectInformation(@NotNull PsiFile file, @NotNull Editor editor, boolean hasErrors) { + final YouTrackIntellisense intellisense = file.getUserData(YouTrackIntellisense.INTELLISENSE_KEY); + if (intellisense == null || !intellisense.getRepository().isConfigured()) { + return null; + } + final String text = file.getText(); + final int offset = editor.getCaretModel().getOffset(); + //LOG.debug(String.format("Highlighting YouTrack query: '%s' (cursor=%d)", text, offset)); + return new QueryInfo(offset, text, intellisense); + } + + @Nullable + @Override + public List<HighlightRange> doAnnotate(QueryInfo collectedInfo) { + if (collectedInfo == null) { + return Collections.emptyList(); + } + final String query = collectedInfo.myText; + final int offset = collectedInfo.myCaretOffset; + try { + return collectedInfo.myIntellisense.fetchHighlighting(query, offset); + } + catch (Exception e) { + return Collections.emptyList(); + } + } + + @Override + public void apply(@NotNull PsiFile file, List<HighlightRange> ranges, @NotNull AnnotationHolder holder) { + for (HighlightRange range : ranges) { + if (range.getStyleClass().equals("error")) { + holder.createErrorAnnotation(range.getTextRange(), null); + } + else { + final Annotation infoAnnotation = holder.createInfoAnnotation(range.getTextRange(), null); + infoAnnotation.setEnforcedTextAttributes(range.getTextAttributes()); + } + } + } + + public static class QueryInfo { + private final int myCaretOffset; + private final String myText; + private final YouTrackIntellisense myIntellisense; + + private QueryInfo(int caretOffset, String text, YouTrackIntellisense repository) { + myCaretOffset = caretOffset; + myText = text; + myIntellisense = repository; + } + } +} diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackLanguage.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackLanguage.java new file mode 100644 index 000000000000..6f48659baea7 --- /dev/null +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackLanguage.java @@ -0,0 +1,21 @@ +package com.intellij.tasks.youtrack.lang; + +import com.intellij.lang.Language; + +/** + * @author Mikhail Golubev + */ +public class YouTrackLanguage extends Language { + public static YouTrackLanguage INSTANCE = new YouTrackLanguage(); + + private YouTrackLanguage() { + super("YouTrack"); + } + + @Override + public boolean isCaseSensitive() { + return false; + } + + +} diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackParserDefinition.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackParserDefinition.java new file mode 100644 index 000000000000..b50811fe4da9 --- /dev/null +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackParserDefinition.java @@ -0,0 +1,166 @@ +package com.intellij.tasks.youtrack.lang; + +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.intellij.lang.ASTNode; +import com.intellij.lang.ParserDefinition; +import com.intellij.lang.PsiBuilder; +import com.intellij.lang.PsiParser; +import com.intellij.lexer.Lexer; +import com.intellij.lexer.LexerBase; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.FileViewProvider; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.IFileElementType; +import com.intellij.psi.tree.TokenSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Mikhail Golubev + */ +public class YouTrackParserDefinition implements ParserDefinition { + private static final Logger LOG = Logger.getInstance(YouTrackParserDefinition.class); + + public static final IElementType ANY_TEXT = new IElementType("ANY_TEXT", YouTrackLanguage.INSTANCE); + public static final IElementType QUERY = new IElementType("QUERY", YouTrackLanguage.INSTANCE); + public static final IFileElementType FILE = new IFileElementType(YouTrackLanguage.INSTANCE); + + @NotNull + @Override + public Lexer createLexer(Project project) { + return new YouTrackMockLexer(); + } + + @Override + public PsiParser createParser(Project project) { + return new YouTrackMockParser(); + } + + @Override + public IFileElementType getFileNodeType() { + return FILE; + } + + @NotNull + @Override + public TokenSet getWhitespaceTokens() { + return TokenSet.EMPTY; + } + + @NotNull + @Override + public TokenSet getCommentTokens() { + return TokenSet.EMPTY; + } + + @NotNull + @Override + public TokenSet getStringLiteralElements() { + return TokenSet.EMPTY; + } + + @NotNull + @Override + public PsiElement createElement(ASTNode node) { + assert node.getElementType() == QUERY; + return new YouTrackQueryElement(node); + } + + @Override + public PsiFile createFile(FileViewProvider viewProvider) { + return new YouTrackFile(viewProvider); + } + + @Override + public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) { + return SpaceRequirements.MAY; + } + + /** + * Sole element that represents YouTrack query in PSI tree + */ + public static class YouTrackQueryElement extends ASTWrapperPsiElement { + YouTrackQueryElement(@NotNull ASTNode node) { + super(node); + } + } + + /** + * Tokenize whole query as single {@code ANY_TEXT} token + */ + private static class YouTrackMockLexer extends LexerBase { + private int myStart; + private int myEnd; + private CharSequence myBuffer; + + @Override + public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) { + //LOG.debug(String.format("buffer: '%s', start: %d, end: %d", buffer, startOffset, endOffset)); + myBuffer = buffer; + myStart = startOffset; + myEnd = endOffset; + } + + @Override + public int getState() { + return 0; + } + + @Nullable + @Override + public IElementType getTokenType() { + return myStart >= myEnd? null : ANY_TEXT; + } + + @Override + public int getTokenStart() { + return myStart; + } + + @Override + public int getTokenEnd() { + return myEnd; + } + + @Override + public void advance() { + myStart = myEnd; + } + + @NotNull + @Override + public CharSequence getBufferSequence() { + return myBuffer; + } + + @Override + public int getBufferEnd() { + return myEnd; + } + } + + + /** + * Parse whole YouTrack query as single {@code QUERY} element + */ + private static class YouTrackMockParser implements PsiParser { + + @NotNull + @Override + public ASTNode parse(IElementType root, PsiBuilder builder) { + PsiBuilder.Marker rootMarker = builder.mark(); + + PsiBuilder.Marker queryMarker = builder.mark(); + assert builder.getTokenType() == null || builder.getTokenType() == ANY_TEXT; + builder.advanceLexer(); + queryMarker.done(QUERY); + assert builder.eof(); + + rootMarker.done(root); + return builder.getTreeBuilt(); + } + } +} diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/codeinsight/YouTrackCompletionContributor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/codeinsight/YouTrackCompletionContributor.java new file mode 100644 index 000000000000..4b397e9ed825 --- /dev/null +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/codeinsight/YouTrackCompletionContributor.java @@ -0,0 +1,160 @@ +package com.intellij.tasks.youtrack.lang.codeinsight; + +import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.DebugUtil; +import com.intellij.tasks.youtrack.YouTrackIntellisense; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import static com.intellij.tasks.youtrack.YouTrackIntellisense.CompletionItem; + +/** + * @author Mikhail Golubev + */ +public class YouTrackCompletionContributor extends CompletionContributor { + private static final Logger LOG = Logger.getInstance(YouTrackCompletionContributor.class); + private static final int TIMEOUT = 2000; // ms + + private static final InsertHandler<LookupElement> INSERT_HANDLER = new MyInsertHandler(); + + @Override + public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) { + if (LOG.isDebugEnabled()) { + LOG.debug(DebugUtil.psiToString(parameters.getOriginalFile(), true)); + } + + super.fillCompletionVariants(parameters, result); + + PsiFile file = parameters.getOriginalFile(); + final YouTrackIntellisense intellisense = file.getUserData(YouTrackIntellisense.INTELLISENSE_KEY); + if (intellisense == null) { + return; + } + + final Application application = ApplicationManager.getApplication(); + Future<List<CompletionItem>> future = application.executeOnPooledThread(new Callable<List<CompletionItem>>() { + @Override + public List<CompletionItem> call() throws Exception { + return intellisense.fetchCompletion(parameters.getOriginalFile().getText(), parameters.getOffset()); + } + }); + try { + final List<CompletionItem> suggestions = future.get(TIMEOUT, TimeUnit.MILLISECONDS); + // actually backed by original CompletionResultSet + result = result.withPrefixMatcher(extractPrefix(parameters)).caseInsensitive(); + result.addAllElements(ContainerUtil.map(suggestions, new Function<CompletionItem, LookupElement>() { + @Override + public LookupElement fun(CompletionItem item) { + return LookupElementBuilder.create(item, item.getOption()) + .withTypeText(item.getDescription(), true) + .withInsertHandler(INSERT_HANDLER) + .withBoldness(item.getStyleClass().equals("keyword")); + } + })); + } + catch (Exception ignored) { + //noinspection InstanceofCatchParameter + if (ignored instanceof TimeoutException) { + LOG.debug(String.format("YouTrack request took more than %d ms to complete", TIMEOUT)); + } + LOG.debug(ignored); + } + } + + /** + * Find first word left boundary before cursor and strip leading braces and '#' signs + */ + @NotNull + private static String extractPrefix(CompletionParameters parameters) { + String text = parameters.getOriginalFile().getText(); + final int caretOffset = parameters.getOffset(); + if (text.isEmpty() || caretOffset == 0) { + return ""; + } + int stopAt = text.lastIndexOf('{', caretOffset - 1); + // caret isn't inside braces + if (stopAt <= text.lastIndexOf('}', caretOffset - 1)) { + // we stay right after colon + if (text.charAt(caretOffset - 1) == ':') { + stopAt = caretOffset - 1; + } + // use rightmost word boundary as last resort + else { + stopAt = text.lastIndexOf(' ', caretOffset - 1); + } + } + //int start = CharArrayUtil.shiftForward(text, lastSpace < 0 ? 0 : lastSpace + 1, "#{ "); + int prefixStart = stopAt + 1; + if (prefixStart < text.length() && text.charAt(prefixStart) == '#') { + prefixStart++; + } + return StringUtil.trimLeading(text.substring(prefixStart, caretOffset)); + } + + + /** + * Inserts additional braces around values that contains spaces, colon after attribute names + * and '#' before short-cut attributes if any + */ + private static class MyInsertHandler implements InsertHandler<LookupElement> { + @Override + public void handleInsert(InsertionContext context, LookupElement item) { + final CompletionItem completionItem = (CompletionItem)item.getObject(); + final Document document = context.getDocument(); + final Editor editor = context.getEditor(); + + context.commitDocument(); + context.setAddCompletionChar(false); + + final String prefix = completionItem.getPrefix(); + final String suffix = completionItem.getSuffix(); + String text = document.getText(); + int offset = context.getStartOffset(); + // skip possible spaces after '{', e.g. "{ My Project <caret>" + if (prefix.endsWith("{")) { + while (offset > prefix.length() && Character.isWhitespace(text.charAt(offset - 1))) { + offset--; + } + } + if (!prefix.isEmpty() && !hasPrefixAt(document.getText(), offset - prefix.length(), prefix)) { + document.insertString(offset, prefix); + } + offset = context.getTailOffset(); + text = document.getText(); + if (suffix.startsWith("} ")) { + while (offset < text.length() - suffix.length() && Character.isWhitespace(text.charAt(offset))) { + offset++; + } + } + if (!suffix.isEmpty() && !hasPrefixAt(text, offset, suffix)) { + document.insertString(offset, suffix); + } + editor.getCaretModel().moveToOffset(context.getTailOffset()); + } + } + + static boolean hasPrefixAt(String text, int offset, String prefix) { + if (text.isEmpty() || offset < 0 || offset >= text.length()) { + return false; + } + return text.regionMatches(true, offset, prefix, 0, prefix.length()); + } +} + + diff --git a/plugins/tasks/tasks-java/src/com/intellij/tasks/context/java/BreakpointsContextProvider.java b/plugins/tasks/tasks-java/src/com/intellij/tasks/context/java/BreakpointsContextProvider.java index fc0917ec9fa2..057aa1b748a6 100644 --- a/plugins/tasks/tasks-java/src/com/intellij/tasks/context/java/BreakpointsContextProvider.java +++ b/plugins/tasks/tasks-java/src/com/intellij/tasks/context/java/BreakpointsContextProvider.java @@ -17,10 +17,11 @@ package com.intellij.tasks.context.java; import com.intellij.debugger.DebuggerManager; -import com.intellij.debugger.ui.breakpoints.BreakpointManager; +import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.ui.breakpoints.Breakpoint; -import com.intellij.debugger.impl.DebuggerManagerImpl; +import com.intellij.debugger.ui.breakpoints.BreakpointManager; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; import com.intellij.tasks.context.WorkingContextProvider; @@ -53,15 +54,16 @@ public class BreakpointsContextProvider extends WorkingContextProvider { } public void saveContext(Element toElement) throws WriteExternalException { - myDebuggerManager.writeExternal(toElement); + ((DebuggerManagerEx)myDebuggerManager).getBreakpointManager().writeExternal(toElement); } public void loadContext(Element fromElement) throws InvalidDataException { - myDebuggerManager.readExternal(fromElement); + //noinspection unchecked + ((PersistentStateComponent<Element>)myDebuggerManager).loadState(fromElement); } public void clearContext() { - final BreakpointManager breakpointManager = ((DebuggerManagerImpl)myDebuggerManager).getBreakpointManager(); + final BreakpointManager breakpointManager = ((DebuggerManagerEx)myDebuggerManager).getBreakpointManager(); List<Breakpoint> breakpoints = breakpointManager.getBreakpoints(); for (final Breakpoint breakpoint : breakpoints) { ApplicationManager.getApplication().runWriteAction(new Runnable() { diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java index 75a792d7e493..3780bd89c15a 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java @@ -20,6 +20,7 @@ import com.intellij.tasks.TaskManagerTestCase; import com.intellij.tasks.TaskState; import com.intellij.tasks.jira.JiraRepository; import com.intellij.tasks.jira.JiraRepositoryType; +import com.intellij.tasks.jira.JiraVersion; import org.jetbrains.annotations.NonNls; /** @@ -115,6 +116,13 @@ public class JiraIntegrationTest extends TaskManagerTestCase { } } + public void testParseVersionNumbers() throws Exception { + assertEquals(new JiraVersion("6.1-OD-09-WN").toString(), "6.1.9"); + assertEquals(new JiraVersion("5.0.6").toString(), "5.0.6"); + assertEquals(new JiraVersion("4.4.5").toString(), "4.4.5"); + + } + @Override public void setUp() throws Exception { super.setUp(); diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java index b0f9cc32247f..5c7aa0e07a7a 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java @@ -249,7 +249,8 @@ class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider { @NotNull @Override public Color getDefaultBackground() { - return getGlobal().getColor(ConsoleViewContentType.CONSOLE_BACKGROUND_KEY); + Color color = getGlobal().getColor(ConsoleViewContentType.CONSOLE_BACKGROUND_KEY); + return color != null ? color : getGlobal().getDefaultBackground(); } @NotNull diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java index 8cb28eaa74f3..d8d98440a421 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java @@ -2,6 +2,7 @@ package org.jetbrains.plugins.terminal; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; @@ -30,7 +31,7 @@ public class OpenLocalTerminalAction extends AnAction implements DumbAware { } public void runLocalTerminal(AnActionEvent event) { - final Project project = event.getData(PlatformDataKeys.PROJECT); + final Project project = event.getData(CommonDataKeys.PROJECT); runLocalTerminal(project); } diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPatternConfigurationProducer.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPatternConfigurationProducer.java index cc6d307812d2..ff5adf190eec 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPatternConfigurationProducer.java +++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPatternConfigurationProducer.java @@ -27,6 +27,7 @@ import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.actions.ConfigurationContext; import com.intellij.execution.configurations.ModuleBasedConfiguration; import com.intellij.execution.junit.JUnitUtil; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.module.Module; @@ -98,7 +99,7 @@ public class TestNGPatternConfigurationProducer extends TestNGConfigurationProdu } return elements; } else { - final PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext); + final PsiFile file = CommonDataKeys.PSI_FILE.getData(dataContext); if (file instanceof PsiClassOwner) { for (PsiMember psiMember : collectTestMembers(((PsiClassOwner)file).getClasses())) { classes.add(((PsiClass)psiMember).getQualifiedName()); diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/actions/CreatePackageTestAction.java b/plugins/testng/src/com/theoryinpractice/testng/ui/actions/CreatePackageTestAction.java index 3ec023805e64..12dcc203219e 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/actions/CreatePackageTestAction.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/actions/CreatePackageTestAction.java @@ -20,6 +20,7 @@ import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.configurations.ConfigurationFactory; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.application.ApplicationManager; @@ -61,7 +62,7 @@ public class CreatePackageTestAction extends AnAction } PsiPackage getSelectedPackage(DataContext context) { - final PsiElement element = LangDataKeys.PSI_ELEMENT.getData(context); + final PsiElement element = CommonDataKeys.PSI_ELEMENT.getData(context); if (element == null) { return null; } diff --git a/plugins/testng/testSources/com/theoryinpractice/testng/configuration/ConfigurationsTest.java b/plugins/testng/testSources/com/theoryinpractice/testng/configuration/ConfigurationsTest.java index fae7cec4676c..16276d151d51 100644 --- a/plugins/testng/testSources/com/theoryinpractice/testng/configuration/ConfigurationsTest.java +++ b/plugins/testng/testSources/com/theoryinpractice/testng/configuration/ConfigurationsTest.java @@ -27,6 +27,7 @@ import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.actions.ConfigurationContext; import com.intellij.execution.actions.ConfigurationFromContext; import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.PluginPathManager; @@ -197,7 +198,7 @@ public class ConfigurationsTest { final MapDataContext dataContext = new MapDataContext(); - dataContext.put(PlatformDataKeys.PROJECT, project); + dataContext.put(CommonDataKeys.PROJECT, project); dataContext.put(LangDataKeys.MODULE, ModuleUtil.findModuleForPsiElement(psiClass)); dataContext.put(Location.DATA_KEY, PsiLocation.fromPsiElement(psiClass)); diff --git a/plugins/ui-designer-core/src/com/intellij/designer/inspection/AbstractQuickFixManager.java b/plugins/ui-designer-core/src/com/intellij/designer/inspection/AbstractQuickFixManager.java index 5f96cad473e3..bf8e071ad8ce 100644 --- a/plugins/ui-designer-core/src/com/intellij/designer/inspection/AbstractQuickFixManager.java +++ b/plugins/ui-designer-core/src/com/intellij/designer/inspection/AbstractQuickFixManager.java @@ -116,7 +116,7 @@ public abstract class AbstractQuickFixManager { @Override public void update(AnActionEvent e) { - e.getPresentation().setEnabled(e.getData(PlatformDataKeys.EDITOR) == null); + e.getPresentation().setEnabled(e.getData(CommonDataKeys.EDITOR) == null); } }; showHintAction.registerCustomShortcutSet( diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/FormEditingUtil.java b/plugins/ui-designer/src/com/intellij/uiDesigner/FormEditingUtil.java index faef895aa6d3..3d83737c2d75 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/FormEditingUtil.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/FormEditingUtil.java @@ -17,6 +17,7 @@ package com.intellij.uiDesigner; import com.intellij.lang.properties.PropertiesReferenceManager; import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.command.CommandProcessor; @@ -598,7 +599,7 @@ public final class FormEditingUtil { @Nullable public static GuiEditor getActiveEditor(final DataContext context) { - Project project = PlatformDataKeys.PROJECT.getData(context); + Project project = CommonDataKeys.PROJECT.getData(context); if (project == null) { return null; } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateListenerAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateListenerAction.java index 00393b85d225..20a3c3c85e00 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateListenerAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateListenerAction.java @@ -230,7 +230,7 @@ public class CreateListenerAction extends AbstractGuiEditorAction { IdeFocusManager.findInstance().doWhenFocusSettlesDown(new Runnable() { public void run() { final PsiClass newClass = (PsiClass)ptr.getElement(); - final Editor editor = PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext()); + final Editor editor = CommonDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext()); if (editor != null && newClass != null) { CommandProcessor.getInstance().executeCommand(myClass.getProject(), new Runnable() { public void run() { diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/GenerateMainAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/GenerateMainAction.java index 530ab8b7c1bd..d698a076b891 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/GenerateMainAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/GenerateMainAction.java @@ -20,6 +20,7 @@ import com.intellij.codeInsight.generation.GenerateMembersUtil; import com.intellij.codeInsight.generation.PsiGenerationInfo; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; @@ -53,9 +54,9 @@ public class GenerateMainAction extends AnAction { private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.actions.GenerateMainAction"); public void actionPerformed(AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); assert project != null; - final Editor editor = e.getData(PlatformDataKeys.EDITOR); + final Editor editor = e.getData(CommonDataKeys.EDITOR); assert editor != null; final int offset = editor.getCaretModel().getOffset(); final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); @@ -133,9 +134,9 @@ public class GenerateMainAction extends AnAction { } private static boolean isActionEnabled(final AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) return false; - Editor editor = e.getData(PlatformDataKeys.EDITOR); + Editor editor = e.getData(CommonDataKeys.EDITOR); if (editor == null) return false; int offset = editor.getCaretModel().getOffset(); PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/componentTree/ComponentTree.java b/plugins/ui-designer/src/com/intellij/uiDesigner/componentTree/ComponentTree.java index a2f50bb6b13c..48a4bd938aa8 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/componentTree/ComponentTree.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/componentTree/ComponentTree.java @@ -258,7 +258,7 @@ public final class ComponentTree extends Tree implements DataProvider { return myFormEditor; } - if (!PlatformDataKeys.NAVIGATABLE.is(dataId)) { + if (!CommonDataKeys.NAVIGATABLE.is(dataId)) { return null; } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GlassLayer.java b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GlassLayer.java index 281cefc2cb1a..015a9dc4653e 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GlassLayer.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GlassLayer.java @@ -135,7 +135,7 @@ public final class GlassLayer extends JComponent implements DataProvider, PopupO * binding of currently selected component (if any) */ public Object getData(final String dataId) { - if(PlatformDataKeys.NAVIGATABLE.is(dataId)) { + if(CommonDataKeys.NAVIGATABLE.is(dataId)) { final ComponentTree componentTree = UIDesignerToolWindowManager.getInstance(myEditor.getProject()).getComponentTree(); if (componentTree != null) { return componentTree.getData(dataId); diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/AddComponentAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/AddComponentAction.java index f34cb9743da5..44270fe9ade8 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/AddComponentAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/AddComponentAction.java @@ -18,6 +18,7 @@ package com.intellij.uiDesigner.palette; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.fileTypes.StdFileTypes; @@ -44,10 +45,10 @@ import java.util.HashMap; */ public class AddComponentAction extends AnAction { public void actionPerformed(AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) return; GroupItem groupItem = e.getData(GroupItem.DATA_KEY); - PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE); + PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE); PsiElement elementToAdd = (psiFile != null) ? findElementToAdd(psiFile) : null; String className = ""; if (elementToAdd instanceof PsiClass) { @@ -119,7 +120,7 @@ public class AddComponentAction extends AnAction { } @Override public void update(AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); if (e.getData(GroupItem.DATA_KEY) != null || e.getData(ComponentItem.DATA_KEY) != null) { e.getPresentation().setVisible(true); @@ -127,7 +128,7 @@ public class AddComponentAction extends AnAction { e.getPresentation().setEnabled(project != null && (groupItem == null || !groupItem.isReadOnly())); } else { - PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE); + PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE); e.getPresentation().setVisible(psiFile != null && findElementToAdd(psiFile) != null); } } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItem.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItem.java index e11ac2cacd72..3f27a0f8372a 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItem.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItem.java @@ -19,6 +19,7 @@ import com.intellij.ide.dnd.DnDDragStartBean; import com.intellij.ide.palette.PaletteItem; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.diagnostic.Logger; @@ -366,7 +367,7 @@ public final class ComponentItem implements Cloneable, PaletteItem { } @Nullable public Object getData(Project project, String dataId) { - if (LangDataKeys.PSI_ELEMENT.is(dataId)) { + if (CommonDataKeys.PSI_ELEMENT.is(dataId)) { return JavaPsiFacade.getInstance(project).findClass(myClassName, GlobalSearchScope.allScope(project)); } if (getClass().getName().equals(dataId)) { diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/DeleteComponentAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/DeleteComponentAction.java index 96c91b19cfeb..cd1fa5a435dc 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/DeleteComponentAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/DeleteComponentAction.java @@ -19,6 +19,7 @@ package com.intellij.uiDesigner.palette; import com.intellij.CommonBundle; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; @@ -29,7 +30,7 @@ import com.intellij.uiDesigner.UIDesignerBundle; */ public class DeleteComponentAction extends AnAction { public void actionPerformed(AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); ComponentItem selectedItem = e.getData(ComponentItem.DATA_KEY); GroupItem groupItem = e.getData(GroupItem.DATA_KEY); if (project == null || selectedItem == null || groupItem == null) return; @@ -53,7 +54,7 @@ public class DeleteComponentAction extends AnAction { } @Override public void update(AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); ComponentItem selectedItem = e.getData(ComponentItem.DATA_KEY); GroupItem groupItem = e.getData(GroupItem.DATA_KEY); e.getPresentation().setEnabled(project != null && selectedItem != null && groupItem != null && diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/DeleteGroupAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/DeleteGroupAction.java index fbed8fd5ba57..97805920c248 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/DeleteGroupAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/DeleteGroupAction.java @@ -19,6 +19,7 @@ package com.intellij.uiDesigner.palette; import com.intellij.CommonBundle; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; @@ -31,7 +32,7 @@ import java.util.ArrayList; */ public class DeleteGroupAction extends AnAction { public void actionPerformed(AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); GroupItem groupToBeRemoved = e.getData(GroupItem.DATA_KEY); if (groupToBeRemoved == null || project == null) return; @@ -51,7 +52,7 @@ public class DeleteGroupAction extends AnAction { } @Override public void update(AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); GroupItem groupItem = e.getData(GroupItem.DATA_KEY); ComponentItem selectedItem = e.getData(ComponentItem.DATA_KEY); e.getPresentation().setEnabled(project != null && groupItem != null && !groupItem.isReadOnly() && selectedItem == null); diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditComponentAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditComponentAction.java index 1c208d02babc..e3cacf56bd9d 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditComponentAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditComponentAction.java @@ -18,6 +18,7 @@ package com.intellij.uiDesigner.palette; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -33,7 +34,7 @@ public class EditComponentAction extends AnAction { private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.palette.EditComponentAction"); public void actionPerformed(AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); ComponentItem selectedItem = e.getData(ComponentItem.DATA_KEY); if (project == null || selectedItem == null || selectedItem.isAnyComponent() || selectedItem.isSpacer()) { return; @@ -66,7 +67,7 @@ public class EditComponentAction extends AnAction { } @Override public void update(AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); + Project project = e.getData(CommonDataKeys.PROJECT); ComponentItem selectedItem = e.getData(ComponentItem.DATA_KEY); GroupItem groupItem = e.getData(GroupItem.DATA_KEY); e.getPresentation().setEnabled(project != null && diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java index b882b9cfd2d3..3bedd33a745a 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java @@ -19,6 +19,7 @@ package com.intellij.uiDesigner.palette; import com.intellij.CommonBundle; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; @@ -31,7 +32,7 @@ import java.util.ArrayList; */ public class EditGroupAction extends AnAction { public void actionPerformed(AnActionEvent e) { - Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); GroupItem groupToBeEdited = GroupItem.DATA_KEY.getData(e.getDataContext()); if (groupToBeEdited == null || project == null) return; @@ -63,7 +64,7 @@ public class EditGroupAction extends AnAction { } @Override public void update(AnActionEvent e) { - Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); GroupItem groupItem = GroupItem.DATA_KEY.getData(e.getDataContext()); e.getPresentation().setEnabled(project != null && groupItem != null && !groupItem.isReadOnly()); } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/FormMergerTreeStructureProvider.java b/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/FormMergerTreeStructureProvider.java index b710a078cc59..5c6786eaaa76 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/FormMergerTreeStructureProvider.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/FormMergerTreeStructureProvider.java @@ -22,6 +22,7 @@ import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.projectView.impl.nodes.BasePsiNode; import com.intellij.ide.util.DeleteHandler; import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.fileTypes.StdFileTypes; @@ -152,7 +153,7 @@ public class FormMergerTreeStructureProvider implements TreeStructureProvider { } public void deleteElement(@NotNull DataContext dataContext) { - Project project = PlatformDataKeys.PROJECT.getData(dataContext); + Project project = CommonDataKeys.PROJECT.getData(dataContext); DeleteHandler.deletePsiElement(myElements, project); } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/UIDesignerFavoriteNodeProvider.java b/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/UIDesignerFavoriteNodeProvider.java index 287d305fe85a..f43c0cbc0984 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/UIDesignerFavoriteNodeProvider.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/UIDesignerFavoriteNodeProvider.java @@ -19,6 +19,7 @@ package com.intellij.uiDesigner.projectView; import com.intellij.ide.favoritesTreeView.FavoriteNodeProvider; import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.fileTypes.FileType; @@ -46,7 +47,7 @@ import java.util.*; public class UIDesignerFavoriteNodeProvider extends FavoriteNodeProvider { @Nullable public Collection<AbstractTreeNode> getFavoriteNodes(DataContext context, final ViewSettings viewSettings) { - Project project = PlatformDataKeys.PROJECT.getData(context); + Project project = CommonDataKeys.PROJECT.getData(context); if (project == null) return null; Form[] forms = Form.DATA_KEY.getData(context); if (forms != null) { @@ -65,7 +66,7 @@ public class UIDesignerFavoriteNodeProvider extends FavoriteNodeProvider { } } - VirtualFile vFile = PlatformDataKeys.VIRTUAL_FILE.getData(context); + VirtualFile vFile = CommonDataKeys.VIRTUAL_FILE.getData(context); if (vFile != null) { final FileType fileType = vFile.getFileType(); if (fileType.equals(StdFileTypes.GUI_DESIGNER_FORM)) { diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/PropertyInspectorTable.java b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/PropertyInspectorTable.java index a711578b3f28..059ba0407107 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/PropertyInspectorTable.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/PropertyInspectorTable.java @@ -257,7 +257,7 @@ public final class PropertyInspectorTable extends Table implements DataProvider{ if(getClass().getName().equals(dataId)){ return this; } - else if(LangDataKeys.PSI_ELEMENT.is(dataId)){ + else if(CommonDataKeys.PSI_ELEMENT.is(dataId)){ final IntrospectedProperty introspectedProperty = getSelectedIntrospectedProperty(); if(introspectedProperty == null){ return null; @@ -274,7 +274,7 @@ public final class PropertyInspectorTable extends Table implements DataProvider{ return PropertyUtil.findPropertySetter(aClass, introspectedProperty.getName(), false, true); } - else if (LangDataKeys.PSI_FILE.is(dataId) && myEditor != null) { + else if (CommonDataKeys.PSI_FILE.is(dataId) && myEditor != null) { return PsiManager.getInstance(myEditor.getProject()).findFile(myEditor.getFile()); } else if (GuiEditor.DATA_KEY.is(dataId)) { diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/editors/string/KeyChooserDialog.java b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/editors/string/KeyChooserDialog.java index 0d0900fb49b9..5e2abf8519e3 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/editors/string/KeyChooserDialog.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/editors/string/KeyChooserDialog.java @@ -18,6 +18,7 @@ package com.intellij.uiDesigner.propertyInspector.editors.string; import com.intellij.ide.DataManager; import com.intellij.lang.properties.IProperty; import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -110,7 +111,7 @@ public final class KeyChooserDialog extends DialogWrapper{ }); // Calculate width for "Key" columns - final Project projectGuess = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(parent)); + final Project projectGuess = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(parent)); final Dimension size = DimensionService.getInstance().getSize(getDimensionServiceKey(), projectGuess); final FontMetrics metrics = myTable.getFontMetrics(myTable.getFont()); int minWidth = 200; diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/quickFixes/ShowHintAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/quickFixes/ShowHintAction.java index f8db319cb65a..f08294c5cbff 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/quickFixes/ShowHintAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/quickFixes/ShowHintAction.java @@ -56,6 +56,6 @@ final class ShowHintAction extends AnAction { public void update(AnActionEvent e) { // Alt-Enter hotkey for editor takes precedence over this action - e.getPresentation().setEnabled(e.getData(PlatformDataKeys.EDITOR) == null); + e.getPresentation().setEnabled(e.getData(CommonDataKeys.EDITOR) == null); } } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/snapShooter/CreateSnapShotAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/snapShooter/CreateSnapShotAction.java index e498ca80211f..4400cd03b09c 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/snapShooter/CreateSnapShotAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/snapShooter/CreateSnapShotAction.java @@ -28,6 +28,7 @@ import com.intellij.ide.IdeView; import com.intellij.ide.highlighter.JavaHighlightingColors; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; @@ -83,7 +84,7 @@ public class CreateSnapShotAction extends AnAction { @Override public void update(AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); final IdeView view = e.getData(LangDataKeys.IDE_VIEW); e.getPresentation().setVisible(project != null && view != null && hasDirectoryInPackage(project, view)); } @@ -100,7 +101,7 @@ public class CreateSnapShotAction extends AnAction { } public void actionPerformed(AnActionEvent e) { - final Project project = e.getData(PlatformDataKeys.PROJECT); + final Project project = e.getData(CommonDataKeys.PROJECT); final IdeView view = e.getData(LangDataKeys.IDE_VIEW); if (project == null || view == null) { return; diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsGroup.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsGroup.java index 281d093bafed..42c0ff89e5f5 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsGroup.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsGroup.java @@ -81,6 +81,6 @@ public class AssociationsGroup extends ActionGroup { @Nullable static PsiFile getPsiFile(@Nullable AnActionEvent e) { - return e != null ? LangDataKeys.PSI_FILE.getData(e.getDataContext()) : null; + return e != null ? CommonDataKeys.PSI_FILE.getData(e.getDataContext()) : null; } } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/ConfigureAssociationsAction.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/ConfigureAssociationsAction.java index 9fa937262c7c..81df7a3c80d2 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/ConfigureAssociationsAction.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/ConfigureAssociationsAction.java @@ -17,6 +17,7 @@ package org.intellij.lang.xpath.xslt.associations.impl; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; @@ -28,10 +29,10 @@ class ConfigureAssociationsAction extends AnAction { } public void actionPerformed(final AnActionEvent e) { - final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); if (project == null) return; - final PsiFile file = LangDataKeys.PSI_FILE.getData(e.getDataContext()); + final PsiFile file = CommonDataKeys.PSI_FILE.getData(e.getDataContext()); FileAssociationsConfigurable.editAssociations(project, file); } } diff --git a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathAction.java b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathAction.java index df5cfa4b178a..20e3597c8f2f 100644 --- a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathAction.java +++ b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathAction.java @@ -58,13 +58,13 @@ public abstract class XPathAction extends AnAction { } protected boolean isEnabled(AnActionEvent event, boolean checkAvailable) { - final Project project = PlatformDataKeys.PROJECT.getData(event.getDataContext()); + final Project project = CommonDataKeys.PROJECT.getData(event.getDataContext()); if (project == null) { // no active project return false; } - Editor editor = PlatformDataKeys.EDITOR.getData(event.getDataContext()); + Editor editor = CommonDataKeys.EDITOR.getData(event.getDataContext()); if (editor == null) { FileEditorManager fem = FileEditorManager.getInstance(project); editor = fem.getSelectedTextEditor(); diff --git a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathEvalAction.java b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathEvalAction.java index 797000b81062..83a52404abea 100644 --- a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathEvalAction.java +++ b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathEvalAction.java @@ -20,6 +20,7 @@ import com.intellij.ide.projectView.PresentationData; import com.intellij.lang.Language; import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -135,14 +136,14 @@ public class XPathEvalAction extends XPathAction { @Override public void actionPerformed(AnActionEvent event) { - final Project project = PlatformDataKeys.PROJECT.getData(event.getDataContext()); + final Project project = CommonDataKeys.PROJECT.getData(event.getDataContext()); if (project == null) { // no active project LOG.debug("No project"); return; } - Editor editor = PlatformDataKeys.EDITOR.getData(event.getDataContext()); + Editor editor = CommonDataKeys.EDITOR.getData(event.getDataContext()); if (editor == null) { FileEditorManager fem = FileEditorManager.getInstance(project); editor = fem.getSelectedTextEditor(); diff --git a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/ui/EditContextDialog.java b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/ui/EditContextDialog.java index e2c0c59124c1..c488410b7083 100644 --- a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/ui/EditContextDialog.java +++ b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/ui/EditContextDialog.java @@ -18,6 +18,7 @@ package org.intellij.plugins.xpathView.ui; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.ide.DataManager; import com.intellij.javaee.ExternalResourceManager; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.fileTypes.LanguageFileType; @@ -139,7 +140,7 @@ public class EditContextDialog extends DialogWrapper { Collections.sort(allURIs); final DataContext dataContext = DataManager.getInstance().getDataContext(myNamespaceTable); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); final AddNamespaceDialog dlg = new AddNamespaceDialog(project, myUnresolvedPrefixes, allURIs, AddNamespaceDialog.Mode.EDITABLE); dlg.show(); if (dlg.isOK()) { diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/ui/StructureTree.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/ui/StructureTree.java index 79773bfaccb4..a464af9d7bb7 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/ui/StructureTree.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/ui/StructureTree.java @@ -46,12 +46,12 @@ public class StructureTree extends Tree implements TypeSafeDataProvider { } public void calcData(DataKey key, DataSink sink) { - if (key.equals(PlatformDataKeys.NAVIGATABLE)) { + if (key.equals(CommonDataKeys.NAVIGATABLE)) { final TreePath selection = getSelectionPath(); if (selection != null) { final Object o = selection.getLastPathComponent(); if (o instanceof Navigatable) { - sink.put(PlatformDataKeys.NAVIGATABLE, (Navigatable)o); + sink.put(CommonDataKeys.NAVIGATABLE, (Navigatable)o); } } } else if (key.equals(CopyValueAction.SELECTED_NODE)) { diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/ui/actions/OpenOutputAction.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/ui/actions/OpenOutputAction.java index bae589cc01d0..aa6edcd65c91 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/ui/actions/OpenOutputAction.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/ui/actions/OpenOutputAction.java @@ -20,6 +20,7 @@ import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditorManager; @@ -40,7 +41,7 @@ public class OpenOutputAction extends AnAction { } public void actionPerformed(AnActionEvent e) { - final Editor editor = PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext(myConsole.getComponent())); + final Editor editor = CommonDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext(myConsole.getComponent())); if (editor != null) { try { final byte[] content = editor.getDocument().getText().getBytes("UTF-8"); @@ -51,7 +52,7 @@ public class OpenOutputAction extends AnAction { return Charset.forName("UTF-8"); } }; - FileEditorManager.getInstance(PlatformDataKeys.PROJECT.getData(e.getDataContext())).openFile(file, true); + FileEditorManager.getInstance(CommonDataKeys.PROJECT.getData(e.getDataContext())).openFile(file, true); } catch (UnsupportedEncodingException e1) { throw new AssertionError(e); } @@ -59,7 +60,7 @@ public class OpenOutputAction extends AnAction { } public void update(AnActionEvent e) { - final Editor editor = PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext(myConsole.getComponent())); + final Editor editor = CommonDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext(myConsole.getComponent())); e.getPresentation().setEnabled(editor != null && editor.getDocument().getTextLength() > 0); } } |