diff --git a/bin/linux/libbreakgen64.so b/bin/linux/libbreakgen64.so new file mode 100644 index 000000000000..ba9c5900404e Binary files /dev/null and b/bin/linux/libbreakgen64.so differ diff --git a/bin/win/breakgen64.dll b/bin/win/breakgen64.dll new file mode 100644 index 000000000000..5b92f6df5fa8 Binary files /dev/null and b/bin/win/breakgen64.dll differ diff --git a/java/java-impl/java-impl.iml b/java/java-impl/java-impl.iml index 90be2386c2c3..c41067e99861 100644 --- a/java/java-impl/java-impl.iml +++ b/java/java-impl/java-impl.iml @@ -13,7 +13,6 @@ - diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/CopyPasteReferenceProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/CopyPasteReferenceProcessor.java index 30c4ebcc7c31..dabe31bccb74 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/CopyPasteReferenceProcessor.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/CopyPasteReferenceProcessor.java @@ -44,6 +44,9 @@ public class CopyPasteReferenceProcessor implements CopyPastePostProcessor { if (file instanceof PsiCompiledElement) { file = (PsiFile) ((PsiCompiledElement) file).getMirror(); } + if (!(file instanceof PsiClassOwner)) { + return new ReferenceTransferableData(new ReferenceTransferableData.ReferenceData[0]); + } final ArrayList array = new ArrayList(); for (int j = 0; j < startOffsets.length; j++) { @@ -104,10 +107,13 @@ public class CopyPasteReferenceProcessor implements CopyPastePostProcessor { if (DumbService.getInstance(project).isDumb()) { return; } - final Document document = editor.getDocument(); final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); + if (!(file instanceof PsiClassOwner)) { + return; + } + PsiDocumentManager.getInstance(project).commitAllDocuments(); final ReferenceTransferableData.ReferenceData[] referenceData = ((ReferenceTransferableData)value).getData(); final PsiJavaCodeReferenceElement[] refs = findReferencesToRestore(file, bounds, referenceData); diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageViewModuleNode.java b/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageViewModuleNode.java index 112af5accbbf..d2430b7a4e11 100644 --- a/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageViewModuleNode.java +++ b/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageViewModuleNode.java @@ -18,14 +18,15 @@ package com.intellij.ide.projectView.impl.nodes; import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; import java.util.Arrays; import java.util.Collection; -import org.jetbrains.annotations.NotNull; - public class PackageViewModuleNode extends AbstractModuleNode{ public PackageViewModuleNode(Project project, Module value, ViewSettings viewSettings) { super(project, value, viewSettings); @@ -45,4 +46,9 @@ public class PackageViewModuleNode extends AbstractModuleNode{ } + public boolean contains(@NotNull VirtualFile file) { + Module module = getValue(); + return module != null && !module.isDisposed() && + (ModuleUtil.moduleContainsFile(module, file, false) || ModuleUtil.moduleContainsFile(module, file, true)); + } } diff --git a/java/java-impl/src/com/intellij/refactoring/actions/ChangeSignatureAction.java b/java/java-impl/src/com/intellij/refactoring/actions/ChangeSignatureAction.java index 8f850bc263e8..1da3be897e59 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/ChangeSignatureAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/ChangeSignatureAction.java @@ -1,28 +1,27 @@ - /* - * Copyright 2000-2009 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. - */ +* Copyright 2000-2009 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.refactoring.actions; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiMethod; +import com.intellij.psi.*; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.changeSignature.ChangeSignatureHandler; +import com.intellij.refactoring.changeSignature.ChangeSignatureTargetUtil; public class ChangeSignatureAction extends BaseRefactoringAction { public boolean isAvailableInEditorOnly() { @@ -34,10 +33,15 @@ public class ChangeSignatureAction extends BaseRefactoringAction { } protected boolean isAvailableOnElementInEditor(final PsiElement element, final Editor editor) { + final Document document = editor.getDocument(); + final PsiFile file = PsiDocumentManager.getInstance(element.getProject()).getPsiFile(document); + if (file != null && ChangeSignatureTargetUtil.findTargetMember(file, editor) != null) { + return true; + } return element instanceof PsiMethod || element instanceof PsiClass; } public RefactoringActionHandler getHandler(DataContext dataContext) { return new ChangeSignatureHandler(); } -} \ No newline at end of file +} diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java index ad997fca7ce4..5c099c16bb49 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java @@ -37,7 +37,10 @@ public class ChangeSignatureHandler implements RefactoringActionHandler { public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) { editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); - PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext); + PsiElement element = ChangeSignatureTargetUtil.findTargetMember(file, editor); + if (element == null) { + element = LangDataKeys.PSI_ELEMENT.getData(dataContext); + } invokeOnElement(project, editor, element); } @@ -93,4 +96,4 @@ public class ChangeSignatureHandler implements RefactoringActionHandler { ChangeClassSignatureDialog dialog = new ChangeClassSignatureDialog(aClass); dialog.show(); } -} \ No newline at end of file +} diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureTargetUtil.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureTargetUtil.java new file mode 100644 index 000000000000..5c947f4c48bb --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureTargetUtil.java @@ -0,0 +1,77 @@ +/* + * Copyright 2000-2009 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. + */ + +/* + * User: anna + * Date: 24-Nov-2009 + */ +package com.intellij.refactoring.changeSignature; + +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.Nullable; + +public class ChangeSignatureTargetUtil { + private ChangeSignatureTargetUtil() {} + + @Nullable + public static PsiMember findTargetMember(PsiFile file, Editor editor) { + PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); + if (PsiTreeUtil.getParentOfType(element, PsiParameterList.class) != null) { + return PsiTreeUtil.getParentOfType(element, PsiMethod.class); + } + + final PsiMethodCallExpression expression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class); + if (expression != null) { + assert element != null; + final PsiExpression qualifierExpression = expression.getMethodExpression().getQualifierExpression(); + if (PsiTreeUtil.isAncestor(qualifierExpression, element, false)) { + final PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(qualifierExpression, PsiExpressionList.class); + if (expressionList != null) { + final PsiElement parent = expressionList.getParent(); + if (parent instanceof PsiMethodCallExpression) { + return ((PsiMethodCallExpression)parent).resolveMethod(); + } + } + } else { + return expression.resolveMethod(); + } + } + + final PsiTypeParameterList typeParameterList = PsiTreeUtil.getParentOfType(element, PsiTypeParameterList.class); + if (typeParameterList != null) { + return PsiTreeUtil.getParentOfType(typeParameterList, PsiMember.class); + } + + final PsiReferenceParameterList referenceParameterList = PsiTreeUtil.getParentOfType(element, PsiReferenceParameterList.class); + if (referenceParameterList != null) { + final PsiJavaCodeReferenceElement referenceElement = + PsiTreeUtil.getParentOfType(referenceParameterList, PsiJavaCodeReferenceElement.class); + if (referenceElement != null) { + final PsiElement resolved = referenceElement.resolve(); + if (resolved instanceof PsiClass) { + return (PsiMember)resolved; + } + else if (resolved instanceof PsiMethod) { + return (PsiMember)resolved; + } + } + } + return null; + } + +} diff --git a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassDialog.java b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassDialog.java index 8dc6143f71c4..656f4ac7e5a8 100644 --- a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassDialog.java @@ -53,6 +53,7 @@ class CopyClassDialog extends DialogWrapper{ public CopyClassDialog(PsiClass aClass, PsiDirectory defaultTargetDirectory, Project project, boolean doClone) { super(project, true); myProject = project; + myDefaultTargetDirectory = defaultTargetDirectory; init(); myDoClone = doClone; String text = myDoClone ? RefactoringBundle.message("copy.class.clone.0.1", UsageViewUtil.getType(aClass), UsageViewUtil.getLongName(aClass)) : @@ -60,13 +61,6 @@ class CopyClassDialog extends DialogWrapper{ myInformationLabel.setText(text); myNameField.setText(UsageViewUtil.getShortName(aClass)); myNameLabel.setText(RefactoringBundle.message("name.prompt")); - myDefaultTargetDirectory = defaultTargetDirectory; - if (myDefaultTargetDirectory != null) { - PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(myDefaultTargetDirectory); - if (aPackage != null) { - myTfPackage.prependItem(aPackage.getQualifiedName()); - } - } if (myDoClone) { myTfPackage.setVisible(false); myPackageLabel.setVisible(false); @@ -116,7 +110,18 @@ class CopyClassDialog extends DialogWrapper{ gbConstraints.gridx = 1; gbConstraints.weightx = 1; - myTfPackage = new PackageNameReferenceEditorCombo("", myProject, RECENTS_KEY, RefactoringBundle.message("choose.destination.package")); + String qualifiedName = ""; + if (myDefaultTargetDirectory != null) { + final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(myDefaultTargetDirectory); + if (aPackage != null) { + qualifiedName = aPackage.getQualifiedName(); + } + } + + myTfPackage = new PackageNameReferenceEditorCombo(qualifiedName, myProject, RECENTS_KEY, RefactoringBundle.message("choose.destination.package")); + if (qualifiedName.length() > 0) { + myTfPackage.setTextFieldPreferredWidth(qualifiedName.length() + 5); + } myPackageLabel.setText(RefactoringBundle.message("destination.package")); diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java index 843f19c36e48..35dfa38e291d 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java @@ -89,19 +89,9 @@ public class ExtractMethodDialog extends AbstractExtractDialog { myStaticFlag = isStatic; myCanBeStatic = canBeStatic; myElementsToExtract = elementsToExtract; - - boolean canBeVarargs = false; - for (ParameterTablePanel.VariableData data : inputVariables.getInputVariables()) { - canBeVarargs |= data.type instanceof PsiArrayType; - } myVariableData = inputVariables; - - if (inputVariables.isFoldable()) { - canBeVarargs |= inputVariables.isFoldingSelectedByDefault(); - } - - setTitle(title); myHelpId = helpId; + setTitle(title); // Create UI components @@ -118,9 +108,6 @@ public class ExtractMethodDialog extends AbstractExtractDialog { if (canBeChainedConstructor) { myCbChainedConstructor = new NonFocusableCheckBox(RefactoringBundle.message("extract.chained.constructor.checkbox")); } - if (canBeVarargs) { - myCbMakeVarargs = new NonFocusableCheckBox(RefactoringBundle.message("declare.varargs.checkbox")); - } // Initialize UI @@ -232,7 +219,15 @@ public class ExtractMethodDialog extends AbstractExtractDialog { }); panel.add(myFoldCb); - if (myCbMakeVarargs != null) { + boolean canBeVarargs = false; + for (ParameterTablePanel.VariableData data : myInputVariables) { + canBeVarargs |= data.type instanceof PsiArrayType; + } + if (myVariableData.isFoldable()) { + canBeVarargs |= myVariableData.isFoldingSelectedByDefault(); + } + if (canBeVarargs) { + myCbMakeVarargs = new NonFocusableCheckBox(RefactoringBundle.message("declare.varargs.checkbox")); updateVarargsEnabled(); myCbMakeVarargs.setSelected(false); panel.add(myCbMakeVarargs); diff --git a/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java b/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java index 912afc938181..9e306a10e0ab 100644 --- a/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java +++ b/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java @@ -39,9 +39,14 @@ public class AppMain { final String osName = System.getProperty("os.name").toLowerCase(); String libPath = null; if (osName.startsWith("windows")) { - libPath = binPath + "breakgen.dll"; + if (System.getProperty("os.arch").equals("amd64")) { + libPath = binPath + "breakgen64.dll"; + } + else { + libPath = binPath + "breakgen.dll"; + } } else if (osName.startsWith("linux")) { - if (System.getProperty("os.name").toLowerCase().equals("amd64")) { + if (System.getProperty("os.arch").toLowerCase().equals("amd64")) { libPath = binPath + "libbreakgen64.so"; } else { libPath = binPath + "libbreakgen.so"; diff --git a/java/java-tests/testData/refactoring/changeSignatureTarget/inClassTypeParameters.java b/java/java-tests/testData/refactoring/changeSignatureTarget/inClassTypeParameters.java new file mode 100644 index 000000000000..cd816bf9da2a --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignatureTarget/inClassTypeParameters.java @@ -0,0 +1,3 @@ +import java.util.*; +class A1<T> { +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/changeSignatureTarget/inMethodArguments.java b/java/java-tests/testData/refactoring/changeSignatureTarget/inMethodArguments.java new file mode 100644 index 000000000000..7b56e5dbd51e --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignatureTarget/inMethodArguments.java @@ -0,0 +1,12 @@ +import java.util.*; +class B{ + + public static void main(String[] args) { + B b = null; + b.bar(b.ing>foo("", "")); + } + + String foo(T t, String s){return null;} + String bar(String s) {return null;} + +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/changeSignatureTarget/inMethodParameters.java b/java/java-tests/testData/refactoring/changeSignatureTarget/inMethodParameters.java new file mode 100644 index 000000000000..a66333b6f871 --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignatureTarget/inMethodParameters.java @@ -0,0 +1,4 @@ +import java.util.*; +class B { + String foo(T t, String s){return null;} +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/changeSignatureTarget/inTypeArguments.java b/java/java-tests/testData/refactoring/changeSignatureTarget/inTypeArguments.java new file mode 100644 index 000000000000..d0fb0a13392e --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignatureTarget/inTypeArguments.java @@ -0,0 +1,23 @@ +import java.util.*; +class A1 { + public static void main(String[] args) { + + Callable callable = new Callable() { + public Object call() throws Exception { + return new A1ing>().toString(); + + } + }; + B b = null; + b.bar(b.foo("", "")); + } + + + String foo(T t, String s) { + return null; + } + + String bar(String s) { + return null; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTargetTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTargetTest.java new file mode 100644 index 000000000000..175bed687acf --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTargetTest.java @@ -0,0 +1,50 @@ +/* + * User: anna + * Date: 25-Nov-2009 + */ +package com.intellij.refactoring; + +import com.intellij.JavaTestUtil; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; +import com.intellij.psi.PsiMember; +import com.intellij.refactoring.changeSignature.ChangeSignatureTargetUtil; +import com.intellij.testFramework.LightCodeInsightTestCase; +import org.jetbrains.annotations.NonNls; + +public class ChangeSignatureTargetTest extends LightCodeInsightTestCase { + @Override + protected String getTestDataPath() { + return JavaTestUtil.getJavaTestDataPath(); + } + + public void testInMethodParameters() throws Exception { + doTest("foo"); + } + + public void testInMethodArguments() throws Exception { + doTest("foo"); + } + + public void testInClassTypeParameters() throws Exception { + doTest("A1"); + } + + public void testInTypeArguments() throws Exception { + doTest("A1"); + } + + @Override + protected Sdk getProjectJDK() { + return JavaSdkImpl.getMockJdk15("java 1.5"); + } + + private void doTest(String expectedMemberName) throws Exception { + String basePath = "/refactoring/changeSignatureTarget/" + getTestName(false); + @NonNls final String filePath = basePath + ".java"; + configureByFile(filePath); + final PsiMember member = ChangeSignatureTargetUtil.findTargetMember(getFile(), getEditor()); + assertNotNull(member); + assertEquals(expectedMemberName, member.getName()); + } +} \ No newline at end of file diff --git a/native/breakgen/AppMain.c b/native/breakgen/AppMain.c index 4b33f16fa89c..15b2831ab366 100644 --- a/native/breakgen/AppMain.c +++ b/native/breakgen/AppMain.c @@ -14,10 +14,10 @@ * limitations under the License. */ +#include #if defined(WIN32) #include #else -#include #include #include #include diff --git a/native/breakgen/make.sh b/native/breakgen/make.sh new file mode 100644 index 000000000000..5ef8c5b7cd56 --- /dev/null +++ b/native/breakgen/make.sh @@ -0,0 +1 @@ +gcc -I/opt/jdk1.6.0_16_x64/include/ -I/opt/jdk1.6.0_16_x64/include/linux/ AppMain.c -shared -fPIC -o libbreakgen64.so diff --git a/platform/lang-api/src/com/intellij/profile/DefaultProjectProfileManager.java b/platform/lang-api/src/com/intellij/profile/DefaultProjectProfileManager.java index c0a3256a9d45..736792bb6d0a 100644 --- a/platform/lang-api/src/com/intellij/profile/DefaultProjectProfileManager.java +++ b/platform/lang-api/src/com/intellij/profile/DefaultProjectProfileManager.java @@ -125,11 +125,13 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager if (projectProfile != null) { final Element profileElement = new Element(PROFILE); projectProfile.writeExternal(profileElement); - boolean hasSmthToSave = sortedProfiles.size() > 1; - for (Object child : profileElement.getChildren()) { - if (!((Element)child).getName().equals("option")) { - hasSmthToSave = true; - break; + boolean hasSmthToSave = sortedProfiles.size() > 1 || !Comparing.strEqual(PROJECT_PROFILE, PROJECT_DEFAULT_PROFILE_NAME); + if (!hasSmthToSave) { + for (Object child : profileElement.getChildren()) { + if (!((Element)child).getName().equals("option")) { + hasSmthToSave = true; + break; + } } } if (!hasSmthToSave) continue; @@ -143,7 +145,7 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager } } - if (profiles != null || !Comparing.strEqual(PROJECT_PROFILE, PROJECT_DEFAULT_PROFILE_NAME)) { + if (profiles != null) { DefaultJDOMExternalizer.writeExternal(this, element); final Element version = new Element("version"); version.setAttribute("value", VERSION); diff --git a/platform/lang-impl/lang-impl.iml b/platform/lang-impl/lang-impl.iml index 05045cad5f6e..c1022af449fb 100644 --- a/platform/lang-impl/lang-impl.iml +++ b/platform/lang-impl/lang-impl.iml @@ -19,6 +19,7 @@ + diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java b/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java index ed4d563790f9..ef82cdb1de28 100644 --- a/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java +++ b/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java @@ -1077,6 +1077,7 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract public void disposeUIResources() { if (mySubPanel != null) { mySubPanel.disposeUIResources(); + mySubPanel = null; } } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/macro/GroovyScriptMacro.java b/platform/lang-impl/src/com/intellij/codeInsight/template/macro/GroovyScriptMacro.java similarity index 100% rename from java/java-impl/src/com/intellij/codeInsight/template/macro/GroovyScriptMacro.java rename to platform/lang-impl/src/com/intellij/codeInsight/template/macro/GroovyScriptMacro.java diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java index 8c01d33801ea..ef4b3fc1a99e 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java @@ -23,6 +23,7 @@ import com.intellij.codeInspection.InspectionProfile; import com.intellij.codeInspection.InspectionProfileEntry; import com.intellij.codeInspection.InspectionsBundle; import com.intellij.codeInspection.ModifiableModel; +import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; @@ -249,6 +250,17 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel, } } + public Set getUsedSeverities() { + LOG.assertTrue(myInitialized.get()); + final Set result = new HashSet(); + for (ToolsImpl tools : myTools.values()) { + for (ScopeToolState state : tools.getTools()) { + result.add(state.getLevel().getSeverity()); + } + } + return result; + } + public void writeExternal(Element element) throws WriteExternalException { super.writeExternal(element); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java index f0eeebca8049..2c8f98c85e77 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java @@ -168,8 +168,10 @@ public class ToolsImpl implements Tools { final InspectionProfileEntry copyTool = ((InspectionProfileImpl)profile).myRegistrar.createInspectionTool(myShortName, tool); copyTool.readSettings(scopeElement); - final HighlightDisplayLevel scopeLevel = errorLevel != null ? HighlightDisplayLevel - .find(((SeverityProvider)profileManager).getOwnSeverityRegistrar().getSeverity(errorLevel)) : level; + HighlightDisplayLevel scopeLevel = level; + if (errorLevel != null){ + scopeLevel = HighlightDisplayLevel.find(((SeverityProvider)profileManager).getOwnSeverityRegistrar().getSeverity(errorLevel)); + } if (namedScope != null) { addTool(namedScope, copyTool, enabledInScope != null && Boolean.parseBoolean(enabledInScope), scopeLevel); } else { diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java index 2e07f4d5290e..941c89108a1e 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java @@ -303,7 +303,7 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo List existingTemplates = new ArrayList(); // Read user-defined templates for (File file : files) { - if (file.isDirectory()) { + if (file.isDirectory() || FileTypeManagerEx.getInstance().isFileIgnored(file.getName())) { continue; } String name = file.getName(); @@ -332,6 +332,7 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo LOG.debug("FileTemplateManagerImpl.loadTemplates() reading default templates..."); // Read default templates for (VirtualFile file : defaultTemplates) { + if(FileTypeManagerEx.getInstance().isFileIgnored(file.getName())) continue; String name = file.getName(); //name.extension.ft , e.g. "NewClass.java.ft" @NonNls String extension = myTypeManager.getExtension(name); name = name.substring(0, name.length() - extension.length() - 1); //name="NewClass.java" extension="ft" diff --git a/platform/lang-impl/src/com/intellij/ide/impl/ModuleStructureComponent.java b/platform/lang-impl/src/com/intellij/ide/impl/ModuleStructureComponent.java index 575e39e8e5ae..8a346bfa23b8 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/ModuleStructureComponent.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/ModuleStructureComponent.java @@ -20,20 +20,27 @@ package com.intellij.ide.impl; import com.intellij.openapi.Disposable; +import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.module.Module; import com.intellij.openapi.ui.SimpleToolWindowPanel; import com.intellij.openapi.util.Disposer; +import org.jetbrains.annotations.NonNls; + +public class ModuleStructureComponent extends SimpleToolWindowPanel implements Disposable, DataProvider { + private final ModuleStructurePane myStructurePane; -public class ModuleStructureComponent extends SimpleToolWindowPanel implements Disposable { public ModuleStructureComponent(Module module) { super(true, true); - final ModuleStructurePane structurePane = new ModuleStructurePane(module); - Disposer.register(this, structurePane); + myStructurePane = new ModuleStructurePane(module); + Disposer.register(this, myStructurePane); - setContent(structurePane.createComponent()); + setContent(myStructurePane.createComponent()); } + public Object getData(@NonNls String dataId) { + return myStructurePane.getData(dataId); + } public void dispose() { diff --git a/platform/lang-impl/src/com/intellij/ide/impl/StructureViewSelectInTarget.java b/platform/lang-impl/src/com/intellij/ide/impl/StructureViewSelectInTarget.java index f7c6cdf9b3ae..522df36065f1 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/StructureViewSelectInTarget.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/StructureViewSelectInTarget.java @@ -52,7 +52,7 @@ public class StructureViewSelectInTarget implements SelectInTarget { StructureViewFactoryEx.getInstanceEx(myProject).runWhenInitialized(new Runnable() { public void run() { final StructureViewWrapper structureView = getStructureViewWrapper(); - structureView.selectCurrentElement(fileEditor,requestFocus); + structureView.selectCurrentElement(fileEditor, context.getVirtualFile(), requestFocus); } }); } diff --git a/platform/lang-impl/src/com/intellij/ide/impl/StructureViewWrapperImpl.java b/platform/lang-impl/src/com/intellij/ide/impl/StructureViewWrapperImpl.java index 85c681072efe..e672c21aafdf 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/StructureViewWrapperImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/StructureViewWrapperImpl.java @@ -18,31 +18,40 @@ package com.intellij.ide.impl; import com.intellij.ide.DataManager; import com.intellij.ide.IdeBundle; +import com.intellij.ide.projectView.impl.ProjectRootsUtil; import com.intellij.ide.structureView.StructureView; import com.intellij.ide.structureView.StructureViewBuilder; import com.intellij.ide.structureView.StructureViewWrapper; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.actionSystem.TimerListener; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileEditorProvider; +import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; import com.intellij.psi.PsiDocumentManager; +import com.intellij.util.Alarm; import com.intellij.util.IJSwingUtilities; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; -import java.util.Arrays; /** * @author Eugene Belyaev @@ -50,13 +59,13 @@ import java.util.Arrays; public class StructureViewWrapperImpl implements StructureViewWrapper, Disposable { private final Project myProject; - private FileEditor myFileEditor; - private Module myModule; + private VirtualFile myFile; private StructureView myStructureView; private ModuleStructureComponent myModuleStructureComponent; private final JPanel myPanel; + private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); // ------------------------------------------------------------------------- // Constructor @@ -69,7 +78,7 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl ActionManager.getInstance().addTimerListener(500, new TimerListener() { public ModalityState getModalityState() { - return ModalityState.NON_MODAL; + return ModalityState.stateForComponent(myPanel); } public void run() { @@ -80,7 +89,7 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl getComponent().addHierarchyListener(new HierarchyListener() { public void hierarchyChanged(HierarchyEvent e) { if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) { - rebuild(); + scheduleRebuild(); } } }); @@ -100,18 +109,23 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl if (owner == null || SwingUtilities.isDescendingFrom(owner, myPanel)) return; final DataContext dataContext = DataManager.getInstance().getDataContext(owner); - final FileEditor fileEditor = PlatformDataKeys.FILE_EDITOR.getData(dataContext); - if (fileEditor != null) { - if (Arrays.asList(FileEditorManager.getInstance(myProject).getSelectedEditors()).contains(fileEditor)) { - setFileEditor(fileEditor); - } + final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); + if (files != null && files.length == 1) { + setFile(files[0]); } else { - setModule(LangDataKeys.MODULE_CONTEXT.getData(dataContext)); + setFile(null); } } } + private void setFile(VirtualFile file) { + if (!Comparing.equal(file, myFile)) { + myFile = file; + scheduleRebuild(); + } + } + // ------------------------------------------------------------------------- // StructureView interface implementation @@ -122,14 +136,13 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl } public void dispose() { - myFileEditor = null; rebuild(); } - public boolean selectCurrentElement(FileEditor fileEditor, boolean requestFocus) { + public boolean selectCurrentElement(FileEditor fileEditor, VirtualFile file, boolean requestFocus) { if (myStructureView != null) { if (!Comparing.equal(myStructureView.getFileEditor(), fileEditor)) { - setFileEditor(fileEditor); + myFile = file; rebuild(); } return myStructureView.navigateToSelectedElement(requestFocus); @@ -139,30 +152,13 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl } } - private void setModule(Module module) { - if (module != myModule) { - myModule = module; - rebuild(); - } - } - - public void setFileEditor(FileEditor fileEditor) { - if (myModule != null) { - myModule = null; - rebuild(); - } - else { - if (!Comparing.equal(myFileEditor, fileEditor)) { - myFileEditor = fileEditor; - rebuild(); - return; - } - - if (isStructureViewShowing() && myPanel.getComponentCount() == 0 && myFileEditor != null) { + private void scheduleRebuild() { + myUpdateAlarm.cancelAllRequests(); + myUpdateAlarm.addRequest(new Runnable() { + public void run() { rebuild(); } - } - + }, 300, ModalityState.stateForComponent(myPanel)); } public void rebuild() { @@ -188,29 +184,48 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl return; } - if (myModule != null) { - myModuleStructureComponent = new ModuleStructureComponent(myModule); - myPanel.add(myModuleStructureComponent, BorderLayout.CENTER); - if (hadFocus) { - JComponent focusedComponent = IdeFocusTraversalPolicy.getPreferredFocusedComponent(myModuleStructureComponent); - if (focusedComponent != null) { - focusedComponent.requestFocus(); - } + VirtualFile file = myFile; + if (file == null) { + final VirtualFile[] selectedFiles = FileEditorManager.getInstance(myProject).getSelectedFiles(); + if (selectedFiles.length > 0) { + file = selectedFiles[0]; } } - else if (myFileEditor != null && myFileEditor.isValid()) { - final StructureViewBuilder structureViewBuilder = myFileEditor.getStructureViewBuilder(); - if (structureViewBuilder != null) { - myStructureView = structureViewBuilder.createStructureView(myFileEditor, myProject); - myPanel.add(myStructureView.getComponent(), BorderLayout.CENTER); - if (hadFocus) { - JComponent focusedComponent = IdeFocusTraversalPolicy.getPreferredFocusedComponent(myStructureView.getComponent()); - if (focusedComponent != null) { - focusedComponent.requestFocus(); + + if (file != null) { + if (file.isDirectory()) { + if (ProjectRootsUtil.isModuleContentRoot(file, myProject)) { + Module module = ModuleUtil.findModuleForFile(file, myProject); + if (module != null) { + myModuleStructureComponent = new ModuleStructureComponent(module); + myPanel.add(myModuleStructureComponent, BorderLayout.CENTER); + if (hadFocus) { + JComponent focusedComponent = IdeFocusTraversalPolicy.getPreferredFocusedComponent(myModuleStructureComponent); + if (focusedComponent != null) { + focusedComponent.requestFocus(); + } + } + } + } + } + else { + FileEditor editor = FileEditorManager.getInstance(myProject).getSelectedEditor(file); + if (editor == null) editor = crteateTempFileEditor(file); + if (editor != null && editor.isValid()) { + final StructureViewBuilder structureViewBuilder = editor.getStructureViewBuilder(); + if (structureViewBuilder != null) { + myStructureView = structureViewBuilder.createStructureView(editor, myProject); + myPanel.add(myStructureView.getComponent(), BorderLayout.CENTER); + if (hadFocus) { + JComponent focusedComponent = IdeFocusTraversalPolicy.getPreferredFocusedComponent(myStructureView.getComponent()); + if (focusedComponent != null) { + focusedComponent.requestFocus(); + } + } + myStructureView.restoreState(); + myStructureView.centerSelectedRow(); } } - myStructureView.restoreState(); - myStructureView.centerSelectedRow(); } } @@ -222,6 +237,16 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl myPanel.repaint(); } + @Nullable + private FileEditor crteateTempFileEditor(VirtualFile file) { + FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance(); + final FileEditorProvider[] providers = editorProviderManager.getProviders(myProject, file); + for (FileEditorProvider provider : providers) { + return provider.createEditor(myProject, file); + } + return null; + } + protected boolean isStructureViewShowing() { ToolWindowManager windowManager = ToolWindowManager.getInstance(myProject); diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractModuleNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractModuleNode.java index b827926bd315..a1e5831efbc6 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractModuleNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractModuleNode.java @@ -19,10 +19,12 @@ import com.intellij.ide.projectView.PresentationData; import com.intellij.ide.projectView.ProjectViewNode; import com.intellij.ide.projectView.ViewSettings; import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService; +import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.SimpleTextAttributes; import org.jetbrains.annotations.NotNull; public abstract class AbstractModuleNode extends ProjectViewNode { @@ -36,6 +38,8 @@ public abstract class AbstractModuleNode extends ProjectViewNode { return; } presentation.setPresentableText(getValue().getName()); + presentation.addText(getValue().getName(), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); + presentation.setOpenIcon(getValue().getModuleType().getNodeIcon(true)); presentation.setClosedIcon(getValue().getModuleType().getNodeIcon(false)); } @@ -45,10 +49,12 @@ public abstract class AbstractModuleNode extends ProjectViewNode { return "Module"; } + @Override public boolean contains(@NotNull VirtualFile file) { - Module module = getValue(); - return module != null && !module.isDisposed() && - (ModuleUtil.moduleContainsFile(module, file, false) || ModuleUtil.moduleContainsFile(module, file, true)); + for (VirtualFile root : ModuleRootManager.getInstance(getValue()).getContentRoots()) { + if (VfsUtil.isAncestor(root, file, false)) return true; + } + return false; } public String getToolTip() { diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java index a38440091491..2f27d6f1e799 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java @@ -62,9 +62,12 @@ public class ProjectViewModuleNode extends AbstractModuleNode { PsiDirectoryNode directoryNode = new PsiDirectoryNode(getProject(), psiDirectory, getSettings()); children.add(directoryNode); } + + /* if (getSettings().isShowLibraryContents()) { children.add(new LibraryGroupNode(getProject(), new LibraryGroupElement(getValue()), getSettings())); } + */ return children; } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java index de8955f25638..725d33dbff81 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java @@ -45,11 +45,22 @@ public class ProjectViewProjectNode extends AbstractProjectNode { public Collection getChildren() { List topLevelContentRoots = ProjectViewDirectoryHelper.getInstance(myProject).getTopLevelRoots(); + Set modules = new LinkedHashSet(topLevelContentRoots.size()); + + for (VirtualFile root : topLevelContentRoots) { + modules.add(ModuleUtil.findModuleForFile(root, myProject)); + } + ArrayList nodes = new ArrayList(); final PsiManager psiManager = PsiManager.getInstance(getProject()); + + /* for (VirtualFile root : reduceRoots(topLevelContentRoots)) { nodes.add(new PsiDirectoryNode(getProject(), psiManager.findDirectory(root), getSettings())); } + */ + + nodes.addAll(modulesAndGroups(modules.toArray(new Module[modules.size()]))); final VirtualFile baseDir = getProject().getBaseDir(); if (baseDir == null) return nodes; diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java index 208223f8b3e6..047e12c09453 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java @@ -57,21 +57,27 @@ public class PsiDirectoryNode extends BasePsiNode { final PsiDirectory psiDirectory = getValue(); final VirtualFile directoryFile = psiDirectory.getVirtualFile(); + final Object parentValue = getParentValue(); if (ProjectRootsUtil.isModuleContentRoot(directoryFile, project)) { ProjectFileIndex fi = ProjectRootManager.getInstance(project).getFileIndex(); Module module = fi.getModuleForFile(directoryFile); data.setPresentableText(directoryFile.getName()); if (module != null) { - if (Comparing.equal(module.getName(), directoryFile.getName())) { - data.addText(directoryFile.getName(), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); + if (!(parentValue instanceof Module )) { + if (Comparing.equal(module.getName(), directoryFile.getName())) { + data.addText(directoryFile.getName(), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); + } + else { + data.addText(directoryFile.getName() + " ", SimpleTextAttributes.REGULAR_ATTRIBUTES); + data.addText("[" + module.getName() + "]", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); + } } else { - data.addText(directoryFile.getName() + " ", SimpleTextAttributes.REGULAR_ATTRIBUTES); - data.addText("[" + module.getName() + "]", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); + data.addText(directoryFile.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); } - if (getParentValue() instanceof Project) { + if (parentValue instanceof Project || parentValue instanceof Module) { data.addText(" (" + directoryFile.getPresentableUrl() + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES); } else if (ProjectRootsUtil.isSourceOrTestRoot(directoryFile, project)) { @@ -89,9 +95,9 @@ public class PsiDirectoryNode extends BasePsiNode { } } - final String name = getParentValue() instanceof Project + final String name = parentValue instanceof Project ? psiDirectory.getVirtualFile().getPresentableUrl() - : ProjectViewDirectoryHelper.getInstance(psiDirectory.getProject()).getNodeName(getSettings(), getParentValue(), psiDirectory); + : ProjectViewDirectoryHelper.getInstance(psiDirectory.getProject()).getNodeName(getSettings(), parentValue, psiDirectory); if (name == null) { setValue(null); return; diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/StructureViewModuleNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/StructureViewModuleNode.java index 397064957117..fc663a133279 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/StructureViewModuleNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/StructureViewModuleNode.java @@ -21,6 +21,7 @@ import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -48,4 +49,9 @@ public class StructureViewModuleNode extends AbstractModuleNode { public int getTypeSortWeight(final boolean sortByType) { return 2; } + + @Override + public boolean contains(@NotNull VirtualFile file) { + return false; + } } diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/StructureViewWrapper.java b/platform/lang-impl/src/com/intellij/ide/structureView/StructureViewWrapper.java index 6e0fd0696f40..78bdb6f9288b 100644 --- a/platform/lang-impl/src/com/intellij/ide/structureView/StructureViewWrapper.java +++ b/platform/lang-impl/src/com/intellij/ide/structureView/StructureViewWrapper.java @@ -17,6 +17,7 @@ package com.intellij.ide.structureView; import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.vfs.VirtualFile; /** * Created by IntelliJ IDEA. @@ -26,5 +27,5 @@ import com.intellij.openapi.fileEditor.FileEditor; * To change this template use File | Settings | File Templates. */ public interface StructureViewWrapper { - boolean selectCurrentElement(FileEditor fileEditor, boolean requestFocus); + boolean selectCurrentElement(FileEditor fileEditor, VirtualFile file, boolean requestFocus); } diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/impl/StructureViewFactoryImpl.java b/platform/lang-impl/src/com/intellij/ide/structureView/impl/StructureViewFactoryImpl.java index 3ee447ce4d84..554d10bda53a 100644 --- a/platform/lang-impl/src/com/intellij/ide/structureView/impl/StructureViewFactoryImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/structureView/impl/StructureViewFactoryImpl.java @@ -23,7 +23,6 @@ import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.fileEditor.FileEditor; -import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.MultiValuesMap; @@ -87,10 +86,7 @@ public final class StructureViewFactoryImpl extends StructureViewFactoryEx imple final Content content = ContentFactory.SERVICE.getInstance().createContent(myStructureViewWrapperImpl.getComponent(), "", false); Disposer.register(content, myStructureViewWrapperImpl); toolWindow.getContentManager().addContent(content); - final FileEditor[] fileEditors = FileEditorManager.getInstance(myProject).getSelectedEditors(); - if (fileEditors.length > 0) { - myStructureViewWrapperImpl.setFileEditor(fileEditors [0]); - } + if (myRunWhenInitialized != null) { myRunWhenInitialized.run(); myRunWhenInitialized = null; diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java index 2eacdd56cf48..49a3c4570d6d 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java @@ -22,10 +22,16 @@ */ package com.intellij.profile.codeInspection.ui; +import com.intellij.codeInsight.daemon.impl.HighlightInfoType; +import com.intellij.codeInsight.daemon.impl.SeverityRegistrar; import com.intellij.codeInspection.ModifiableModel; import com.intellij.codeInspection.ex.InspectionProfileImpl; import com.intellij.codeInspection.ex.InspectionToolRegistrar; +import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.colors.CodeInsightColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; @@ -36,6 +42,7 @@ import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.profile.Profile; @@ -53,9 +60,7 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Map; +import java.util.*; public abstract class InspectionToolsConfigurable extends BaseConfigurable implements ErrorsConfigurable { private CardLayout myLayout = new CardLayout(); @@ -116,7 +121,37 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple InspectionProfileImpl profile = new InspectionProfileImpl("TempProfile", InspectionToolRegistrar.getInstance(), myProfileManager); try { - profile.readExternal(JDOMUtil.loadDocument(VfsUtil.virtualToIoFile(files[0])).getRootElement()); + final Element rootElement = JDOMUtil.loadDocument(VfsUtil.virtualToIoFile(files[0])).getRootElement(); + final Set levels = new HashSet(); + for (Object o : rootElement.getChildren("inspection_tool")) { + final Element inspectElement = (Element)o; + levels.add(inspectElement.getAttributeValue("level")); + for (Object s : inspectElement.getChildren("scope")) { + levels.add(((Element)s).getAttributeValue("level")); + } + } + for (Iterator iterator = levels.iterator(); iterator.hasNext();) { + String level = iterator.next(); + if (myProfileManager.getOwnSeverityRegistrar().getSeverity(level) != null) { + iterator.remove(); + } + } + if (!levels.isEmpty()) { + if (Messages.showOkCancelDialog(myWholePanel, "Undefined severities detected: " + + StringUtil.join(levels, ", ") + + ". Do you want to create them?", "Warning", Messages.getWarningIcon()) == + DialogWrapper.OK_EXIT_CODE) { + for (String level : levels) { + final TextAttributes textAttributes = CodeInsightColors.WARNINGS_ATTRIBUTES.getDefaultAttributes(); + HighlightInfoType.HighlightInfoTypeImpl info + = new HighlightInfoType.HighlightInfoTypeImpl(new HighlightSeverity(level, 50), TextAttributesKey.createTextAttributesKey(level)); + myProfileManager.getOwnSeverityRegistrar() + .registerSeverity(new SeverityRegistrar.SeverityBasedTextAttributes(textAttributes.clone(), info), + textAttributes.getErrorStripeColor()); + } + } + } + profile.readExternal(rootElement); profile.initInspectionTools(); if (myProfileManager.getProfile(profile.getName(), false) != null) { if (Messages.showOkCancelDialog(myWholePanel, "Profile with name \'" + profile.getName() + "\' already exists. Do you want to overwrite it?", "Warning", Messages.getInformationIcon()) != DialogWrapper.OK_EXIT_CODE) return; diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java index a3b3d167936b..f409d9717fa0 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java @@ -19,6 +19,7 @@ package com.intellij.profile.codeInspection.ui; import com.intellij.CommonBundle; import com.intellij.codeHighlighting.HighlightDisplayLevel; import com.intellij.codeInsight.daemon.HighlightDisplayKey; +import com.intellij.codeInsight.daemon.impl.HighlightInfoType; import com.intellij.codeInsight.daemon.impl.SeverityRegistrar; import com.intellij.codeInspection.InspectionProfile; import com.intellij.codeInspection.InspectionProfileEntry; @@ -36,6 +37,8 @@ import com.intellij.ide.ui.search.SearchableOptionsRegistrar; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.Splitter; @@ -926,6 +929,7 @@ public class SingleInspectionProfilePanel extends JPanel { if (selectedProfile.getProfileManager().getProfile(selectedProfile.getName(), false) != null) { selectedProfile.getProfileManager().deleteProfile(selectedProfile.getName()); } + copyUsedSeveritiesIfUndefined(selectedProfile, profileManager); selectedProfile.setProfileManager(profileManager); } final InspectionProfile parentProfile = selectedProfile.getParentProfile(); @@ -948,6 +952,29 @@ public class SingleInspectionProfilePanel extends JPanel { myModified = false; } + private static void copyUsedSeveritiesIfUndefined(final ModifiableModel selectedProfile, final ProfileManager profileManager) { + final SeverityRegistrar registrar = ((SeverityProvider)profileManager).getSeverityRegistrar(); + final Set severities = ((InspectionProfileImpl)selectedProfile).getUsedSeverities(); + for (Iterator iterator = severities.iterator(); iterator.hasNext();) { + HighlightSeverity severity = iterator.next(); + if (registrar.isSeverityValid(severity.toString())) { + iterator.remove(); + } + } + + if (!severities.isEmpty()) { + final SeverityRegistrar oppositeRegister = ((SeverityProvider)selectedProfile.getProfileManager()).getSeverityRegistrar(); + for (HighlightSeverity severity : severities) { + final TextAttributesKey attributesKey = TextAttributesKey.find(severity.toString()); + final TextAttributes textAttributes = oppositeRegister.getTextAttributesBySeverity(severity); + LOG.assertTrue(textAttributes != null); + HighlightInfoType.HighlightInfoTypeImpl info = new HighlightInfoType.HighlightInfoTypeImpl(severity, attributesKey); + registrar.registerSeverity(new SeverityRegistrar.SeverityBasedTextAttributes(textAttributes.clone(), info), + textAttributes.getErrorStripeColor()); + } + } + } + private boolean descriptorsAreChanged() { for (Descriptor defaultDescriptor : myDescriptors.keySet()) { if (mySelectedProfile.isToolEnabled(defaultDescriptor.getKey(), (NamedScope)null) != defaultDescriptor.isEnabled()){ diff --git a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyHandler.java b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyHandler.java index a212cb6b1c8e..232dc80bae92 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyHandler.java @@ -87,7 +87,7 @@ public class CopyHandler { else if (ToolWindowId.STRUCTURE_VIEW.equals(id)) { VirtualFile virtualFile = newElement.getContainingFile().getVirtualFile(); FileEditor editor = FileEditorManager.getInstance(newElement.getProject()).getSelectedEditor(virtualFile); - StructureViewFactoryEx.getInstanceEx(project).getStructureViewWrapper().selectCurrentElement(editor, true); + StructureViewFactoryEx.getInstanceEx(project).getStructureViewWrapper().selectCurrentElement(editor, virtualFile, true); } } } diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java b/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java index 25d29cf7892c..c0f4924fe46c 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java @@ -74,6 +74,8 @@ public class ComponentWithBrowseButton extends JPanel i FontMetrics fontMetrics = comp.getFontMetrics(comp.getFont()); size.width = fontMetrics.charWidth('a') * charCount; comp.setPreferredSize(size); + final Dimension preferredSize = myBrowseButton.getPreferredSize(); + setPreferredSize(new Dimension(size.width + preferredSize.width + 2, preferredSize.height + 2)); } public void setEnabled(boolean enabled) { diff --git a/platform/platform-api/src/com/intellij/openapi/ui/TypingTarget.java b/platform/platform-api/src/com/intellij/openapi/ui/TypingTarget.java new file mode 100644 index 000000000000..4439e775d1f8 --- /dev/null +++ b/platform/platform-api/src/com/intellij/openapi/ui/TypingTarget.java @@ -0,0 +1,24 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.ui; + +import com.intellij.openapi.util.ActionCallback; + +public interface TypingTarget { + + ActionCallback type(String text); + +} diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacro.java b/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacro.java index 55175993432b..fcd575cecfbb 100644 --- a/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacro.java +++ b/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacro.java @@ -20,14 +20,14 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorActionManager; import com.intellij.openapi.editor.actionSystem.TypedAction; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.JDOMExternalizable; -import com.intellij.openapi.util.WriteExternalException; -import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.ui.playback.commands.KeyCodeTypeCommand; +import com.intellij.openapi.ui.playback.commands.TypeCommand; +import com.intellij.openapi.util.*; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import java.util.ArrayList; +import java.util.Arrays; import java.util.Iterator; import java.util.List; @@ -50,6 +50,8 @@ public class ActionMacro implements JDOMExternalizable { @NonNls private static final String ATTRIBUTE_TEXT = "text"; @NonNls + private static final String ATTRIBUTE_KEY_CODES = "text-keycode"; + @NonNls private static final String ELEMENT_ACTION = "action"; @NonNls private static final String ATTRIBUTE_ID = "id"; @@ -80,7 +82,8 @@ public class ActionMacro implements JDOMExternalizable { for (Iterator iterator = actions.iterator(); iterator.hasNext();) { Element action = (Element)iterator.next(); if (ELEMENT_TYPING.equals(action.getName())) { - myActions.add(new TypedDescriptor(action.getAttributeValue(ATTRIBUTE_TEXT))); + Pair, List> codes = parseKeyCodes(action.getAttributeValue(ATTRIBUTE_KEY_CODES)); + myActions.add(new TypedDescriptor(action.getAttributeValue(ATTRIBUTE_TEXT), codes.getFirst(), codes.getSecond())); } else if (ELEMENT_ACTION.equals(action.getName())) { myActions.add(new IdActionDescriptor(action.getAttributeValue(ATTRIBUTE_ID))); @@ -90,6 +93,14 @@ public class ActionMacro implements JDOMExternalizable { } } + private Pair, List> parseKeyCodes(String keyCodesText) { + return KeyCodeTypeCommand.parseKeyCodes(keyCodesText); + } + + public String unparseKeyCodes(Pair, List> keyCodes) { + return KeyCodeTypeCommand.unparseKeyCodes(keyCodes); + } + public void writeExternal(Element macro) throws WriteExternalException { macro.setAttribute(ATTRIBUTE_NAME, myName); final ActionDescriptor[] actions = getActions(); @@ -98,8 +109,10 @@ public class ActionMacro implements JDOMExternalizable { Element actionNode = null; if (action instanceof TypedDescriptor) { actionNode = new Element(ELEMENT_TYPING); - final String t = ((TypedDescriptor)action).getText(); + TypedDescriptor typedDescriptor = (TypedDescriptor)action; + final String t = typedDescriptor.getText(); actionNode.setAttribute(ATTRIBUTE_TEXT, JDOMUtil.escapeText(t)); + actionNode.setAttribute(ATTRIBUTE_KEY_CODES, unparseKeyCodes(new Pair, List>(typedDescriptor.getKeyCodes(), typedDescriptor.getKeyModifiers()))); } else if (action instanceof IdActionDescriptor) { actionNode = new Element(ELEMENT_ACTION); @@ -161,13 +174,13 @@ public class ActionMacro implements JDOMExternalizable { myActions.add(new ShortcutActionDesciption(text)); } - public void appendKeytyped(char c) { + public void appendKeytyped(char c, int keyCode, int modifiers) { ActionDescriptor lastAction = myActions.size() > 0 ? myActions.get(myActions.size() - 1) : null; if (lastAction instanceof TypedDescriptor) { - ((TypedDescriptor)lastAction).addChar(c); + ((TypedDescriptor)lastAction).addChar(c, keyCode, modifiers); } else { - myActions.add(new TypedDescriptor(c)); + myActions.add(new TypedDescriptor(c, keyCode, modifiers)); } } @@ -184,18 +197,30 @@ public class ActionMacro implements JDOMExternalizable { } public static class TypedDescriptor implements ActionDescriptor { + private String myText; - public TypedDescriptor(String text) { + private List myKeyCodes = new ArrayList(); + private List myModifiers = new ArrayList(); + + public TypedDescriptor(String text, List keyCodes, List modifiers) { myText = text; + myKeyCodes.addAll(keyCodes); + myModifiers.addAll(modifiers); + + assert myKeyCodes.size() == myModifiers.size() : "codes=" + myKeyCodes.toString() + " modifiers=" + myModifiers.toString(); } - public TypedDescriptor(char c) { + public TypedDescriptor(char c, int keyCode, int modifiers) { myText = String.valueOf(c); + myKeyCodes.add(keyCode); + myModifiers.add(modifiers); } - public void addChar(char c) { + public void addChar(char c, int keyCode, int modifier) { myText = myText + c; + myKeyCodes.add(keyCode); + myModifiers.add(modifier); } public String getText() { @@ -203,7 +228,7 @@ public class ActionMacro implements JDOMExternalizable { } public Object clone() { - return new TypedDescriptor(myText); + return new TypedDescriptor(myText, myKeyCodes, myModifiers); } public boolean equals(Object o) { @@ -217,8 +242,23 @@ public class ActionMacro implements JDOMExternalizable { } public void generateTo(StringBuffer script) { - script.append(myText); - script.append("\n"); + if (TypeCommand.containsUnicode(myText)) { + script.append(KeyCodeTypeCommand.PREFIX).append(" "); + + for (int i = 0; i < myKeyCodes.size(); i++) { + Integer each = myKeyCodes.get(i); + script.append(each.toString()); + script.append(KeyCodeTypeCommand.MODIFIER_DELIMITER); + script.append(myModifiers.get(i)); + if (i < myKeyCodes.size() - 1) { + script.append(KeyCodeTypeCommand.CODE_DELIMITER); + } + } + script.append(" ").append(myText).append("\n"); + } else { + script.append(myText); + script.append("\n"); + } } public String toString() { @@ -233,6 +273,14 @@ public class ActionMacro implements JDOMExternalizable { typedAction.actionPerformed(editor, chars[i], context); } } + + public List getKeyCodes() { + return myKeyCodes; + } + + public List getKeyModifiers() { + return myModifiers; + } } public static class ShortcutActionDesciption implements ActionDescriptor { diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacroManager.java b/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacroManager.java index b32bea00fd66..4cd3ade5eaa4 100644 --- a/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacroManager.java +++ b/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacroManager.java @@ -360,11 +360,11 @@ public class ActionMacroManager implements ExportableApplicationComponent, Named && e.getKeyCode() != KeyEvent.VK_META && e.getKeyCode() != KeyEvent.VK_SHIFT; - if (e.getID() == KeyEvent.KEY_TYPED && plainType && !isEnter) { - myRecordingMacro.appendKeytyped(e.getKeyChar()); + if (e.getID() == KeyEvent.KEY_PRESSED && plainType && !isEnter) { + myRecordingMacro.appendKeytyped(e.getKeyChar(), e.getKeyCode(), e.getModifiers()); } else if (e.getID() == KeyEvent.KEY_PRESSED && noModifierKeyIsPressed && (!plainType || isEnter)) { final boolean waiting = IdeEventQueue.getInstance().getKeyEventDispatcher().isWaitingForSecondKeyStroke(); - if (!e.equals(myLastActionInputEvent) && !waiting) { + if ((!e.equals(myLastActionInputEvent) && !waiting) || isEnter) { final String stroke = KeyStroke.getKeyStrokeForEvent(e).toString(); final int pressed = stroke.indexOf("pressed"); @@ -374,7 +374,9 @@ public class ActionMacroManager implements ExportableApplicationComponent, Named String ready = (modifiers.replaceAll("ctrl", "control").trim() + " " + key.trim()).trim(); myRecordingMacro.appendShortuct(ready); - myLastActionInputEvent = null; + if (!isEnter) { + myLastActionInputEvent = null; + } } } } diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/StartStopMacroRecordingAction.java b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/StartStopMacroRecordingAction.java index b508f088a8f4..f750dce297dc 100644 --- a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/StartStopMacroRecordingAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/StartStopMacroRecordingAction.java @@ -28,8 +28,11 @@ import com.intellij.openapi.project.DumbAware; */ public class StartStopMacroRecordingAction extends AnAction implements DumbAware { public void update(AnActionEvent e) { - e.getPresentation().setEnabled(e.getDataContext().getData(DataConstants.EDITOR) != null); - e.getPresentation().setText(ActionMacroManager.getInstance().isRecording() + boolean editorAvailable = e.getDataContext().getData(DataConstants.EDITOR) != null; + boolean isRecording = ActionMacroManager.getInstance().isRecording(); + + e.getPresentation().setEnabled(editorAvailable || isRecording); + e.getPresentation().setText(isRecording ? IdeBundle.message("action.stop.macro.recording") : IdeBundle.message("action.start.macro.recording")); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorComponentImpl.java index cd1fce386caa..bc0a3fb12e2e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorComponentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorComponentImpl.java @@ -22,6 +22,8 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.impl.ApplicationImpl; import com.intellij.openapi.ui.TestableUi; import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.ui.TypingTarget; +import com.intellij.openapi.util.ActionCallback; import javax.swing.*; import java.awt.*; @@ -33,7 +35,7 @@ import java.util.Map; /** * */ -public class EditorComponentImpl extends JComponent implements Scrollable, DataProvider, TestableUi { +public class EditorComponentImpl extends JComponent implements Scrollable, DataProvider, TestableUi, TypingTarget { private final EditorImpl myEditor; public EditorComponentImpl(EditorImpl editor) { @@ -96,6 +98,10 @@ public class EditorComponentImpl extends JComponent implements Scrollable, DataP } } + public ActionCallback type(String text) { + return myEditor.type(text); + } + public InputMethodRequests getInputMethodRequests() { return myEditor.getInputMethodRequests(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 234cd6fea95e..bc5d030aa1f1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -24,6 +24,7 @@ import com.intellij.ide.*; import com.intellij.ide.dnd.DnDManager; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ex.ApplicationManagerEx; @@ -593,17 +594,43 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myPropertyChangeSupport.firePropertyChange(PROP_FONT_SIZE, oldFontSize, fontSize); } - private void processKeyTyped(char c) { + public ActionCallback type(final String text) { + final ActionCallback result = new ActionCallback(); + + Application app = ApplicationManager.getApplication(); + if (!app.isWriteAccessAllowed()) { + result.setRejected(); + } else { + app.runWriteAction(new Runnable() { + public void run() { + for (int i = 0; i < text.length(); i++) { + if (!processKeyTyped(text.charAt(i))) { + result.setRejected(); + return; + } + } + + result.setDone(); + } + }); + } + + return result; + } + + private boolean processKeyTyped(char c) { // [vova] This is patch for Mac OS X. Under Mac "input methods" // is handled before our EventQueue consume upcoming KeyEvents. IdeEventQueue queue = IdeEventQueue.getInstance(); if (queue.shouldNotTypeInEditor() || ProgressManager.getInstance().hasModalProgressIndicator()) { - return; + return false; } ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); DataContext dataContext = getDataContext(); actionManager.fireBeforeEditorTyping(c, dataContext); EditorActionManager.getInstance().getTypedAction().actionPerformed(this, c, dataContext); + + return true; } private void fireFocusLost() { diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/playback/PlaybackRunner.java b/platform/platform-impl/src/com/intellij/openapi/ui/playback/PlaybackRunner.java index 0027308deb4e..d04b434ad180 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/playback/PlaybackRunner.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/playback/PlaybackRunner.java @@ -126,6 +126,10 @@ public class PlaybackRunner { return new EmptyCommand(line); } + if (actualString.startsWith(KeyCodeTypeCommand.PREFIX)) { + return new KeyCodeTypeCommand(string, line); + } + if (actualString.startsWith(DelayCommand.PREFIX)) { return new DelayCommand(string, line); } @@ -229,7 +233,7 @@ public class PlaybackRunner { } }); - new PlaybackRunner("%[comma]", new StatusCallback() { + new PlaybackRunner("%type", new StatusCallback() { public void error(String text, int currentLine) { System.out.println("Error: " + currentLine + " " + text); } diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/AlphaNumericTypeCommand.java b/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/AlphaNumericTypeCommand.java index c0a034f9a1c2..10a938d963ab 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/AlphaNumericTypeCommand.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/AlphaNumericTypeCommand.java @@ -15,8 +15,11 @@ */ package com.intellij.openapi.ui.playback.commands; +import com.intellij.openapi.ui.TypingTarget; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.ui.playback.PlaybackRunner; +import com.intellij.openapi.util.registry.Registry; +import org.jetbrains.annotations.Nullable; import java.awt.*; import java.awt.event.KeyEvent; @@ -28,7 +31,31 @@ public class AlphaNumericTypeCommand extends TypeCommand { } public ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot, boolean directActionCall) { - final String text = getText(); + return type(robot, getText()); + } + + protected ActionCallback type(final Robot robot, final String text) { + final ActionCallback result = new ActionCallback(); + + TypingTarget typingTarget = findTarget(); + if (typingTarget != null) { + typingTarget.type(text).doWhenDone(new Runnable() { + public void run() { + result.setDone(); + } + }).doWhenRejected(new Runnable() { + public void run() { + typeByRobot(robot, text).notify(result); + } + }); + } else { + typeByRobot(robot, text).notify(result); + } + + return result; + } + + private ActionCallback typeByRobot(Robot robot, String text) { for (int i = 0; i < text.length(); i++) { final char each = text.charAt(i); if ('\\' == each && i + 1 < text.length()) { @@ -57,4 +84,23 @@ public class AlphaNumericTypeCommand extends TypeCommand { } return new ActionCallback.Done(); } + + @Nullable + public static TypingTarget findTarget() { + if (!Registry.is("actionSystem.playback.useTypingTargets")) return null; + + Component each = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + + while (each != null) { + if (each instanceof TypingTarget) { + return (TypingTarget)each; + } + + each = each.getParent(); + } + + return null; + } + + } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/KeyCodeTypeCommand.java b/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/KeyCodeTypeCommand.java new file mode 100644 index 000000000000..b0b8745fa3e4 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/KeyCodeTypeCommand.java @@ -0,0 +1,135 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.ui.playback.commands; + +import com.intellij.openapi.ui.TypingTarget; +import com.intellij.openapi.ui.playback.PlaybackRunner; +import com.intellij.openapi.util.ActionCallback; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.registry.Registry; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.awt.List; +import java.util.*; + +public class KeyCodeTypeCommand extends AlphaNumericTypeCommand { + + public static final String PREFIX = CMD_PREFIX + "type"; + public static final String CODE_DELIMITER = ";"; + public static final String MODIFIER_DELIMITER = ":"; + + public KeyCodeTypeCommand(String text, int line) { + super(text, line); + } + + @Override + public ActionCallback _execute(final PlaybackRunner.StatusCallback cb, final Robot robot, boolean directActionCall) { + String text = getText().substring(PREFIX.length()).trim(); + + int textDelim = text.indexOf(" "); + + final String codes; + if (textDelim >= 0) { + codes = text.substring(0, textDelim); + } else { + codes = text; + } + + String unicode; + if (codes.length() + 1 < text.length()) { + unicode = text.substring(textDelim + 1); + } else { + unicode = ""; + } + + final ActionCallback result = new ActionCallback(); + + TypingTarget typingTarget = findTarget(); + if (typingTarget != null) { + typingTarget.type(unicode).doWhenDone(new Runnable() { + public void run() { + result.setDone(); + } + }).doWhenRejected(new Runnable() { + public void run() { + typeCodes(cb, robot, codes).notify(result); + } + }); + } else { + typeCodes(cb, robot, codes).notify(result); + } + + return result; + } + + private ActionCallback typeCodes(PlaybackRunner.StatusCallback cb, Robot robot, String codes) { + String[] pairs = codes.split(CODE_DELIMITER); + for (String eachPair : pairs) { + try { + String[] splits = eachPair.split(MODIFIER_DELIMITER); + Integer code = Integer.valueOf(splits[0]); + Integer modifier = Integer.valueOf(splits[1]); + type(robot, code.intValue(), modifier.intValue()); + } + catch (NumberFormatException e) { + dumpError(cb, "Invalid code: " + eachPair); + return new ActionCallback.Rejected(); + } + } + + + return new ActionCallback.Done(); + } + + public static Pair, java.util.List> parseKeyCodes(String keyCodesText) { + ArrayList codes = new ArrayList(); + ArrayList modifiers = new ArrayList(); + + if (keyCodesText != null) { + String[] pairs = keyCodesText.split(CODE_DELIMITER); + for (String each : pairs) { + String[] strings = each.split(MODIFIER_DELIMITER); + if (strings.length == 2) { + codes.add(Integer.valueOf(strings[0])); + modifiers.add(Integer.valueOf(strings[1])); + } + } + } + + return new Pair, java.util.List>(codes, modifiers); + } + + public static String unparseKeyCodes(Pair, java.util.List> pairs) { + StringBuffer result = new StringBuffer(); + + java.util.List codes = pairs.getFirst(); + java.util.List modifiers = pairs.getSecond(); + + for (int i = 0; i < codes.size(); i++) { + Integer each = codes.get(i); + result.append(each.toString()); + result.append(MODIFIER_DELIMITER); + result.append(modifiers.get(i)); + if (i < codes.size() - 1) { + result.append(CODE_DELIMITER); + } + } + + return result.toString(); + } + +} diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/KeyShortcutCommand.java b/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/KeyShortcutCommand.java index cfca38ba76b5..c5bd853b1588 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/KeyShortcutCommand.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/KeyShortcutCommand.java @@ -23,7 +23,7 @@ import java.awt.*; public class KeyShortcutCommand extends TypeCommand { public static String PREFIX = CMD_PREFIX + "["; - public static String POSTFIX = CMD_PREFIX + "]"; + public static String POSTFIX = "]"; public KeyShortcutCommand(String text, int line) { super(text, line); @@ -31,7 +31,7 @@ public class KeyShortcutCommand extends TypeCommand { public ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot, boolean directActionCall) { final String one = getText().substring(PREFIX.length()); - if (!one.endsWith("]")) { + if (!one.endsWith(POSTFIX)) { dumpError(cb, "Expected " + "]"); return new ActionCallback.Rejected(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/KeyStokeMap.java b/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/KeyStokeMap.java index f3831b55973c..3ef546a7d14e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/KeyStokeMap.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/KeyStokeMap.java @@ -22,7 +22,6 @@ import javax.swing.*; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.util.HashMap; -import java.util.Locale; import java.util.Map; public class KeyStokeMap { @@ -32,11 +31,17 @@ public class KeyStokeMap { private Map myMap; public KeyStroke get(char c) { - if (myMap == null) { - myMap = generateKeyStrokeMappings(); - } + Character mappedChar = new Character(c); - return myMap.get(new Character(c)); + if (getMap().containsKey(mappedChar)) { + return getMap().get(mappedChar); + } else { + return KeyStroke.getKeyStroke(c); + } + } + + public boolean containsChar(char c) { + return getMap().containsKey(c); } public KeyStroke get(String strokeText) { @@ -136,13 +141,13 @@ public class KeyStokeMap { map.put(new Character((char)entry[0]), stroke); } - // If the locale is not en_US/GB, provide only a very basic map and - // rely on key_typed events instead - Locale locale = Locale.getDefault(); - if (!Locale.US.equals(locale) && !Locale.UK.equals(locale)) { - LOG.debug("Not US: " + locale); - return map; - } + //// If the locale is not en_US/GB, provide only a very basic map and + //// rely on key_typed events instead + //Locale locale = Locale.getDefault(); + //if (!Locale.US.equals(locale) && !Locale.UK.equals(locale)) { + // LOG.debug("Not US: " + locale); + // return map; + //} // Basic symbol/punctuation mappings for (int i = 0; i < mappings.length; i++) { @@ -175,4 +180,11 @@ public class KeyStokeMap { return map; } + private Map getMap() { + if (myMap == null) { + myMap = generateKeyStrokeMappings(); + } + + return myMap; + } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/TypeCommand.java b/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/TypeCommand.java index a4f1d864a8c7..02530d93fec4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/TypeCommand.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/playback/commands/TypeCommand.java @@ -24,7 +24,7 @@ import java.awt.event.KeyEvent; public abstract class TypeCommand extends AbstractCommand { - private KeyStokeMap myMap = new KeyStokeMap(); + private static KeyStokeMap ourMap = new KeyStokeMap(); public TypeCommand(String text, int line) { super(text, line); @@ -56,9 +56,16 @@ public abstract class TypeCommand extends AbstractCommand { robot.keyPress(KeyEvent.VK_META); } - robot.keyPress(keyStroke.getKeyCode()); - robot.delay(Registry.intValue("actionSystem.playback.autodelay")); - robot.keyRelease(keyStroke.getKeyCode()); + if (keyStroke.getKeyCode() > 0) { + robot.keyPress(keyStroke.getKeyCode()); + robot.delay(Registry.intValue("actionSystem.playback.autodelay")); + robot.keyRelease(keyStroke.getKeyCode()); + } else { + robot.keyPress(keyStroke.getKeyChar()); + robot.delay(Registry.intValue("actionSystem.playback.autodelay")); + robot.keyRelease(keyStroke.getKeyChar()); + } + if (shift) { robot.keyRelease(KeyEvent.VK_SHIFT); @@ -78,10 +85,18 @@ public abstract class TypeCommand extends AbstractCommand { } protected KeyStroke get(char c) { - return myMap.get(c); + return ourMap.get(c); } protected KeyStroke getFromShortcut(String sc) { - return myMap.get(sc); + return ourMap.get(sc); + } + + public static boolean containsUnicode(String s) { + for (int i = 0; i < s.length(); i++) { + if (!ourMap.containsChar(s.charAt(i))) return true; + } + + return false; } } \ No newline at end of file diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 32bd52c1ebe3..35fe382c6e0b 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -17,6 +17,7 @@ actionSystem.typeAheadTimeBeforeDialog.description=If dialog shown as a result o actionSystem.playback.autodelay=20 actionSystem.playback.autodelay.description=Delay between events generated by the playback runner actionSystem.playback.useDirectActionCall=true +actionSystem.playback.useTypingTargets=true actionSystem.focusIdleTimeout=20 actionSystem.mac.screenMenuNotUpdatedFix=false actionSystem.keyGestures.enabled=false diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index e82e662923cd..32194841e990 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -286,6 +286,7 @@ + diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java index 0d3d267dfb40..8cfab7e3ba83 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java @@ -27,6 +27,7 @@ import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.DumbAwareRunnable; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.*; @@ -561,7 +562,11 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme } StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new Runnable() { public void run() { - myMappings.setDirectoryMappings(mappingsList); + DumbService.getInstance(myProject).runWhenSmart(new Runnable() { + public void run() { + myMappings.setDirectoryMappings(mappingsList); + } + }); } }); } diff --git a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties index 0986ee4cac5f..f86bd858a29a 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties @@ -1312,7 +1312,8 @@ unnecessarily.qualified.static.usage.problem.descriptor1=Unnecessarily qualified unnecessarily.qualified.static.usage.ignore.field.option=Ignore unnecessarily qualified field accesses unnecessarily.qualified.static.usage.ignore.method.option=Ignore unnecessarily qualified method calls unnecessary.interface.modifier.problem.descriptor=Modifier #ref is redundant for interfaces #loc -unnecessary.interface.modifier.problem.descriptor1=Modifier #ref is redundant for inner interfaces of interfaces #loc +unnecessary.interface.modifier.inner.interface.of.interface.problem.descriptor=Modifier #ref is redundant for inner interfaces of interfaces #loc +unnecessary.interface.modifier.inner.interface.of.class.problem.descriptor=Modifier #ref is redundant for inner interfaces of classes #loc unnecessary.interface.modifier.problem.descriptor2=Modifier #ref is redundant for interface methods #loc unnecessary.interface.modifier.problem.descriptor3=Modifier #ref is redundant for inner classes of interfaces #loc unnecessary.interface.modifier.problem.descriptor4=Modifier #ref is redundant for interface fields #loc @@ -1754,4 +1755,4 @@ unnecessary.javadoc.link.display.name=Unnecessary JavaDoc link unnecessary.javadoc.link.problem.descriptor=#ref is unnecessary unnecessary.javadoc.link.quickfix=Remove unnecessary {0} thread.local.not.static.final.display.name=ThreadLocal field not declared static final -thread.local.not.static.final.problem.descriptor=ThreadLocal #ref is not declared 'static final' \ No newline at end of file +thread.local.not.static.final.problem.descriptor=ThreadLocal #ref is not declared 'static final' diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InstanceOfUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InstanceOfUtils.java index fa8e4b66c00d..458f40f99374 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InstanceOfUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InstanceOfUtils.java @@ -108,15 +108,17 @@ public class InstanceOfUtils { expression.getOperationSign(); final IElementType tokenType = sign.getTokenType(); if (tokenType == JavaTokenType.ANDAND) { - inElse = false; - final PsiExpression lhs = expression.getLOperand(); - checkExpression(lhs); - final PsiExpression rhs = expression.getROperand(); - checkExpression(rhs); + checkExpression(expression.getLOperand()); + checkExpression(expression.getROperand()); + if (!inElse && conflictingInstanceof != null) { + agreeingInstanceof = false; + } } else if (tokenType == JavaTokenType.OROR) { - inElse = true; - final PsiExpression lhs = expression.getLOperand(); - checkExpression(lhs); + checkExpression(expression.getLOperand()); + checkExpression(expression.getROperand()); + if (inElse && conflictingInstanceof != null) { + agreeingInstanceof = false; + } } } @@ -259,4 +261,4 @@ public class InstanceOfUtils { return conflictingInstanceof; } } -} \ No newline at end of file +} diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryInterfaceModifierInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryInterfaceModifierInspection.java index ba33b2c6b63a..666226451957 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryInterfaceModifierInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryInterfaceModifierInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2009 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. @@ -65,8 +65,13 @@ public class UnnecessaryInterfaceModifierInspection extends BaseInspection { final PsiClass containingClass = aClass.getContainingClass(); if (containingClass != null) { if (aClass.isInterface()) { - return InspectionGadgetsBundle.message( - "unnecessary.interface.modifier.problem.descriptor1"); + if (containingClass.isInterface()) { + return InspectionGadgetsBundle.message( + "unnecessary.interface.modifier.inner.interface.of.interface.problem.descriptor"); + } else { + return InspectionGadgetsBundle.message( + "unnecessary.interface.modifier.inner.interface.of.class.problem.descriptor"); + } } else { return InspectionGadgetsBundle.message( "unnecessary.interface.modifier.problem.descriptor3"); @@ -91,15 +96,15 @@ public class UnnecessaryInterfaceModifierInspection extends BaseInspection { @Override public InspectionGadgetsFix buildFix(Object... infos) { - return new UnnecessaryInterfaceModifersFix((String) infos[0]); + return new UnnecessaryInterfaceModifiersFix((String) infos[0]); } - private static class UnnecessaryInterfaceModifersFix + private static class UnnecessaryInterfaceModifiersFix extends InspectionGadgetsFix { private final String modifiersText; - private UnnecessaryInterfaceModifersFix(String modifiersText) { + private UnnecessaryInterfaceModifiersFix(String modifiersText) { this.modifiersText = modifiersText; } @@ -217,4 +222,4 @@ public class UnnecessaryInterfaceModifierInspection extends BaseInspection { } } } -} \ No newline at end of file +} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/elseElse/ElseElse.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/elseElse/ElseElse.java new file mode 100644 index 000000000000..fc68cfe0d3aa --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/elseElse/ElseElse.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2009 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. + */ +public interface I {} +class A implements I {} +class B implements I {} + +class U { + void foo(Object o, boolean b) { + if (o instanceof I && b) { + + } else { + if (o instanceof A) { + + } else { + B bb = (B)o; + } + } + } +} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/elseElse/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/elseElse/expected.xml new file mode 100644 index 000000000000..580a889dbfd6 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/elseElse/expected.xml @@ -0,0 +1,3 @@ + + + diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/elseElseOrOr/ElseElse.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/elseElseOrOr/ElseElse.java new file mode 100644 index 000000000000..657c588cbbfa --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/elseElseOrOr/ElseElse.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2009 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. + */ +public interface I {} +class A implements I {} +class B implements I {} + +class U { + void foo(Object o, boolean b) { + if (o instanceof I || b) { + + } else { + if (o instanceof A) { + + } else { + B bb = (B)o; + } + } + } +} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/elseElseOrOr/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/elseElseOrOr/expected.xml new file mode 100644 index 000000000000..580a889dbfd6 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/elseElseOrOr/expected.xml @@ -0,0 +1,3 @@ + + + diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/simple/ElseElse.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/simple/ElseElse.java new file mode 100644 index 000000000000..9c10e992a4ef --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/simple/ElseElse.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2009 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. + */ +public interface I {} +class A implements I {} +class B implements I {} + +class U { + void foo(Object o, boolean b) { + if (o instanceof I && b) { + + } else { + if (o instanceof A) { + B bb = (B)o; + } else { + } + } + } +} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/simple/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/simple/expected.xml new file mode 100644 index 000000000000..c81a83943265 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/simple/expected.xml @@ -0,0 +1,8 @@ + + + + ElseElse.java + 26 + Cast to <code>(B)o</code> conflicts with surrounding 'instanceof' check #loc + + diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspectionTest.java new file mode 100644 index 000000000000..b64c12f9596b --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspectionTest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2009 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.bugs; + +import com.IGInspectionTestCase; + +public class CastConflictsWithInstanceofInspectionTest extends IGInspectionTestCase { + + public void testElseElse() throws Exception { + doTest(); + } + + public void testSimple() throws Exception { + doTest(); + } + + public void testElseElseOrOr() throws Exception { + doTest(); + } + + private void doTest() throws Exception { + doTest("com/siyeh/igtest/bugs/castConflictingInstanceof/" + getTestName(false), new CastConflictsWithInstanceofInspection()); + } +} diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/util/AnnotationUtilEx.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/util/AnnotationUtilEx.java index 8547922d2174..cbb98ac79f86 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/util/AnnotationUtilEx.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/util/AnnotationUtilEx.java @@ -241,9 +241,10 @@ public class AnnotationUtilEx { if (listOwner instanceof PsiParameter) { PsiParameter parameter = (PsiParameter)listOwner; PsiElement declarationScope = parameter.getDeclarationScope(); - if (declarationScope instanceof PsiMethod && parameter.getParent() == ((PsiMethod)declarationScope).getParameterList()) { + PsiParameterList parameterList; + if (declarationScope instanceof PsiMethod && parameter.getParent() == (parameterList = ((PsiMethod)declarationScope).getParameterList())) { PsiMethod method = (PsiMethod)declarationScope; - final int parameterIndex = method.getParameterList().getParameterIndex(parameter); + final int parameterIndex = parameterList.getParameterIndex(parameter); all.addAll(Arrays.asList(modifierList.getAnnotations())); SuperMethodsSearch.search(method, null, true, true).forEach(new Processor() { public boolean process(final MethodSignatureBackedByPsiMethod superMethod) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index e743e6052466..6665639f686b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -425,7 +425,7 @@ public class GroovyAnnotator implements Annotator { for (List args : map.values()) { for (int i = 1; i < args.size(); i++) { GrNamedArgument namedArgument = args.get(i); - holder.createErrorAnnotation(namedArgument, GroovyBundle.message("duplicate.element.in.the.map")); + holder.createWarningAnnotation(namedArgument, GroovyBundle.message("duplicate.element.in.the.map")); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java index 1eda5cea10d0..a02a2b9ec3b6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java @@ -141,7 +141,13 @@ public class GroovycStubGenerator extends GroovyCompilerBase { deleteChildrenRecursively(child); } TranslatingCompilerFilesMonitor.removeSourceInfo(child); - child.delete(this); + try { + child.delete(this); + } + catch (IOException ignored) { + //may be a leaked handle from some non-completely terminated compiler process, or compiler caches, or something else + //not a big deal, we'll delete it next time + } } } }.execute(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrLiteralImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrLiteralImpl.java index 902482de6da2..96a222aeaea9 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrLiteralImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrLiteralImpl.java @@ -22,11 +22,12 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry; +import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference; import com.intellij.psi.impl.source.tree.LeafElement; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; -import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrExpressionImpl; @@ -36,6 +37,8 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.util.List; +import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*; + /** * @author ilyas */ @@ -120,6 +123,16 @@ public class GrLiteralImpl extends GrExpressionImpl implements GrLiteral, PsiLan return ReferenceProvidersRegistry.getReferencesFromProviders(this, GrLiteral.class); } + @Nullable + @Override + public PsiReference getReference() { + final PsiReference[] references = getReferences(); + if (references.length > 0) { + return new PsiMultiReference(references, this); + } + return null; + } + public List> getInjectedPsi() { if (!(getValue() instanceof String)) return null; return InjectedLanguageUtil.getInjectedPsiFiles(this); diff --git a/plugins/junit/src/com/intellij/execution/junit/TestObject.java b/plugins/junit/src/com/intellij/execution/junit/TestObject.java index cd8c0fa1f5c8..dc41fd979f9e 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestObject.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestObject.java @@ -46,8 +46,8 @@ import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.psi.PsiElement; import com.intellij.refactoring.listeners.RefactoringElementListener; -import com.intellij.rt.execution.junit.JUnitStarter; import com.intellij.rt.execution.junit.IDEAJUnitListener; +import com.intellij.rt.execution.junit.JUnitStarter; import com.intellij.util.Function; import com.intellij.util.PathUtil; import org.jetbrains.annotations.NotNull; @@ -57,7 +57,10 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.List; public abstract class TestObject implements JavaCommandLine { protected static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit.TestObject"); @@ -296,13 +299,18 @@ public abstract class TestObject implements JavaCommandLine { try { writer.println(junit4 ? JUnitStarter.JUNIT4_PARAMETER : "-junit3"); writer.println(packageName); + final List testNames = new ArrayList(); for (final PsiElement element : elements) { final String name = nameFunction.fun(element); if (name == null) { LOG.error("invalid element " + element); return; } - writer.println(name); + testNames.add(name); + } + Collections.sort(testNames); //sort tests in FQN order + for (String testName : testNames) { + writer.println(testName); } } finally { 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 68d29c785d5d..6708aac730dd 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 @@ -242,16 +242,6 @@ public class MavenProjectsStructure extends SimpleTreeStructure { ALWAYS, NEVER, NORMAL } - private DisplayKind getDisplayKind(CustomNode node) { - Class[] visibles = getVisibleNodesClasses(); - if (visibles == null) return DisplayKind.NORMAL; - - for (Class each : visibles) { - if (each.isInstance(node)) return DisplayKind.ALWAYS; - } - return DisplayKind.NORMAL; - } - protected Class[] getVisibleNodesClasses() { return null; } @@ -353,7 +343,13 @@ public class MavenProjectsStructure extends SimpleTreeStructure { } public DisplayKind getDisplayKind() { - return MavenProjectsStructure.this.getDisplayKind(this); + Class[] visibles = getVisibleNodesClasses(); + if (visibles == null) return DisplayKind.NORMAL; + + for (Class each : visibles) { + if (each.isInstance(this)) return DisplayKind.ALWAYS; + } + return DisplayKind.NEVER; } public CustomNode[] getChildren() { @@ -1094,11 +1090,6 @@ public class MavenProjectsStructure extends SimpleTreeStructure { setNodeErrorLevel(myArtifact.isResolved() ? ErrorLevel.NONE : ErrorLevel.ERROR); } - @Override - public boolean isVisible() { - return true; - } - @Override public Navigatable getNavigatable() { final Module m = myProjectsManager.findModule(myMavenProject); @@ -1119,5 +1110,10 @@ public class MavenProjectsStructure extends SimpleTreeStructure { } }; } + + @Override + public boolean isVisible() { + return getDisplayKind() != DisplayKind.NEVER; + } } } diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 781d9f879bb1..faa30377fd39 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -828,7 +828,7 @@ - + diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java index 70f6a5711831..82fab83bb460 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java @@ -12,6 +12,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Factory; import com.intellij.openapi.util.Key; @@ -320,7 +321,7 @@ public final class DomManagerImpl extends DomManager { } final InvocationHandler handler = AdvancedProxy.getInvocationHandler(proxy); if (handler instanceof StableInvocationHandler) { - final DomElement element = ((StableInvocationHandler)handler).getWrappedElement(); + final DomElement element = ((StableInvocationHandler)handler).getWrappedElement(); return element == null ? null : getDomInvocationHandler(element); } if (handler instanceof DomInvocationHandler) { @@ -493,9 +494,17 @@ public final class DomManagerImpl extends DomManager { } public final T createStableValue(final Factory provider) { + return createStableValue(provider, new Condition() { + public boolean value(T t) { + return t.isValid(); + } + }); + } + + public final T createStableValue(final Factory provider, final Condition validator) { final T initial = provider.create(); assert initial != null; - final StableInvocationHandler handler = new StableInvocationHandler(initial, provider); + final StableInvocationHandler handler = new StableInvocationHandler(initial, provider, validator); final Set intf = new HashSet(); intf.addAll(Arrays.asList(initial.getClass().getInterfaces())); diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/StableInvocationHandler.java b/xml/dom-impl/src/com/intellij/util/xml/impl/StableInvocationHandler.java index 48a5ce1cc8c4..82f802f16ee4 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/StableInvocationHandler.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/StableInvocationHandler.java @@ -16,6 +16,7 @@ package com.intellij.util.xml.impl; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Factory; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xml.DomElement; @@ -33,16 +34,18 @@ import java.util.Set; /** * @author peter */ -class StableInvocationHandler implements InvocationHandler, StableElement { +class StableInvocationHandler implements InvocationHandler, StableElement { private T myOldValue; private T myCachedValue; private final Set myClasses; private final Factory myProvider; + private final Condition myValidator; - public StableInvocationHandler(final T initial, final Factory provider) { + public StableInvocationHandler(final T initial, final Factory provider, Condition validator) { myProvider = provider; myCachedValue = initial; myOldValue = initial; + myValidator = validator; final Class superClass = initial.getClass().getSuperclass(); final Set classes = new HashSet(); classes.addAll(Arrays.asList(initial.getClass().getInterfaces())); @@ -125,7 +128,7 @@ class StableInvocationHandler implements InvocationHandler } } - public final DomElement getWrappedElement() { + public final T getWrappedElement() { if (isNotValid(myCachedValue)) { myCachedValue = myProvider.create(); } @@ -137,7 +140,7 @@ class StableInvocationHandler implements InvocationHandler } private boolean isNotValid(final T t) { - if (t == null || !t.isValid()) return true; + if (t == null || !myValidator.value(t)) return true; for (final Class aClass : myClasses) { if (!aClass.isInstance(t)) return true; } diff --git a/xml/dom-openapi/src/com/intellij/util/xml/DomManager.java b/xml/dom-openapi/src/com/intellij/util/xml/DomManager.java index 01a54cd28e52..df0a415e5490 100644 --- a/xml/dom-openapi/src/com/intellij/util/xml/DomManager.java +++ b/xml/dom-openapi/src/com/intellij/util/xml/DomManager.java @@ -19,10 +19,7 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Factory; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.ModificationTracker; -import com.intellij.openapi.util.NotNullLazyKey; +import com.intellij.openapi.util.*; import com.intellij.psi.PsiReferenceFactory; import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlFile; @@ -121,6 +118,8 @@ public abstract class DomManager implements ModificationTracker { */ public abstract T createStableValue(Factory provider); + public abstract T createStableValue(final Factory provider, final Condition validator); + /** * Registers a new {@link com.intellij.util.xml.DomFileDescription} within the manager. The description parameter describes some DOM * parameters and restrictions to the particular XML files, that need DOM support. Should be called on