diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java index b6ca9eafe1f1..759d92fd57a8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java @@ -30,6 +30,7 @@ public final class EvaluationContextImpl implements EvaluationContext{ private final SuspendContextImpl mySuspendContext; private final StackFrameProxyImpl myFrameProxy; private boolean myAutoLoadClasses = true; + private ClassLoaderReference myClassLoader; public EvaluationContextImpl(@NotNull SuspendContextImpl suspendContext, StackFrameProxyImpl frameProxy, @Nullable Value thisObject) { myThisObject = thisObject; @@ -77,9 +78,16 @@ public final class EvaluationContextImpl implements EvaluationContext{ @Override public ClassLoaderReference getClassLoader() throws EvaluateException { DebuggerManagerThreadImpl.assertIsManagerThread(); + if (myClassLoader != null) { + return myClassLoader; + } return myFrameProxy != null ? myFrameProxy.getClassLoader() : null; } + public void setClassLoader(ClassLoaderReference classLoader) { + myClassLoader = classLoader; + } + public boolean isAutoLoadClasses() { return myAutoLoadClasses; } diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form index 7246f2cfb566..61333a8ed4ec 100644 --- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form +++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form @@ -79,7 +79,14 @@ - + + + + + + + + diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java index 10e11f74077f..94e551250aed 100644 --- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java +++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java @@ -54,6 +54,7 @@ import com.intellij.ui.CollectionListModel; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.ListSpeedSearch; import com.intellij.ui.SingleSelectionModel; +import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBList; import com.intellij.ui.popup.list.GroupedItemsListRenderer; import com.intellij.util.Function; @@ -81,10 +82,6 @@ import java.util.List; @SuppressWarnings("unchecked") public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, Disposable { - private static final String TEMPLATES_CARD = "templates card"; - private static final String FRAMEWORKS_CARD = "frameworks card"; - - private static final String PROJECT_WIZARD_GROUP = "project.wizard.group"; public static final Convertor PROVIDER_STRING_CONVERTOR = new Convertor() { @Override @@ -98,23 +95,14 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D return node.getId(); } }; - - private JPanel myPanel; - private JPanel myOptionsPanel; - private JBList myProjectTypeList; - private ProjectTemplateList myTemplatesList; - private JPanel myFrameworksPanelPlaceholder; - private JPanel myHeaderPanel; - + private static final String TEMPLATES_CARD = "templates card"; + private static final String FRAMEWORKS_CARD = "frameworks card"; + private static final String PROJECT_WIZARD_GROUP = "project.wizard.group"; private final WizardContext myContext; private final NewProjectWizard myWizard; private final ModulesProvider myModulesProvider; private final AddSupportForFrameworksPanel myFrameworksPanel; private final ModuleBuilder.ModuleConfigurationUpdater myConfigurationUpdater; - @Nullable - private ModuleWizardStep mySettingsStep; - - @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") private final FactoryMap myBuilders = new FactoryMap() { @Nullable @@ -125,6 +113,15 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D }; private final Map myCustomSteps = new HashMap(); private final MultiMap myTemplatesMap; + private JPanel myPanel; + private JPanel myOptionsPanel; + private JBList myProjectTypeList; + private ProjectTemplateList myTemplatesList; + private JPanel myFrameworksPanelPlaceholder; + private JPanel myHeaderPanel; + private JBLabel myFrameworksLabel; + @Nullable + private ModuleWizardStep mySettingsStep; private String myCurrentCard; private TemplatesGroup myLastSelectedGroup; @@ -206,6 +203,8 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D myFrameworksPanel = new AddSupportForFrameworksPanel(Collections.emptyList(), model, true, myHeaderPanel); Disposer.register(this, myFrameworksPanel); myFrameworksPanelPlaceholder.add(myFrameworksPanel.getMainPanel()); + myFrameworksLabel.setLabelFor(myFrameworksPanel.getFrameworksTree()); + myFrameworksLabel.setBorder(IdeBorderFactory.createEmptyBorder(3)); myConfigurationUpdater = new ModuleBuilder.ModuleConfigurationUpdater() { @Override @@ -258,6 +257,20 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D myTemplatesList.restoreSelection(); } + private static ModuleType getModuleType(TemplatesGroup group) { + ModuleBuilder moduleBuilder = group.getModuleBuilder(); + return moduleBuilder == null ? null : moduleBuilder.getModuleType(); + } + + private static boolean matchFramework(ProjectCategory projectCategory, FrameworkSupportInModuleProvider framework) { + + FrameworkRole[] roles = framework.getRoles(); + if (roles.length == 0) return true; + + List acceptable = Arrays.asList(projectCategory.getAcceptableFrameworkRoles()); + return ContainerUtil.intersects(Arrays.asList(roles), acceptable); + } + private boolean isFrameworksMode() { return FRAMEWORKS_CARD.equals(myCurrentCard) && getSelectedBuilder().equals(myContext.getProjectBuilder()); } @@ -356,11 +369,6 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D return groups; } - private static ModuleType getModuleType(TemplatesGroup group) { - ModuleBuilder moduleBuilder = group.getModuleBuilder(); - return moduleBuilder == null ? null : moduleBuilder.getModuleType(); - } - // new TemplatesGroup selected public void projectTypeChanged() { TemplatesGroup group = getSelectedGroup(); @@ -438,15 +446,6 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D showCard(TEMPLATES_CARD); } - private static boolean matchFramework(ProjectCategory projectCategory, FrameworkSupportInModuleProvider framework) { - - FrameworkRole[] roles = framework.getRoles(); - if (roles.length == 0) return true; - - List acceptable = Arrays.asList(projectCategory.getAcceptableFrameworkRoles()); - return ContainerUtil.intersects(Arrays.asList(roles), acceptable); - } - private void setTemplatesList(TemplatesGroup group, Collection templates, boolean preserveSelection) { List list = new ArrayList(templates); ModuleBuilder moduleBuilder = group.getModuleBuilder(); diff --git a/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java b/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java index 90c4f630df1c..c6c4f6c144d2 100644 --- a/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java +++ b/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java @@ -72,79 +72,86 @@ public class JavaLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSett } else if (settingsType == SettingsType.WRAPPING_AND_BRACES_SETTINGS) { consumer.showStandardOptions("RIGHT_MARGIN", + "KEEP_CONTROL_STATEMENT_IN_ONE_LINE", + "LINE_COMMENT_AT_FIRST_COLUMN", + "BLOCK_COMMENT_AT_FIRST_COLUMN", "KEEP_LINE_BREAKS", "KEEP_FIRST_COLUMN_COMMENT", - "KEEP_CONTROL_STATEMENT_IN_ONE_LINE", - "KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE", - "KEEP_SIMPLE_BLOCKS_IN_ONE_LINE", - "KEEP_SIMPLE_METHODS_IN_ONE_LINE", - "KEEP_SIMPLE_CLASSES_IN_ONE_LINE", - "WRAP_LONG_LINES", - "CLASS_BRACE_STYLE", - "METHOD_BRACE_STYLE", - "BRACE_STYLE", - "EXTENDS_LIST_WRAP", - "ALIGN_MULTILINE_EXTENDS_LIST", - "EXTENDS_KEYWORD_WRAP", - "THROWS_LIST_WRAP", - "ALIGN_MULTILINE_THROWS_LIST", - "ALIGN_THROWS_KEYWORD", - "THROWS_KEYWORD_WRAP", - "METHOD_PARAMETERS_WRAP", - "ALIGN_MULTILINE_PARAMETERS", - "METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE", - "METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE", "CALL_PARAMETERS_WRAP", - "ALIGN_MULTILINE_PARAMETERS_IN_CALLS", "PREFER_PARAMETERS_WRAP", "CALL_PARAMETERS_LPAREN_ON_NEXT_LINE", "CALL_PARAMETERS_RPAREN_ON_NEXT_LINE", - "ALIGN_MULTILINE_METHOD_BRACKETS", - "METHOD_CALL_CHAIN_WRAP", - "ALIGN_MULTILINE_CHAINED_METHODS", - "ALIGN_GROUP_FIELD_DECLARATIONS", - "IF_BRACE_FORCE", - "ELSE_ON_NEW_LINE", - "SPECIAL_ELSE_IF_TREATMENT", - "FOR_STATEMENT_WRAP", - "ALIGN_MULTILINE_FOR", - "FOR_STATEMENT_LPAREN_ON_NEXT_LINE", - "FOR_STATEMENT_RPAREN_ON_NEXT_LINE", - "FOR_BRACE_FORCE", - "WHILE_BRACE_FORCE", - "DOWHILE_BRACE_FORCE", - "WHILE_ON_NEW_LINE", - "INDENT_CASE_FROM_SWITCH", + "METHOD_PARAMETERS_WRAP", + "METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE", + "METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE", "RESOURCE_LIST_WRAP", - "ALIGN_MULTILINE_RESOURCES", "RESOURCE_LIST_LPAREN_ON_NEXT_LINE", "RESOURCE_LIST_RPAREN_ON_NEXT_LINE", - "CATCH_ON_NEW_LINE", - "FINALLY_ON_NEW_LINE", - "BINARY_OPERATION_WRAP", - "ALIGN_MULTILINE_BINARY_OPERATION", - "BINARY_OPERATION_SIGN_ON_NEXT_LINE", - "ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION", + "EXTENDS_LIST_WRAP", + "THROWS_LIST_WRAP", + "EXTENDS_KEYWORD_WRAP", + "THROWS_KEYWORD_WRAP", + "METHOD_CALL_CHAIN_WRAP", "PARENTHESES_EXPRESSION_LPAREN_WRAP", "PARENTHESES_EXPRESSION_RPAREN_WRAP", - "ASSIGNMENT_WRAP", - "ALIGN_MULTILINE_ASSIGNMENT", - "PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE", + "BINARY_OPERATION_WRAP", + "BINARY_OPERATION_SIGN_ON_NEXT_LINE", "TERNARY_OPERATION_WRAP", - "ALIGN_MULTILINE_TERNARY_OPERATION", "TERNARY_OPERATION_SIGNS_ON_NEXT_LINE", + "MODIFIER_LIST_WRAP", + "KEEP_SIMPLE_BLOCKS_IN_ONE_LINE", + "KEEP_SIMPLE_METHODS_IN_ONE_LINE", + "KEEP_SIMPLE_CLASSES_IN_ONE_LINE", + "KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE", + "FOR_STATEMENT_WRAP", + "FOR_STATEMENT_LPAREN_ON_NEXT_LINE", + "FOR_STATEMENT_RPAREN_ON_NEXT_LINE", "ARRAY_INITIALIZER_WRAP", - "ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION", "ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE", "ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE", - "MODIFIER_LIST_WRAP", + "ASSIGNMENT_WRAP", + "PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE", + "LABELED_STATEMENT_WRAP", "ASSERT_STATEMENT_WRAP", "ASSERT_STATEMENT_COLON_ON_NEXT_LINE", - "CLASS_ANNOTATION_WRAP", + "IF_BRACE_FORCE", + "DOWHILE_BRACE_FORCE", + "WHILE_BRACE_FORCE", + "FOR_BRACE_FORCE", + "WRAP_LONG_LINES", "METHOD_ANNOTATION_WRAP", + "CLASS_ANNOTATION_WRAP", "FIELD_ANNOTATION_WRAP", "PARAMETER_ANNOTATION_WRAP", "VARIABLE_ANNOTATION_WRAP", + "ALIGN_MULTILINE_CHAINED_METHODS", + "ALIGN_MULTILINE_PARAMETERS", + "ALIGN_MULTILINE_PARAMETERS_IN_CALLS", + "ALIGN_MULTILINE_RESOURCES", + "ALIGN_MULTILINE_FOR", + "INDENT_WHEN_CASES", + "ALIGN_MULTILINE_BINARY_OPERATION", + "ALIGN_MULTILINE_ASSIGNMENT", + "ALIGN_MULTILINE_TERNARY_OPERATION", + "ALIGN_MULTILINE_THROWS_LIST", + "ALIGN_THROWS_KEYWORD", + "ALIGN_MULTILINE_EXTENDS_LIST", + "ALIGN_MULTILINE_METHOD_BRACKETS", + "ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION", + "ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION", + "ALIGN_GROUP_FIELD_DECLARATIONS", + "BRACE_STYLE", + "CLASS_BRACE_STYLE", + "METHOD_BRACE_STYLE", + "USE_FLYING_GEESE_BRACES", + "FLYING_GEESE_BRACES_GAP", + "DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS", + "ELSE_ON_NEW_LINE", + "WHILE_ON_NEW_LINE", + "CATCH_ON_NEW_LINE", + "FINALLY_ON_NEW_LINE", + "INDENT_CASE_FROM_SWITCH", + "SPECIAL_ELSE_IF_TREATMENT", "ENUM_CONSTANTS_WRAP"); String groupName = ApplicationBundle.message("wrapping.fields.annotation"); consumer.showCustomOption(JavaCodeStyleSettings.class, "DO_NOT_WRAP_AFTER_SINGLE_ANNOTATION", "Do not wrap after single annotation", groupName); diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java index 20c536bb5a1d..f1a04e453f48 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java @@ -86,7 +86,7 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor { private boolean myMadeStatic = false; private final Set myUsages = new LinkedHashSet(); private PsiClass myInnerClass; - private ChangeSignatureProcessor myChangeSignatureProcessor; + private boolean myChangeReturnType; private Runnable myCopyMethodToInner; public ExtractMethodObjectProcessor(Project project, Editor editor, PsiElement[] elements, final String innerClassName) { @@ -266,12 +266,6 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor { myInnerClass.add(GenerateMembersUtil.generateGetterPrototype(field)); } - PsiParameter[] params = getMethod().getParameterList().getParameters(); - ParameterInfoImpl[] infos = new ParameterInfoImpl[params.length]; - for (int i = 0; i < params.length; i++) { - PsiParameter param = params[i]; - infos[i] = new ParameterInfoImpl(i, param.getName(), param.getType()); - } final PsiCodeBlock body = getMethod().getBody(); LOG.assertTrue(body != null); final LinkedHashSet vars = new LinkedHashSet(); @@ -393,17 +387,25 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor { } } - myChangeSignatureProcessor = new ChangeSignatureProcessor(myProject, getMethod(), false, null, getMethod().getName(), - new PsiImmediateClassType(myInnerClass, PsiSubstitutor.EMPTY), infos); + myChangeReturnType = true; } void runChangeSignature() { - if (myChangeSignatureProcessor != null) { - myChangeSignatureProcessor.run(); - } if (myCopyMethodToInner != null) { ApplicationManager.getApplication().runWriteAction(myCopyMethodToInner); } + if (myChangeReturnType) { + final Runnable runnable = new Runnable() { + public void run() { + final PsiTypeElement typeElement = ((PsiLocalVariable)((PsiDeclarationStatement)JavaPsiFacade.getElementFactory(myProject) + .createStatementFromText(myInnerClassName + " l =null;", myInnerClass)).getDeclaredElements()[0]).getTypeElement(); + final PsiTypeElement innerMethodReturnTypeElement = myInnerMethod.getReturnTypeElement(); + LOG.assertTrue(innerMethodReturnTypeElement != null); + innerMethodReturnTypeElement.replace(typeElement); + } + }; + ApplicationManager.getApplication().runWriteAction(runnable); + } } private String getPureName(PsiVariable var) { @@ -524,7 +526,7 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor { LOG.assertTrue(methodBody != null); replacedMethodBody.replace(methodBody); PsiUtil.setModifierProperty(newMethod, PsiModifier.STATIC, myInnerClass.hasModifierProperty(PsiModifier.STATIC) && notHasGeneratedFields()); - myInnerMethod = (PsiMethod)JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(myInnerClass.add(newMethod)); + myInnerMethod = (PsiMethod)myInnerClass.add(newMethod); } private boolean notHasGeneratedFields() { diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java index 44d71c5e72a7..ec3599fec62e 100644 --- a/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java +++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java @@ -167,7 +167,12 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory search(@NotNull final PsiClass aClass, final boolean checkDeep) { - return search(aClass, aClass.getUseScope(), checkDeep); + return search(aClass, ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public SearchScope compute() { + return aClass.getUseScope(); + } + }), checkDeep); } public static Query search(@NotNull PsiClass aClass) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA114797.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA114797.java new file mode 100644 index 000000000000..9e4ee06ade1e --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA114797.java @@ -0,0 +1,15 @@ +import java.util.ArrayList; +import java.util.List; + +interface A{}; +interface B extends A{}; + +class GenericTest { + public static List convert(List list){ + return new ArrayList(); + } + + public static void test(){ + List as = convert(new ArrayList()); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IDEA102800.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IDEA102800.java new file mode 100644 index 000000000000..7c2cc7bdae5e --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IDEA102800.java @@ -0,0 +1,31 @@ +import java.util.function.IntFunction; +import java.util.function.IntUnaryOperator; +import java.util.function.Supplier; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +class Test { + + interface IntStream1 { + Stream map(IntFunction mapper); + IntStream1 map(IntUnaryOperator mapper); + + Stream boxed(); + } + + void fooBar(IntStream1 instr){ + Supplier> si = () -> instr.map ((i) -> (( i % 2) == 0) ? i : -i).boxed(); + System.out.println(si); + Supplier> si1 = () -> instr.map (null).boxed(); + System.out.println(si1); + } +} + +class TestInitial { + void fooBar(){ + Supplier> si = () -> IntStream.range(0, 20).map((i) -> ((i % 2) == 0) ? i : -i).boxed(); + System.out.println(si); + } +} + + diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/InvokeReturnType.java b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/InvokeReturnType.java new file mode 100644 index 000000000000..353941357c68 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/InvokeReturnType.java @@ -0,0 +1,9 @@ +package my; + +class Sample { + static void foo() { + int x =5; + int y =5; + int z =5; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java index 0a93d8f7f193..ac57a71e9c9f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -373,6 +373,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA124363() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testIDEA78402() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testIDEA106985() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } + public void testIDEA114797() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testCaptureWildcardFromUnboundCaptureWildcard() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testSuperCaptureSubstitutionWhenTypeParameterHasUpperBounds() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testParameterBoundsWithCapturedWildcard() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java index 3ccc97d69c17..0e5c5a2f3d78 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java @@ -43,6 +43,10 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testIDEA102800() throws Exception { + doTest(); + } + private void doTest() { doTest(true); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy index d866ddd783cf..6abd2e809cdd 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy @@ -14,16 +14,14 @@ * limitations under the License. */ package com.intellij.codeInsight.template + import com.intellij.JavaTestUtil import com.intellij.codeInsight.CodeInsightSettings import com.intellij.codeInsight.lookup.LookupManager import com.intellij.codeInsight.lookup.impl.LookupImpl import com.intellij.codeInsight.lookup.impl.LookupManagerImpl import com.intellij.codeInsight.template.impl.* -import com.intellij.codeInsight.template.macro.ClassNameCompleteMacro -import com.intellij.codeInsight.template.macro.CompleteMacro -import com.intellij.codeInsight.template.macro.MethodReturnTypeMacro -import com.intellij.codeInsight.template.macro.SnakeCaseMacro +import com.intellij.codeInsight.template.macro.* import com.intellij.openapi.Disposable import com.intellij.openapi.command.WriteCommandAction import com.intellij.openapi.editor.Editor @@ -39,6 +37,7 @@ import com.intellij.util.ui.UIUtil import org.jetbrains.annotations.NotNull import static com.intellij.codeInsight.template.Template.Property.USE_STATIC_IMPORT_IF_POSSIBLE + /** * @author spleaner */ @@ -462,7 +461,8 @@ class Foo { @Override protected void invokeTestRunnable(@NotNull final Runnable runnable) throws Exception { - if (name in ["testNavigationActionsDontTerminateTemplate", "testTemplateWithEnd", "testDisappearingVar", "test escape string characters in soutv"]) { + if (name in ["testNavigationActionsDontTerminateTemplate", "testTemplateWithEnd", "testDisappearingVar", + "test escape string characters in soutv", "test do not replace macro value with empty result"]) { runnable.run(); return; } @@ -821,6 +821,40 @@ class Foo { abs(PI); } } +""" + } + + public void "test do not replace macro value with empty result"() { + myFixture.configureByText "a.java", """\ +class Foo { + { + + } +} +""" + final TemplateManager manager = TemplateManager.getInstance(getProject()); + final Template template = manager.createTemplate("xxx", "user", '$VAR1$ $VAR2$ $VAR1$'); + template.addVariable("VAR1", "", "", true) + template.addVariable("VAR2", new MacroCallNode(new FileNameMacro()), new ConstantNode("default"), true) + ((TemplateImpl)template).templateContext.setEnabled(contextType(JavaCodeContextType.class), true) + addTemplate(template, testRootDisposable) + + startTemplate(template); + myFixture.checkResult """\ +class Foo { + { + a.java + } +} +""" + myFixture.type 'test' + + myFixture.checkResult """\ +class Foo { + { + test a.java test + } +} """ } } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java index bc6c1befaa12..c1e346a104b3 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java @@ -21,6 +21,7 @@ package com.intellij.refactoring; import com.intellij.JavaTestUtil; +import com.intellij.idea.Bombed; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.psi.*; @@ -28,6 +29,8 @@ import com.intellij.refactoring.extractMethodObject.ExtractLightMethodObjectHand import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; +import java.util.Calendar; + public class ExtractMethodObject4DebuggerTest extends LightRefactoringTestCase { @NotNull @Override @@ -51,8 +54,8 @@ public class ExtractMethodObject4DebuggerTest extends LightRefactoringTestCase { public void testSimpleGeneration() throws Exception { doTest("int i = 0; int j = 0;", "Test test = new Test().invoke();\n" + - " int i = test.getI();\n" + - " int j = test.getJ();", + " int i = test.getI();\n" + + " int j = test.getJ();", "public class Test {\n" + " private int i;\n" + @@ -74,6 +77,31 @@ public class ExtractMethodObject4DebuggerTest extends LightRefactoringTestCase { " }"); } + public void testInvokeReturnType() throws Exception { + doTest("x = 6; y = 6;", "Test test = new Test().invoke();\n" + + " x = test.getX();\n" + + " y = test.getY();", + + "public static class Test {\n" + + " private int x;\n" + + " private int y;\n" + + "\n" + + " public int getX() {\n" + + " return x;\n" + + " }\n" + + "\n" + + " public int getY() {\n" + + " return y;\n" + + " }\n" + + "\n" + + " public Test invoke() {\n" + + " x = 6;\n" + + " y = 6;\n" + + " return this;\n" + + " }\n" + + " }"); + } + @Override protected Sdk getProjectJDK() { return IdeaTestUtil.getMockJdk18(); diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/UpdateHighlightersUtil.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/UpdateHighlightersUtil.java index bd63e19c8657..0f45257b8cb3 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/UpdateHighlightersUtil.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/UpdateHighlightersUtil.java @@ -33,6 +33,8 @@ import com.intellij.openapi.editor.impl.RedBlackTree; import com.intellij.openapi.editor.markup.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; +import com.intellij.openapi.vfs.NonPhysicalFileSystem; +import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.util.Consumer; @@ -49,7 +51,7 @@ import java.util.List; public class UpdateHighlightersUtil { private static final Comparator BY_START_OFFSET_NODUPS = new Comparator() { @Override - public int compare(HighlightInfo o1, HighlightInfo o2) { + public int compare(@NotNull HighlightInfo o1, @NotNull HighlightInfo o2) { int d = o1.getActualStartOffset() - o2.getActualStartOffset(); if (d != 0) return d; d = o1.getActualEndOffset() - o2.getActualEndOffset(); @@ -212,7 +214,8 @@ public class UpdateHighlightersUtil { if (!atStart) return true; if (!info.isFromInjection() && info.getEndOffset() < document.getTextLength() && (info.getEndOffset() <= startOffset || info.getStartOffset()>=endOffset)) return true; // injections are oblivious to restricting range - if (info.isFileLevelAnnotation() && psiFile.getViewProvider().isPhysical()) { + FileViewProvider provider = psiFile.getViewProvider(); + if (info.isFileLevelAnnotation() && (provider.isPhysical() || provider.getVirtualFile().getFileSystem() instanceof NonPhysicalFileSystem)) { codeAnalyzer.addFileLevelHighlight(project, group, info, psiFile); changed[0] = true; return true; diff --git a/platform/indexing-api/src/com/intellij/psi/search/searches/DefinitionsScopedSearch.java b/platform/indexing-api/src/com/intellij/psi/search/searches/DefinitionsScopedSearch.java index 4e94617e7681..001712e0f529 100644 --- a/platform/indexing-api/src/com/intellij/psi/search/searches/DefinitionsScopedSearch.java +++ b/platform/indexing-api/src/com/intellij/psi/search/searches/DefinitionsScopedSearch.java @@ -63,8 +63,13 @@ public class DefinitionsScopedSearch extends ExtensibleQueryFactory() { + @Override + public SearchScope compute() { + return element.getUseScope(); + } + }), true); } public SearchParameters(@NotNull PsiElement element, @NotNull SearchScope scope, final boolean checkDeep) { diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java index 299d17215fdf..fa284c8fd33c 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -21,7 +21,7 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.util.*; import com.intellij.psi.codeStyle.arrangement.ArrangementSettings; import com.intellij.psi.codeStyle.arrangement.ArrangementUtil; -import com.intellij.util.containers.HashSet; +import com.intellij.util.ReflectionUtil; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; import com.intellij.util.xmlb.XmlSerializer; import org.intellij.lang.annotations.MagicConstant; @@ -31,8 +31,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Arrays; import java.util.Set; /** @@ -155,63 +153,20 @@ public class CommonCodeStyleSettings { protected static void copyPublicFields(Object from, Object to) { assert from != to; - copyFields(to.getClass().getFields(), from, to); + ReflectionUtil.copyFields(to.getClass().getFields(), from, to); } void copyNonDefaultValuesFrom(CommonCodeStyleSettings from) { CommonCodeStyleSettings defaultSettings = new CommonCodeStyleSettings(null); PARENT_SETTINGS_INSTALLED = - copyFields(getClass().getFields(), from, this, new SupportedFieldsDiffFilter(from, getSupportedFields(), defaultSettings) { - @Override - public boolean isAccept(@NotNull Field field) { - if ("RIGHT_MARGIN".equals(field.getName())) return false; // Never copy RIGHT_MARGIN, it is inherited automatically if -1 - return super.isAccept(field); - } - }); - } - - private static void copyFields(Field[] fields, Object from, Object to) { - copyFields(fields, from, to, null); - } - - private static boolean copyFields(Field[] fields, Object from, Object to, @Nullable DifferenceFilter diffFilter) { - Set sourceFields = new HashSet(Arrays.asList(from.getClass().getFields())); - boolean valuesChanged = false; - for (Field field : fields) { - if (sourceFields.contains(field)) { - if (isPublic(field) && !isFinal(field)) { - try { - if (diffFilter == null || diffFilter.isAccept(field)) { - copyFieldValue(from, to, field); - valuesChanged = true; - } + ReflectionUtil + .copyFields(getClass().getFields(), from, this, new SupportedFieldsDiffFilter(from, getSupportedFields(), defaultSettings) { + @Override + public boolean isAccept(@NotNull Field field) { + if ("RIGHT_MARGIN".equals(field.getName())) return false; // Never copy RIGHT_MARGIN, it is inherited automatically if -1 + return super.isAccept(field); } - catch (Exception e) { - throw new RuntimeException(e); - } - } - } - } - return valuesChanged; - } - - private static void copyFieldValue(final Object from, Object to, final Field field) - throws IllegalAccessException { - Class fieldType = field.getType(); - if (fieldType.isPrimitive() || fieldType.equals(String.class)) { - field.set(to, field.get(from)); - } - else { - throw new RuntimeException("Field not copied " + field.getName()); - } - } - - private static boolean isPublic(final Field field) { - return (field.getModifiers() & Modifier.PUBLIC) != 0; - } - - private static boolean isFinal(final Field field) { - return (field.getModifiers() & Modifier.FINAL) != 0; + }); } @Nullable diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java index 4ac5e686c5bc..c4843a3e4eaa 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java @@ -54,10 +54,12 @@ import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; +import com.intellij.openapi.vfs.NonPhysicalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.newvfs.RefreshQueueImpl; import com.intellij.packageDependencies.DependencyValidationManager; +import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiCompiledElement; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; @@ -184,8 +186,10 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements JDOM @Override public void cleanFileLevelHighlights(@NotNull Project project, final int group, PsiFile psiFile) { - if (psiFile == null || !psiFile.getViewProvider().isPhysical()) return; - VirtualFile vFile = psiFile.getViewProvider().getVirtualFile(); + if (psiFile == null) return; + FileViewProvider provider = psiFile.getViewProvider(); + if (!provider.isPhysical() && !(provider.getVirtualFile().getFileSystem() instanceof NonPhysicalFileSystem)) return; + VirtualFile vFile = provider.getVirtualFile(); final FileEditorManager manager = FileEditorManager.getInstance(project); for (FileEditor fileEditor : manager.getEditors(vFile)) { final List infos = fileEditor.getUserData(FILE_LEVEL_HIGHLIGHTS); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java index 0c838cd05ec5..2e620c2379c9 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java @@ -723,7 +723,10 @@ public class TemplateState implements Disposable { ExpressionContext context = createExpressionContext(start); Result result = isQuick ? expressionNode.calculateQuickResult(context) : expressionNode.calculateResult(context); - if ((result == null || result.equalsToText("", element)) && defaultValue != null) { + if (isQuick && isEmptyResult(result, element) && !oldValue.isEmpty()) { + return; + } + if (isEmptyResult(result, element) && defaultValue != null) { result = defaultValue.calculateResult(context); } if (element != null) { @@ -743,6 +746,10 @@ public class TemplateState implements Disposable { } } + private static boolean isEmptyResult(Result result, PsiElement context) { + return result == null || result.equalsToText("", context); + } + private void replaceString(String newValue, int start, int end, int segmentNumber) { String oldText = myDocument.getCharsSequence().subSequence(start, end).toString(); diff --git a/platform/platform-api/src/com/intellij/ide/BrowserUtil.java b/platform/platform-api/src/com/intellij/ide/BrowserUtil.java index cd1d1b0dba49..85c0efd2b5cd 100644 --- a/platform/platform-api/src/com/intellij/ide/BrowserUtil.java +++ b/platform/platform-api/src/com/intellij/ide/BrowserUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ import java.net.URL; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -53,7 +54,7 @@ public class BrowserUtil { private BrowserUtil() { } public static boolean isAbsoluteURL(String url) { - return ourExternalPrefix.matcher(url.toLowerCase()).find(); + return ourExternalPrefix.matcher(url.toLowerCase(Locale.ENGLISH)).find(); } public static String getDocURL(String url) { diff --git a/platform/platform-api/src/com/intellij/notification/Notification.java b/platform/platform-api/src/com/intellij/notification/Notification.java index 674e20282334..7b3ecd67ca47 100644 --- a/platform/platform-api/src/com/intellij/notification/Notification.java +++ b/platform/platform-api/src/com/intellij/notification/Notification.java @@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.JBPopupAdapter; import com.intellij.openapi.ui.popup.LightweightWindowEvent; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.reference.SoftReference; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -62,7 +63,7 @@ public class Notification { myType = type; myListener = listener; - LOG.assertTrue(myContent.trim().length() > 0, "Notification should have content, groupId: " + myGroupId); + LOG.assertTrue(!StringUtil.isEmptyOrSpaces(myContent), "Notification should have content, groupId: " + myGroupId); } @SuppressWarnings("MethodMayBeStatic") diff --git a/platform/platform-impl/src/com/intellij/designer/DesignerEditorPanelFacade.java b/platform/platform-impl/src/com/intellij/designer/DesignerEditorPanelFacade.java new file mode 100644 index 000000000000..fa9ecf8610ac --- /dev/null +++ b/platform/platform-impl/src/com/intellij/designer/DesignerEditorPanelFacade.java @@ -0,0 +1,29 @@ +/* + * Copyright 2000-2014 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.designer; + +import com.intellij.openapi.ui.ThreeComponentsSplitter; + +/** + * @author Alexander Lobas + */ +public interface DesignerEditorPanelFacade { + Object getClientProperty(Object key); + + void putClientProperty(Object key, Object value); + + ThreeComponentsSplitter getContentSplitter(); +} \ No newline at end of file diff --git a/plugins/ui-designer-core/src/com/intellij/designer/LightToolWindow.java b/platform/platform-impl/src/com/intellij/designer/LightToolWindow.java similarity index 98% rename from plugins/ui-designer-core/src/com/intellij/designer/LightToolWindow.java rename to platform/platform-impl/src/com/intellij/designer/LightToolWindow.java index 4bbccfa84934..0d644217ef90 100644 --- a/plugins/ui-designer-core/src/com/intellij/designer/LightToolWindow.java +++ b/platform/platform-impl/src/com/intellij/designer/LightToolWindow.java @@ -54,7 +54,7 @@ public class LightToolWindow extends JPanel { private final ThreeComponentsSplitter myContentSplitter; private ToolWindowAnchor myAnchor; private final Project myProject; - private final AbstractToolWindowManager myManager; + private final LightToolWindowManager myManager; private final PropertiesComponent myPropertiesComponent; private boolean myShowContent; private final String myShowStateKey; @@ -86,7 +86,7 @@ public class LightToolWindow extends JPanel { JComponent focusedComponent, ThreeComponentsSplitter contentSplitter, ToolWindowAnchor anchor, - AbstractToolWindowManager manager, + LightToolWindowManager manager, Project project, PropertiesComponent propertiesComponent, String key, @@ -101,8 +101,8 @@ public class LightToolWindow extends JPanel { myManager = manager; myPropertiesComponent = propertiesComponent; - myShowStateKey = AbstractToolWindowManager.EDITOR_MODE + key + ".SHOW"; - myWidthKey = AbstractToolWindowManager.EDITOR_MODE + key + ".WIDTH"; + myShowStateKey = LightToolWindowManager.EDITOR_MODE + key + ".SHOW"; + myWidthKey = LightToolWindowManager.EDITOR_MODE + key + ".WIDTH"; HeaderPanel header = new HeaderPanel(); header.setLayout(new BorderLayout()); diff --git a/plugins/ui-designer-core/src/com/intellij/designer/LightToolWindowContent.java b/platform/platform-impl/src/com/intellij/designer/LightToolWindowContent.java similarity index 100% rename from plugins/ui-designer-core/src/com/intellij/designer/LightToolWindowContent.java rename to platform/platform-impl/src/com/intellij/designer/LightToolWindowContent.java diff --git a/platform/platform-impl/src/com/intellij/designer/LightToolWindowManager.java b/platform/platform-impl/src/com/intellij/designer/LightToolWindowManager.java new file mode 100644 index 000000000000..e6d887ea2c43 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/designer/LightToolWindowManager.java @@ -0,0 +1,323 @@ +/* + * Copyright 2000-2014 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.designer; + +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileEditorManagerEvent; +import com.intellij.openapi.fileEditor.FileEditorManagerListener; +import com.intellij.openapi.project.DumbAwareRunnable; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ex.ToolWindowEx; +import com.intellij.util.ParameterizedRunnable; +import com.intellij.util.messages.MessageBusConnection; +import com.intellij.util.ui.update.MergingUpdateQueue; +import com.intellij.util.ui.update.Update; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** + * @author Alexander Lobas + */ +public abstract class LightToolWindowManager implements ProjectComponent { + public static final String EDITOR_MODE = "UI_DESIGNER_EDITOR_MODE."; + + private final MergingUpdateQueue myWindowQueue = new MergingUpdateQueue(getComponentName(), 200, true, null); + protected final Project myProject; + protected final FileEditorManager myFileEditorManager; + protected volatile ToolWindow myToolWindow; + private volatile boolean myToolWindowDisposed; + + private final PropertiesComponent myPropertiesComponent; + public final String myEditorModeKey; + private ToggleEditorModeAction myLeftEditorModeAction; + private ToggleEditorModeAction myRightEditorModeAction; + + private MessageBusConnection myConnection; + private final FileEditorManagerListener myListener = new FileEditorManagerListener() { + @Override + public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) { + bindToDesigner(getActiveDesigner()); + } + + @Override + public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + bindToDesigner(getActiveDesigner()); + } + }); + } + + @Override + public void selectionChanged(@NotNull FileEditorManagerEvent event) { + bindToDesigner(getDesigner(event.getNewEditor())); + } + }; + + ////////////////////////////////////////////////////////////////////////////////////////// + // + // ToolWindow + // + ////////////////////////////////////////////////////////////////////////////////////////// + + protected LightToolWindowManager(Project project, FileEditorManager fileEditorManager) { + myProject = project; + myFileEditorManager = fileEditorManager; + myPropertiesComponent = PropertiesComponent.getInstance(myProject); + myEditorModeKey = EDITOR_MODE + getComponentName() + ".STATE"; + } + + @Override + public void projectOpened() { + initToolWindow(); + + StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() { + public void run() { + if (getEditorMode() == null) { + initListeners(); + bindToDesigner(getActiveDesigner()); + } + } + }); + } + + @Override + public void projectClosed() { + if (!myToolWindowDisposed) { + disposeComponent(); + myToolWindowDisposed = true; + myToolWindow = null; + } + } + + private void initListeners() { + myConnection = myProject.getMessageBus().connect(myProject); + myConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, myListener); + } + + private void removeListeners() { + myConnection.disconnect(); + myConnection = null; + } + + @Nullable + protected abstract DesignerEditorPanelFacade getDesigner(FileEditor editor); + + @Nullable + public DesignerEditorPanelFacade getActiveDesigner() { + for (FileEditor editor : myFileEditorManager.getSelectedEditors()) { + DesignerEditorPanelFacade designer = getDesigner(editor); + if (designer != null) { + return designer; + } + } + + return null; + } + + private void bindToDesigner(final DesignerEditorPanelFacade designer) { + myWindowQueue.cancelAllUpdates(); + myWindowQueue.queue(new Update("update") { + @Override + public void run() { + if (myToolWindowDisposed) { + return; + } + if (myToolWindow == null) { + if (designer == null) { + return; + } + initToolWindow(); + } + updateToolWindow(designer); + } + }); + } + + protected abstract void initToolWindow(); + + protected abstract void updateToolWindow(@Nullable DesignerEditorPanelFacade designer); + + protected final void initGearActions() { + ToolWindowEx toolWindow = (ToolWindowEx)myToolWindow; + toolWindow.setAdditionalGearActions(new DefaultActionGroup(createGearActions())); + } + + protected abstract ToolWindowAnchor getAnchor(); + + @Override + public void initComponent() { + } + + @Override + public void disposeComponent() { + } + + ////////////////////////////////////////////////////////////////////////////////////////// + // + // LightToolWindow + // + ////////////////////////////////////////////////////////////////////////////////////////// + + public final ActionGroup createGearActions() { + DefaultActionGroup group = new DefaultActionGroup("In Editor Mode", true); + + if (myLeftEditorModeAction == null) { + myLeftEditorModeAction = createToggleAction(ToolWindowAnchor.LEFT); + } + group.add(myLeftEditorModeAction); + + if (myRightEditorModeAction == null) { + myRightEditorModeAction = createToggleAction(ToolWindowAnchor.RIGHT); + } + group.add(myRightEditorModeAction); + + return group; + } + + protected abstract ToggleEditorModeAction createToggleAction(ToolWindowAnchor anchor); + + public final void bind(DesignerEditorPanelFacade designer) { + if (isEditorMode()) { + myCreateAction.run(designer); + } + } + + public final void dispose(DesignerEditorPanelFacade designer) { + if (isEditorMode()) { + disposeContent(designer); + } + } + + protected final Object getContent(DesignerEditorPanelFacade designer) { + LightToolWindow toolWindow = (LightToolWindow)designer.getClientProperty(getComponentName()); + return toolWindow.getContent(); + } + + protected abstract LightToolWindow createContent(DesignerEditorPanelFacade designer); + + protected final LightToolWindow createContent(DesignerEditorPanelFacade designer, + LightToolWindowContent content, + String title, + Icon icon, + JComponent component, + JComponent focusedComponent, + int defaultWidth, + AnAction[] actions) { + return new LightToolWindow(content, + title, + icon, + component, + focusedComponent, + designer.getContentSplitter(), + getEditorMode(), + this, + myProject, + myPropertiesComponent, + getComponentName(), + defaultWidth, + actions); + } + + protected final void disposeContent(DesignerEditorPanelFacade designer) { + String key = getComponentName(); + LightToolWindow toolWindow = (LightToolWindow)designer.getClientProperty(key); + designer.putClientProperty(key, null); + toolWindow.dispose(); + } + + private final ParameterizedRunnable myCreateAction = new ParameterizedRunnable() { + @Override + public void run(DesignerEditorPanelFacade designer) { + designer.putClientProperty(getComponentName(), createContent(designer)); + } + }; + + private final ParameterizedRunnable myUpdateAnchorAction = + new ParameterizedRunnable() { + @Override + public void run(DesignerEditorPanelFacade designer) { + LightToolWindow toolWindow = (LightToolWindow)designer.getClientProperty(getComponentName()); + toolWindow.updateAnchor(getEditorMode()); + } + }; + + private final ParameterizedRunnable myDisposeAction = new ParameterizedRunnable() { + @Override + public void run(DesignerEditorPanelFacade designer) { + disposeContent(designer); + } + }; + + private void runUpdateContent(ParameterizedRunnable action) { + for (FileEditor editor : myFileEditorManager.getAllEditors()) { + DesignerEditorPanelFacade designer = getDesigner(editor); + if (designer != null) { + action.run(designer); + } + } + } + + protected final boolean isEditorMode() { + return getEditorMode() != null; + } + + @Nullable + final ToolWindowAnchor getEditorMode() { + String value = myPropertiesComponent.getValue(myEditorModeKey); + if (value == null) { + return getAnchor(); + } + return value.equals("ToolWindow") ? null : ToolWindowAnchor.fromText(value); + } + + final void setEditorMode(@Nullable ToolWindowAnchor newState) { + ToolWindowAnchor oldState = getEditorMode(); + myPropertiesComponent.setValue(myEditorModeKey, newState == null ? "ToolWindow" : newState.toString()); + + if (oldState != null && newState != null) { + runUpdateContent(myUpdateAnchorAction); + } + else if (newState != null) { + removeListeners(); + updateToolWindow(null); + runUpdateContent(myCreateAction); + } + else { + runUpdateContent(myDisposeAction); + initListeners(); + bindToDesigner(getActiveDesigner()); + } + } + + final ToolWindow getToolWindow() { + return myToolWindow; + } +} \ No newline at end of file diff --git a/plugins/ui-designer-core/src/com/intellij/designer/ToggleEditorModeAction.java b/platform/platform-impl/src/com/intellij/designer/ToggleEditorModeAction.java similarity index 69% rename from plugins/ui-designer-core/src/com/intellij/designer/ToggleEditorModeAction.java rename to platform/platform-impl/src/com/intellij/designer/ToggleEditorModeAction.java index 238de681c4b2..668a0405f4b2 100644 --- a/plugins/ui-designer-core/src/com/intellij/designer/ToggleEditorModeAction.java +++ b/platform/platform-impl/src/com/intellij/designer/ToggleEditorModeAction.java @@ -15,7 +15,6 @@ */ package com.intellij.designer; -import com.intellij.designer.palette.PaletteToolWindowManager; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.ToggleAction; import com.intellij.openapi.project.Project; @@ -25,12 +24,12 @@ import com.intellij.openapi.wm.ToolWindowAnchor; /** * @author Alexander Lobas */ -public class ToggleEditorModeAction extends ToggleAction { - private final AbstractToolWindowManager myManager; - private final Project myProject; +public abstract class ToggleEditorModeAction extends ToggleAction { + protected final LightToolWindowManager myManager; + protected final Project myProject; private final ToolWindowAnchor myAnchor; - public ToggleEditorModeAction(AbstractToolWindowManager manager, Project project, ToolWindowAnchor anchor) { + public ToggleEditorModeAction(LightToolWindowManager manager, Project project, ToolWindowAnchor anchor) { super(StringUtil.capitalize(anchor.toString()), "Pin/unpin tool window to " + anchor + " side UI Designer Editor", null); myManager = manager; myProject = project; @@ -47,7 +46,7 @@ public class ToggleEditorModeAction extends ToggleAction { if (state) { myManager.setEditorMode(myAnchor); - AbstractToolWindowManager manager = getOppositeManager(); + LightToolWindowManager manager = getOppositeManager(); if (manager.getEditorMode() == myAnchor) { manager.setEditorMode(myAnchor == ToolWindowAnchor.LEFT ? ToolWindowAnchor.RIGHT : ToolWindowAnchor.LEFT); } @@ -57,9 +56,5 @@ public class ToggleEditorModeAction extends ToggleAction { } } - private AbstractToolWindowManager getOppositeManager() { - AbstractToolWindowManager designerManager = DesignerToolWindowManager.getInstance(myProject); - AbstractToolWindowManager paletteManager = PaletteToolWindowManager.getInstance(myProject); - return myManager == designerManager ? paletteManager : designerManager; - } + protected abstract LightToolWindowManager getOppositeManager(); } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java index 27124d464d96..32e823bd9758 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java @@ -70,6 +70,7 @@ import java.awt.*; import java.awt.event.*; import java.util.*; import java.util.List; +import java.util.concurrent.Future; public final class ActionManagerImpl extends ActionManagerEx implements ApplicationComponent { @NonNls public static final String ACTION_ELEMENT_NAME = "action"; @@ -1264,7 +1265,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat } } - public void preloadActions() { + public Future preloadActions() { if (myPreloadActionsRunnable == null) { myPreloadActionsRunnable = new Runnable() { @Override @@ -1275,8 +1276,9 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat } } }; - ApplicationManager.getApplication().executeOnPooledThread(myPreloadActionsRunnable); + return ApplicationManager.getApplication().executeOnPooledThread(myPreloadActionsRunnable); } + return null; } private void doPreloadActions() { diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMap.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMap.java index a69b3af26f69..057d96fd01eb 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMap.java +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMap.java @@ -16,16 +16,23 @@ public class SourceMap { private final String outFile; private final SourceResolver sourceResolver; + private final boolean hasNameMappings; // sources - is not originally specified, but canonicalized/normalized public SourceMap(@Nullable String outFile, @NotNull MappingList mappings, @NotNull MappingList[] sourceIndexToMappings, - @NotNull SourceResolver sourceResolver) { + @NotNull SourceResolver sourceResolver, + boolean hasNameMappings) { this.outFile = outFile; this.mappings = mappings; this.sourceIndexToMappings = sourceIndexToMappings; this.sourceResolver = sourceResolver; + this.hasNameMappings = hasNameMappings; + } + + public boolean hasNameMappings() { + return hasNameMappings; } @NotNull diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java index 27bd8abfe0ce..bfad136ce39a 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java @@ -5,6 +5,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtilRt; import com.intellij.util.PathUtil; import com.intellij.util.SmartList; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.CharSequenceSubSequence; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -176,7 +177,7 @@ public final class SourceMapDecoder { sourceToEntries[i] = new SourceMappingList(entries); } } - return new SourceMap(file, new GeneratedMappingList(mappings), sourceToEntries, sourceResolverFactory.create(sources, sourcesContent)); + return new SourceMap(file, new GeneratedMappingList(mappings), sourceToEntries, sourceResolverFactory.create(sources, sourcesContent), !ContainerUtil.isEmpty(names)); } @Nullable diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/BasicDebuggerViewSupport.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/BasicDebuggerViewSupport.java index a5cf778db7e2..b2fd544d0b86 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/BasicDebuggerViewSupport.java +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/BasicDebuggerViewSupport.java @@ -95,6 +95,17 @@ public class BasicDebuggerViewSupport implements DebuggerViewSupport, MemberFilt return Collections.emptyList(); } + @NotNull + @Override + public String getName(@NotNull Variable variable) { + return variable.getName(); + } + + @Override + public boolean hasNameMappings() { + return false; + } + @NotNull @Override public String normalizeMemberName(@NotNull Variable variable) { diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LazyVariablesGroup.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LazyVariablesGroup.java index 25b8b3e11ee5..c00f6727203d 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LazyVariablesGroup.java +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LazyVariablesGroup.java @@ -71,7 +71,7 @@ public final class LazyVariablesGroup extends XValueGroup { @Override public void consumeVariables(@NotNull List variables) { - node.addChildren(Variables.createVariablesList(variables, context), true); + node.addChildren(Variables.createVariablesList(variables, context, null), true); } }, componentType); } diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilter.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilter.java index fb3a7c1f175c..b9b60178e5ff 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilter.java +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilter.java @@ -9,4 +9,9 @@ public interface MemberFilter { @NotNull Collection getAdditionalVariables(); + + @NotNull + String getName(@NotNull Variable variable); + + boolean hasNameMappings(); } \ No newline at end of file diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.java index 6a65c7acf7e5..9ee54199ff8c 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.java +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.java @@ -57,7 +57,11 @@ public final class VariableView extends XNamedValue implements VariableContext { private volatile int remainingChildrenOffset; public VariableView(@NotNull Variable variable, @NotNull VariableContext context) { - super(context.getViewSupport().normalizeMemberName(variable)); + this(context.getViewSupport().normalizeMemberName(variable), variable, context); + } + + public VariableView(@NotNull String name, @NotNull Variable variable, @NotNull VariableContext context) { + super(name); this.context = context; this.variable = variable; @@ -362,7 +366,7 @@ public final class VariableView extends XNamedValue implements VariableContext { @Override public void consumeVariables(@NotNull List variables) { - node.addChildren(Variables.createVariablesList(variables, VariableView.this), isLastChildren); + node.addChildren(Variables.createVariablesList(variables, VariableView.this, null), isLastChildren); } }, null); } @@ -399,7 +403,7 @@ public final class VariableView extends XNamedValue implements VariableContext { int count = variables.size(); int bucketSize = XCompositeNode.MAX_CHILDREN_TO_SHOW; if (count <= bucketSize) { - node.addChildren(Variables.createVariablesList(variables, this), true); + node.addChildren(Variables.createVariablesList(variables, this, null), true); return; } @@ -417,7 +421,7 @@ public final class VariableView extends XNamedValue implements VariableContext { int notGroupedVariablesOffset; if ((variables.size() - count) > bucketSize) { for (notGroupedVariablesOffset = variables.size(); notGroupedVariablesOffset > 0; notGroupedVariablesOffset--) { - if (!variables.get(notGroupedVariablesOffset - 1).getName().startsWith(Variables.SPECIAL_PROPERTY_PREFIX)) { + if (!variables.get(notGroupedVariablesOffset - 1).getName().startsWith("__")) { break; } } diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/Variables.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/Variables.java index b71914443eef..e85091320bfb 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/Variables.java +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/Variables.java @@ -18,13 +18,11 @@ import java.util.*; import java.util.regex.Pattern; public final class Variables { - static final String SPECIAL_PROPERTY_PREFIX = "__"; - private static final Pattern UNNAMED_FUNCTION_PATTERN = Pattern.compile("^function[\\t ]*\\("); private static final Comparator NATURAL_NAME_COMPARATOR = new Comparator() { @Override - public int compare(Variable o1, Variable o2) { + public int compare(@NotNull Variable o1, @NotNull Variable o2) { return naturalCompare(o1.getName(), o2.getName()); } }; @@ -37,7 +35,7 @@ public final class Variables { AsyncResult result = ObsolescentAsyncResults.consume(scope.getVariables(), node, new PairConsumer, XCompositeNode>() { @Override public void consume(List variables, XCompositeNode node) { - MemberFilter memberFilter = context.createMemberFilter(); + final MemberFilter memberFilter = context.createMemberFilter(); Collection additionalVariables = memberFilter.getAdditionalVariables(); List properties = new ArrayList(variables.size() + additionalVariables.size()); List functions = new SmartList(); @@ -56,7 +54,12 @@ public final class Variables { } } - sort(properties); + ContainerUtil.sort(properties, memberFilter.hasNameMappings() ? new Comparator() { + @Override + public int compare(@NotNull Variable o1, @NotNull Variable o2) { + return naturalCompare(memberFilter.getName(o1), memberFilter.getName(o2)); + } + } : NATURAL_NAME_COMPARATOR); sort(functions); for (Variable variable : additionalVariables) { @@ -64,7 +67,7 @@ public final class Variables { } if (!properties.isEmpty()) { - node.addChildren(createVariablesList(properties, context), functions.isEmpty() && isLast); + node.addChildren(createVariablesList(properties, context, memberFilter), functions.isEmpty() && isLast); } if (!functions.isEmpty()) { @@ -110,6 +113,7 @@ public final class Variables { } } + @NotNull public static List filterAndSort(@NotNull List variables, @NotNull VariableContext context, boolean filterFunctions) { if (variables.isEmpty()) { return Collections.emptyList(); @@ -219,16 +223,28 @@ public final class Variables { return string1Length - string2Length; } + @NotNull public static XValueChildrenList createVariablesList(@NotNull List variables, @NotNull VariableContext variableContext) { - return createVariablesList(variables, 0, variables.size(), variableContext); + return createVariablesList(variables, variableContext, null); } + @NotNull + public static XValueChildrenList createVariablesList(@NotNull List variables, @NotNull VariableContext variableContext, @Nullable MemberFilter memberFilter) { + return createVariablesList(variables, 0, variables.size(), variableContext, memberFilter); + } + + @NotNull public static XValueChildrenList createVariablesList(@NotNull List variables, int from, int to, @NotNull VariableContext variableContext) { + return createVariablesList(variables, from, to, variableContext, null); + } + + @NotNull + public static XValueChildrenList createVariablesList(@NotNull List variables, int from, int to, @NotNull VariableContext variableContext, @Nullable MemberFilter memberFilter) { XValueChildrenList list = new XValueChildrenList(to - from); VariableContext getterOrSetterContext = null; for (int i = from; i < to; i++) { Variable variable = variables.get(i); - list.add(new VariableView(variable, variableContext)); + list.add(memberFilter == null ? new VariableView(variable, variableContext) : new VariableView(memberFilter.getName(variable), variable, variableContext)); if (variable instanceof ObjectProperty) { ObjectProperty property = (ObjectProperty)variable; if (property.getGetter() != null) { diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/frame/CallFrameView.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/frame/CallFrameView.java index 3cb993a01194..03d960362183 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/frame/CallFrameView.java +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/frame/CallFrameView.java @@ -36,6 +36,11 @@ public final class CallFrameView extends StackFrameImplBase implements VariableC inLibraryContent = sourceInfo != null && debugProcess.isInLibraryContent(sourceInfo, script); } + @Nullable + public Script getScript() { + return script; + } + @Override protected boolean isInFileScope() { List scopes = callFrame.getVariableScopes(); diff --git a/platform/testFramework/src/com/intellij/testFramework/FlyIdeaTestCase.java b/platform/testFramework/src/com/intellij/testFramework/FlyIdeaTestCase.java index 02a39f148e24..098d76599f5b 100644 --- a/platform/testFramework/src/com/intellij/testFramework/FlyIdeaTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/FlyIdeaTestCase.java @@ -1,36 +1,35 @@ +/* + * Copyright 2000-2014 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.testFramework; -import com.intellij.mock.MockApplicationEx; import com.intellij.openapi.Disposable; -import com.intellij.openapi.application.Application; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; import junit.framework.TestCase; -import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; -import java.util.concurrent.Future; public abstract class FlyIdeaTestCase extends TestCase { - - private Disposable myRootDisposable; + private final Disposable myRootDisposable = Disposer.newDisposable(); private File myTempDir; @Override protected void setUp() throws Exception { - final Application old = ApplicationManagerEx.getApplication(); - myRootDisposable = Disposer.newDisposable(); - MockApplicationEx app = new MockApplicationEx(getRootDisposable()) { - @NotNull - @Override - public Future executeOnPooledThread(@NotNull Runnable action) { - return old != null ? old.executeOnPooledThread(action) : super.executeOnPooledThread(action); - } - }; - ApplicationManager.setApplication(app, myRootDisposable); + LightPlatformTestCase.initApplication(); } public File getTempDir() throws IOException { diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java index 6deda3d4b70a..6f03fd02446e 100644 --- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java @@ -224,7 +224,7 @@ public abstract class UsefulTestCase extends TestCase { } public static CompositeException doCheckForSettingsDamage(@NotNull CodeStyleSettings oldCodeStyleSettings, - @NotNull CodeStyleSettings currentCodeStyleSettings) throws Exception { + @NotNull CodeStyleSettings currentCodeStyleSettings) throws Exception { CompositeException result = new CompositeException(); final CodeInsightSettings settings = CodeInsightSettings.getInstance(); try { @@ -234,9 +234,13 @@ public abstract class UsefulTestCase extends TestCase { } catch (AssertionError error) { CodeInsightSettings clean = new CodeInsightSettings(); - Element temp = new Element("temp"); - clean.writeExternal(temp); - settings.loadState(temp); + for (Field field : clean.getClass().getFields()) { + try { + ReflectionUtil.copyFieldValue(clean, settings, field); + } + catch (Exception ignored) { + } + } result.add(error); } diff --git a/platform/util-rt/src/com/intellij/util/containers/Stack.java b/platform/util-rt/src/com/intellij/util/containers/Stack.java index 29337c9c99b1..f1a0e37b1967 100644 --- a/platform/util-rt/src/com/intellij/util/containers/Stack.java +++ b/platform/util-rt/src/com/intellij/util/containers/Stack.java @@ -15,6 +15,7 @@ */ package com.intellij.util.containers; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -32,11 +33,11 @@ public class Stack extends ArrayList { super(initialCapacity); } - public Stack(Collection init) { + public Stack(@NotNull Collection init) { super(init); } - public Stack(T... items) { + public Stack(@NotNull T... items) { for (T item : items) { push(item); } diff --git a/platform/util/src/com/intellij/util/ReflectionUtil.java b/platform/util/src/com/intellij/util/ReflectionUtil.java index d5f6a58dc951..8e2204415988 100644 --- a/platform/util/src/com/intellij/util/ReflectionUtil.java +++ b/platform/util/src/com/intellij/util/ReflectionUtil.java @@ -19,17 +19,15 @@ package com.intellij.util; import com.intellij.Patches; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Condition; -import com.intellij.util.containers.ContainerUtil; +import com.intellij.openapi.util.DifferenceFilter; +import com.intellij.util.containers.*; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import sun.reflect.ConstructorAccessor; import java.lang.reflect.*; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; +import java.util.*; public class ReflectionUtil { private static final Logger LOG = Logger.getInstance("#com.intellij.util.ReflectionUtil"); @@ -479,6 +477,50 @@ public class ReflectionUtil { return callerClass; } + public static void copyFields(@NotNull Field[] fields, @NotNull Object from, @NotNull Object to) { + copyFields(fields, from, to, null); + } + + public static boolean copyFields(@NotNull Field[] fields, @NotNull Object from, @NotNull Object to, @Nullable DifferenceFilter diffFilter) { + Set sourceFields = new com.intellij.util.containers.HashSet(Arrays.asList(from.getClass().getFields())); + boolean valuesChanged = false; + for (Field field : fields) { + if (sourceFields.contains(field)) { + if (isPublic(field) && !isFinal(field)) { + try { + if (diffFilter == null || diffFilter.isAccept(field)) { + copyFieldValue(from, to, field); + valuesChanged = true; + } + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + } + } + return valuesChanged; + } + + public static void copyFieldValue(@NotNull Object from, @NotNull Object to, @NotNull Field field) + throws IllegalAccessException { + Class fieldType = field.getType(); + if (fieldType.isPrimitive() || fieldType.equals(String.class)) { + field.set(to, field.get(from)); + } + else { + throw new RuntimeException("Field '" + field.getName()+"' not copied: unsupported type: "+field.getType()); + } + } + + private static boolean isPublic(final Field field) { + return (field.getModifiers() & Modifier.PUBLIC) != 0; + } + + private static boolean isFinal(final Field field) { + return (field.getModifiers() & Modifier.FINAL) != 0; + } + private static class MySecurityManager extends SecurityManager { private static final MySecurityManager INSTANCE = new MySecurityManager(); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java index a2fb3d51d253..5a7c4bb6d0d8 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java @@ -187,14 +187,14 @@ public abstract class XValueContainerNodeemptyList()); final int[] indices = getNodesIndices(allMessageChildren); final TreeNode[] nodes = getChildNodes(indices); - myMessageChildren = null; - myTemporaryMessageChildren = null; fireNodesRemoved(indices, nodes); if (!temporary) { myMessageChildren = messages; + myTemporaryMessageChildren = null; } else { myTemporaryMessageChildren = messages; + myMessageChildren = null; } myCachedAllChildren = null; fireNodesInserted(messages); diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java index 5a6c106984bd..47fd152debec 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java @@ -110,13 +110,19 @@ public abstract class IGQuickFixesTestCase extends JavaCodeInsightFixtureTestCas } public IntentionAction findIntention(@NotNull final String hint) { - final List list = + final List availableIntentions = ContainerUtil.findAll(myFixture.getAvailableIntentions(), new Condition() { @Override public boolean value(final IntentionAction intentionAction) { return intentionAction instanceof QuickFixWrapper; } }); + final List list = ContainerUtil.findAll(availableIntentions, new Condition() { + @Override + public boolean value(IntentionAction intentionAction) { + return intentionAction.getText().equals(hint); + } + }); if (list.isEmpty()) { Assert.fail("\"" + hint + "\" not in " + list); } diff --git a/plugins/ui-designer-core/src/com/intellij/designer/AbstractToolWindowManager.java b/plugins/ui-designer-core/src/com/intellij/designer/AbstractToolWindowManager.java index 3fcce90e6801..7c23529c828b 100644 --- a/plugins/ui-designer-core/src/com/intellij/designer/AbstractToolWindowManager.java +++ b/plugins/ui-designer-core/src/com/intellij/designer/AbstractToolWindowManager.java @@ -15,121 +15,25 @@ */ package com.intellij.designer; -import com.intellij.designer.designSurface.DesignerEditorPanel; -import com.intellij.ide.util.PropertiesComponent; -import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.DefaultActionGroup; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.ProjectComponent; +import com.intellij.designer.palette.PaletteToolWindowManager; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.fileEditor.FileEditorManagerEvent; -import com.intellij.openapi.fileEditor.FileEditorManagerListener; -import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.Project; -import com.intellij.openapi.startup.StartupManager; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowAnchor; -import com.intellij.openapi.wm.ex.ToolWindowEx; -import com.intellij.util.ParameterizedRunnable; -import com.intellij.util.messages.MessageBusConnection; -import com.intellij.util.ui.update.MergingUpdateQueue; -import com.intellij.util.ui.update.Update; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; - /** * @author Alexander Lobas */ -public abstract class AbstractToolWindowManager implements ProjectComponent { - public static final String EDITOR_MODE = "UI_DESIGNER_EDITOR_MODE."; - - private final MergingUpdateQueue myWindowQueue = new MergingUpdateQueue(getComponentName(), 200, true, null); - protected final Project myProject; - protected final FileEditorManager myFileEditorManager; - protected volatile ToolWindow myToolWindow; - private volatile boolean myToolWindowDisposed; - - private final PropertiesComponent myPropertiesComponent; - public final String myEditorModeKey; - private ToggleEditorModeAction myLeftEditorModeAction; - private ToggleEditorModeAction myRightEditorModeAction; - - private MessageBusConnection myConnection; - private final FileEditorManagerListener myListener = new FileEditorManagerListener() { - @Override - public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) { - bindToDesigner(getActiveDesigner()); - } - - @Override - public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) { - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - bindToDesigner(getActiveDesigner()); - } - }); - } - - @Override - public void selectionChanged(@NotNull FileEditorManagerEvent event) { - bindToDesigner(getDesigner(event.getNewEditor())); - } - }; - - ////////////////////////////////////////////////////////////////////////////////////////// - // - // ToolWindow - // - ////////////////////////////////////////////////////////////////////////////////////////// +public abstract class AbstractToolWindowManager extends LightToolWindowManager { protected AbstractToolWindowManager(Project project, FileEditorManager fileEditorManager) { - myProject = project; - myFileEditorManager = fileEditorManager; - myPropertiesComponent = PropertiesComponent.getInstance(myProject); - myEditorModeKey = EDITOR_MODE + getComponentName() + ".STATE"; - } - - @Override - public void projectOpened() { - initToolWindow(); - - StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() { - public void run() { - if (getEditorMode() == null) { - initListeners(); - bindToDesigner(getActiveDesigner()); - } - } - }); - } - - @Override - public void projectClosed() { - if (!myToolWindowDisposed) { - disposeComponent(); - myToolWindowDisposed = true; - myToolWindow = null; - } - } - - private void initListeners() { - myConnection = myProject.getMessageBus().connect(myProject); - myConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, myListener); - } - - private void removeListeners() { - myConnection.disconnect(); - myConnection = null; + super(project, fileEditorManager); } @Nullable - private static DesignerEditorPanel getDesigner(FileEditor editor) { + @Override + protected DesignerEditorPanelFacade getDesigner(FileEditor editor) { if (editor instanceof DesignerEditor) { DesignerEditor designerEditor = (DesignerEditor)editor; return designerEditor.getDesignerPanel(); @@ -137,196 +41,20 @@ public abstract class AbstractToolWindowManager implements ProjectComponent { return null; } - @Nullable - public DesignerEditorPanel getActiveDesigner() { - for (FileEditor editor : myFileEditorManager.getSelectedEditors()) { - DesignerEditorPanel designer = getDesigner(editor); - if (designer != null) { - return designer; + @Override + protected ToggleEditorModeAction createToggleAction(ToolWindowAnchor anchor) { + return new ToggleEditorModeAction(this, myProject, anchor) { + @Override + protected LightToolWindowManager getOppositeManager() { + AbstractToolWindowManager designerManager = DesignerToolWindowManager.getInstance(myProject); + AbstractToolWindowManager paletteManager = PaletteToolWindowManager.getInstance(myProject); + return myManager == designerManager ? paletteManager : designerManager; } - } - - return null; + }; } @Nullable protected static DesignerCustomizations getCustomizations() { return DesignerCustomizations.EP_NAME.findExtension(DesignerCustomizations.class); } - - private void bindToDesigner(final DesignerEditorPanel designer) { - myWindowQueue.cancelAllUpdates(); - myWindowQueue.queue(new Update("update") { - @Override - public void run() { - if (myToolWindowDisposed) { - return; - } - if (myToolWindow == null) { - if (designer == null) { - return; - } - initToolWindow(); - } - updateToolWindow(designer); - } - }); - } - - protected abstract void initToolWindow(); - - protected abstract void updateToolWindow(@Nullable DesignerEditorPanel designer); - - protected final void initGearActions() { - ToolWindowEx toolWindow = (ToolWindowEx)myToolWindow; - toolWindow.setAdditionalGearActions(new DefaultActionGroup(createGearActions())); - } - - protected abstract ToolWindowAnchor getAnchor(); - - @Override - public void initComponent() { - } - - @Override - public void disposeComponent() { - } - - ////////////////////////////////////////////////////////////////////////////////////////// - // - // LightToolWindow - // - ////////////////////////////////////////////////////////////////////////////////////////// - - public final ActionGroup createGearActions() { - DefaultActionGroup group = new DefaultActionGroup("In Editor Mode", true); - - if (myLeftEditorModeAction == null) { - myLeftEditorModeAction = new ToggleEditorModeAction(this, myProject, ToolWindowAnchor.LEFT); - } - group.add(myLeftEditorModeAction); - - if (myRightEditorModeAction == null) { - myRightEditorModeAction = new ToggleEditorModeAction(this, myProject, ToolWindowAnchor.RIGHT); - } - group.add(myRightEditorModeAction); - - return group; - } - - public final void bind(DesignerEditorPanel designer) { - if (isEditorMode()) { - myCreateAction.run(designer); - } - } - - public final void dispose(DesignerEditorPanel designer) { - if (isEditorMode()) { - disposeContent(designer); - } - } - - protected final Object getContent(DesignerEditorPanel designer) { - LightToolWindow toolWindow = (LightToolWindow)designer.getClientProperty(getComponentName()); - return toolWindow.getContent(); - } - - protected abstract LightToolWindow createContent(DesignerEditorPanel designer); - - protected final LightToolWindow createContent(DesignerEditorPanel designer, - LightToolWindowContent content, - String title, - Icon icon, - JComponent component, - JComponent focusedComponent, - int defaultWidth, - AnAction[] actions) { - return new LightToolWindow(content, - title, - icon, - component, - focusedComponent, - designer.getContentSplitter(), - getEditorMode(), - this, - myProject, - myPropertiesComponent, - getComponentName(), - defaultWidth, - actions); - } - - protected final void disposeContent(DesignerEditorPanel designer) { - String key = getComponentName(); - LightToolWindow toolWindow = (LightToolWindow)designer.getClientProperty(key); - designer.putClientProperty(key, null); - toolWindow.dispose(); - } - - private final ParameterizedRunnable myCreateAction = new ParameterizedRunnable() { - @Override - public void run(DesignerEditorPanel designer) { - designer.putClientProperty(getComponentName(), createContent(designer)); - } - }; - - private final ParameterizedRunnable myUpdateAnchorAction = new ParameterizedRunnable() { - @Override - public void run(DesignerEditorPanel designer) { - LightToolWindow toolWindow = (LightToolWindow)designer.getClientProperty(getComponentName()); - toolWindow.updateAnchor(getEditorMode()); - } - }; - - private final ParameterizedRunnable myDisposeAction = new ParameterizedRunnable() { - @Override - public void run(DesignerEditorPanel designer) { - disposeContent(designer); - } - }; - - private void runUpdateContent(ParameterizedRunnable action) { - for (FileEditor editor : myFileEditorManager.getAllEditors()) { - DesignerEditorPanel designer = getDesigner(editor); - if (designer != null) { - action.run(designer); - } - } - } - - protected final boolean isEditorMode() { - return getEditorMode() != null; - } - - @Nullable - final ToolWindowAnchor getEditorMode() { - String value = myPropertiesComponent.getValue(myEditorModeKey); - if (value == null) { - return getAnchor(); - } - return value.equals("ToolWindow") ? null : ToolWindowAnchor.fromText(value); - } - - final void setEditorMode(@Nullable ToolWindowAnchor newState) { - ToolWindowAnchor oldState = getEditorMode(); - myPropertiesComponent.setValue(myEditorModeKey, newState == null ? "ToolWindow" : newState.toString()); - - if (oldState != null && newState != null) { - runUpdateContent(myUpdateAnchorAction); - } - else if (newState != null) { - removeListeners(); - updateToolWindow(null); - runUpdateContent(myCreateAction); - } - else { - runUpdateContent(myDisposeAction); - initListeners(); - bindToDesigner(getActiveDesigner()); - } - } - - final ToolWindow getToolWindow() { - return myToolWindow; - } } \ No newline at end of file diff --git a/plugins/ui-designer-core/src/com/intellij/designer/DesignerToolWindowManager.java b/plugins/ui-designer-core/src/com/intellij/designer/DesignerToolWindowManager.java index 8c5fa6412e04..2631e83625a5 100644 --- a/plugins/ui-designer-core/src/com/intellij/designer/DesignerToolWindowManager.java +++ b/plugins/ui-designer-core/src/com/intellij/designer/DesignerToolWindowManager.java @@ -96,8 +96,8 @@ public final class DesignerToolWindowManager extends AbstractToolWindowManager { } @Override - protected void updateToolWindow(@Nullable DesignerEditorPanel designer) { - myToolWindowContent.update(designer); + protected void updateToolWindow(@Nullable DesignerEditorPanelFacade designer) { + myToolWindowContent.update((DesignerEditorPanel)designer); if (designer == null) { myToolWindow.setAvailable(false, null); @@ -126,9 +126,9 @@ public final class DesignerToolWindowManager extends AbstractToolWindowManager { ////////////////////////////////////////////////////////////////////////////////////////// @Override - protected LightToolWindow createContent(DesignerEditorPanel designer) { + protected LightToolWindow createContent(DesignerEditorPanelFacade designer) { DesignerToolWindow toolWindowContent = new DesignerToolWindow(myProject, false); - toolWindowContent.update(designer); + toolWindowContent.update((DesignerEditorPanel)designer); return createContent(designer, toolWindowContent, diff --git a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/DesignerEditorPanel.java b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/DesignerEditorPanel.java index 067924556325..c3aaa6939f54 100644 --- a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/DesignerEditorPanel.java +++ b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/DesignerEditorPanel.java @@ -78,7 +78,8 @@ import java.util.List; /** * @author Alexander Lobas */ -public abstract class DesignerEditorPanel extends JPanel implements DataProvider, ModuleProvider, RadPropertyContext { +public abstract class DesignerEditorPanel extends JPanel + implements DesignerEditorPanelFacade, DataProvider, ModuleProvider, RadPropertyContext { private static final Logger LOG = Logger.getInstance("#com.intellij.designer.designSurface.DesignerEditorPanel"); protected static final Integer LAYER_COMPONENT = JLayeredPane.DEFAULT_LAYER; diff --git a/plugins/ui-designer-core/src/com/intellij/designer/palette/PaletteToolWindowManager.java b/plugins/ui-designer-core/src/com/intellij/designer/palette/PaletteToolWindowManager.java index ae14d96e0248..63631f772665 100644 --- a/plugins/ui-designer-core/src/com/intellij/designer/palette/PaletteToolWindowManager.java +++ b/plugins/ui-designer-core/src/com/intellij/designer/palette/PaletteToolWindowManager.java @@ -17,6 +17,7 @@ package com.intellij.designer.palette; import com.intellij.designer.AbstractToolWindowManager; import com.intellij.designer.DesignerCustomizations; +import com.intellij.designer.DesignerEditorPanelFacade; import com.intellij.designer.LightToolWindow; import com.intellij.designer.designSurface.DesignerEditorPanel; import com.intellij.icons.AllIcons; @@ -85,8 +86,8 @@ public class PaletteToolWindowManager extends AbstractToolWindowManager { } @Override - protected void updateToolWindow(@Nullable DesignerEditorPanel designer) { - myToolWindowPanel.loadPalette(designer); + protected void updateToolWindow(@Nullable DesignerEditorPanelFacade designer) { + myToolWindowPanel.loadPalette((DesignerEditorPanel)designer); if (myToolWindowPanel.isEmpty()) { myToolWindow.setAvailable(false, null); @@ -115,9 +116,9 @@ public class PaletteToolWindowManager extends AbstractToolWindowManager { ////////////////////////////////////////////////////////////////////////////////////////// @Override - protected LightToolWindow createContent(DesignerEditorPanel designer) { + protected LightToolWindow createContent(DesignerEditorPanelFacade designer) { PalettePanel palettePanel = new PalettePanel(); - palettePanel.loadPalette(designer); + palettePanel.loadPalette((DesignerEditorPanel)designer); return createContent(designer, palettePanel, diff --git a/python/edu/course-creator/resources/META-INF/plugin.xml b/python/edu/course-creator/resources/META-INF/plugin.xml index 0e984b2fcb65..1b6dfc9c61af 100644 --- a/python/edu/course-creator/resources/META-INF/plugin.xml +++ b/python/edu/course-creator/resources/META-INF/plugin.xml @@ -58,6 +58,12 @@ + + + + + + diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectComponent.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectComponent.java index d5e3085f0f07..20e7753e0247 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectComponent.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectComponent.java @@ -151,7 +151,7 @@ public class CCProjectComponent implements ProjectComponent { if (task == null) { return; } - lesson.getTasklist().remove(task); + lesson.getTaskList().remove(task); lesson.getTasksMap().remove(removedFile.getName()); } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectService.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectService.java index 17bb8013e2a7..c06925e9a453 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectService.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectService.java @@ -71,6 +71,9 @@ public class CCProjectService implements PersistentStateComponent { @Override public void loadState(Element el) { myCourse = XmlSerializer.deserialize(el.getChild(COURSE_ELEMENT), Course.class); + if (myCourse != null) { + myCourse.init(); + } } public static CCProjectService getInstance(@NotNull Project project) { @@ -155,7 +158,7 @@ public class CCProjectService implements PersistentStateComponent { } Lesson lesson = lessons.get(lessonIndex); int taskIndex = getIndex(taskDirName, "task"); - List tasks = lesson.getTasklist(); + List tasks = lesson.getTaskList(); if (!indexIsValid(taskIndex, tasks)) { return false; } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCRunTests.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCRunTests.java index a0e2efa36c55..d078972e3f56 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCRunTests.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCRunTests.java @@ -228,8 +228,8 @@ public class CCRunTests extends AnAction { .createChildDirectory(project, taskDir.getName()); if (CCProjectService.indexIsValid(lessonIndex, course.getLessons())) { Lesson lesson = course.getLessons().get(lessonIndex); - if (CCProjectService.indexIsValid(index, lesson.getTasklist())) { - Task task = lesson.getTasklist().get(index); + if (CCProjectService.indexIsValid(index, lesson.getTaskList())) { + Task task = lesson.getTaskList().get(index); HashMap taskFilesCopy = new HashMap(); for (Map.Entry entry : task.getTaskFiles().entrySet()) { CreateCourseArchive.createUserFile(project, taskFilesCopy, taskResourceDir, taskDir, entry); diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCRename.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCRename.java new file mode 100644 index 000000000000..ae6c3906f186 --- /dev/null +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCRename.java @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.coursecreator.actions; + +import com.intellij.ide.IdeView; +import com.intellij.ide.projectView.ProjectView; +import com.intellij.ide.util.DirectoryChooserUtil; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.coursecreator.CCProjectService; +import org.jetbrains.plugins.coursecreator.format.Course; + +import javax.swing.*; + +public abstract class CCRename extends DumbAwareAction { + public CCRename(String text, String description, Icon icon) { + super(text, description, icon); + } + + @Override + public void update(@NotNull AnActionEvent event) { + final Presentation presentation = event.getPresentation(); + final Project project = event.getData(CommonDataKeys.PROJECT); + if (project == null) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + + final IdeView view = event.getData(LangDataKeys.IDE_VIEW); + if (view == null) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + + final PsiDirectory[] directories = view.getDirectories(); + if (directories.length == 0) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view); + if (directory == null || !directory.getName().contains(getFolderName())) { + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + presentation.setVisible(true); + presentation.setEnabled(true); + } + + public abstract String getFolderName(); + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + final IdeView view = e.getData(LangDataKeys.IDE_VIEW); + final Project project = e.getData(CommonDataKeys.PROJECT); + + if (view == null || project == null) { + return; + } + final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view); + if (directory == null || !directory.getName().contains("lesson")) { + return; + } + Course course = CCProjectService.getInstance(project).getCourse(); + if (course == null) { + return; + } + if (!processRename(project, directory, course)) return; + ProjectView.getInstance(project).refresh(); + } + + public abstract boolean processRename(Project project, PsiDirectory directory, Course course); +} diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCRenameLesson.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCRenameLesson.java new file mode 100644 index 000000000000..3f580454ed6e --- /dev/null +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCRenameLesson.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.coursecreator.actions; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiDirectory; +import org.jetbrains.plugins.coursecreator.format.Course; +import org.jetbrains.plugins.coursecreator.format.Lesson; + +public class CCRenameLesson extends CCRename { + + public CCRenameLesson() { + super("Rename Lesson", "Rename Lesson", null); + } + + @Override + public String getFolderName() { + return "lesson"; + } + + @Override + public boolean processRename(Project project, PsiDirectory directory, Course course) { + Lesson lesson = course.getLesson(directory.getName()); + if (lesson == null) { + return false; + } + String newName = Messages.showInputDialog(project, "Enter new name", "Rename " + getFolderName(), null); + if (newName == null) { + return false; + } + lesson.setName(newName); + return true; + } +} diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCRenameTask.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCRenameTask.java new file mode 100644 index 000000000000..342621bf0d47 --- /dev/null +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCRenameTask.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.coursecreator.actions; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiDirectory; +import org.jetbrains.plugins.coursecreator.format.Course; +import org.jetbrains.plugins.coursecreator.format.Lesson; +import org.jetbrains.plugins.coursecreator.format.Task; + +public class CCRenameTask extends CCRename { + public CCRenameTask() { + super("Rename Task", "Rename Task", null); + } + + @Override + public String getFolderName() { + return "task"; + } + + @Override + public boolean processRename(Project project, PsiDirectory directory, Course course) { + PsiDirectory lessonDir = directory.getParent(); + if (lessonDir == null || !lessonDir.getName().contains("lesson")) { + return false; + } + Lesson lesson = course.getLesson(lessonDir.getName()); + if (lesson == null) { + return false; + } + Task task = lesson.getTask(directory.getName()); + if (task == null) { + return false; + } + String newName = Messages.showInputDialog(project, "Enter new name", "Rename " + getFolderName(), null); + if (newName == null) { + return false; + } + task.setName(newName); + return true; + + } +} diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateTask.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateTask.java index aa33ccc23a9b..57a37b3f4194 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateTask.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateTask.java @@ -18,6 +18,7 @@ import com.intellij.openapi.ui.Messages; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.util.PlatformIcons; +import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.coursecreator.CCProjectService; import org.jetbrains.plugins.coursecreator.format.Course; import org.jetbrains.plugins.coursecreator.format.Lesson; @@ -42,7 +43,7 @@ public class CreateTask extends DumbAwareAction { final CCProjectService service = CCProjectService.getInstance(project); final Course course = service.getCourse(); final Lesson lesson = course.getLesson(directory.getName()); - final int size = lesson.getTasklist().size(); + final int size = lesson.getTaskList().size(); final String taskName = Messages.showInputDialog("Name:", "Task Name", null, "task" + (size + 1), null); if (taskName == null) return; @@ -83,7 +84,7 @@ public class CreateTask extends DumbAwareAction { } @Override - public void update(AnActionEvent event) { + public void update(@NotNull AnActionEvent event) { final Presentation presentation = event.getPresentation(); final Project project = event.getData(CommonDataKeys.PROJECT); if (project == null) { diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Course.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Course.java index eb62d59cd9b1..e124a6eb305d 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Course.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Course.java @@ -4,10 +4,7 @@ import com.google.gson.annotations.Expose; import com.intellij.psi.PsiDirectory; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class Course { @Expose public List lessons = new ArrayList(); @@ -52,4 +49,13 @@ public class Course { public String getDescription() { return description; } + + public void init() { + lessons.clear(); + for (Lesson lesson: myLessonsMap.values()) { + lessons.add(lesson); + lesson.init(); + } + Collections.sort(lessons); + } } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Lesson.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Lesson.java index 69aa748bf873..bd91e8ec30af 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Lesson.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Lesson.java @@ -4,12 +4,9 @@ import com.google.gson.annotations.Expose; import com.intellij.psi.PsiDirectory; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; -public class Lesson { +public class Lesson implements Comparable{ @Expose public String name; @Expose public List task_list = new ArrayList(); @@ -27,11 +24,15 @@ public class Lesson { task_list.add(task); } + public void setName(String name) { + this.name = name; + } + public Task getTask(@NotNull final String name) { return myTasksMap.get(name); } - public List getTasklist() { + public List getTaskList() { return task_list; } @@ -46,4 +47,18 @@ public class Lesson { public Map getTasksMap() { return myTasksMap; } + + public void init() { + task_list.clear(); + for (Task task : myTasksMap.values()) { + task_list.add(task); + } + Collections.sort(task_list); + } + + @Override + public int compareTo(@NotNull Object o) { + Lesson lesson = (Lesson) o; + return myIndex - lesson.getIndex(); + } } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Task.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Task.java index e1e9923653f7..886add86ceb4 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Task.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Task.java @@ -7,7 +7,7 @@ import org.jetbrains.plugins.coursecreator.CCProjectService; import java.util.HashMap; import java.util.Map; -public class Task { +public class Task implements Comparable{ @Expose public String name; @Expose public Map task_files = new HashMap(); public int myIndex; @@ -44,4 +44,14 @@ public class Task { public boolean isTaskFile(String name) { return task_files.get(name) != null; } + + public void setName(String name) { + this.name = name; + } + + @Override + public int compareTo(@NotNull Object o) { + Task task = (Task) o; + return myIndex - task.getIndex(); + } } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchivePanel.form b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchivePanel.form index 920dcb9494a7..096a85f8da59 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchivePanel.form +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchivePanel.form @@ -27,7 +27,7 @@ - + diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java index c7e8f715672c..53a4a77b97f7 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java @@ -150,4 +150,10 @@ public class CreateTaskWindowDialog extends DialogWrapper { public void validateInput() { super.initValidation(); } + + @Nullable + @Override + public JComponent getPreferredFocusedComponent() { + return myPanel.getPreferredFocusedComponent(); + } } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.java index 21a7eb063c63..a50840deaf2f 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.java @@ -37,6 +37,7 @@ public class CreateTaskWindowPanel extends JPanel { } }); + myTaskWindowText.grabFocus(); myHintName.getDocument().addDocumentListener(new DocumentAdapter() { @Override protected void textChanged(DocumentEvent e) { @@ -93,4 +94,8 @@ public class CreateTaskWindowPanel extends JPanel { public void setGeneratedHintName(String generatedHintName) { myGeneratedHintName = generatedHintName; } + + public JComponent getPreferredFocusedComponent() { + return myTaskWindowText; + } }