From 49354727e9819478e3616d8a2bff505eb350571d Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 8 Aug 2015 17:40:35 +0300 Subject: [PATCH 01/99] [git] Don't fail if meet non-existent config vars starting with 'remote' & DRY Relates to IDEA-143363. --- .../git4idea/src/git4idea/repo/GitConfig.java | 28 +++++--------- .../tests/git4idea/repo/GitConfigTest.java | 37 +++++++++++++++---- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/plugins/git4idea/src/git4idea/repo/GitConfig.java b/plugins/git4idea/src/git4idea/repo/GitConfig.java index f5c86c1b611f..fc35665e2f9d 100644 --- a/plugins/git4idea/src/git4idea/repo/GitConfig.java +++ b/plugins/git4idea/src/git4idea/repo/GitConfig.java @@ -51,7 +51,7 @@ public class GitConfig { private static final Logger LOG = Logger.getInstance(GitConfig.class); - private static final Pattern REMOTE_SECTION = Pattern.compile("(?:svn-)?remote(?: \"(.*)\")?"); + private static final Pattern REMOTE_SECTION = Pattern.compile("(?:svn-)?remote \"(.*)\""); private static final Pattern URL_SECTION = Pattern.compile("url \"(.*)\""); private static final Pattern BRANCH_INFO_SECTION = Pattern.compile("branch \"(.*)\""); private static final Pattern BRANCH_COMMON_PARAMS_SECTION = Pattern.compile("branch"); @@ -246,13 +246,11 @@ public class GitConfig { String sectionName = stringSectionEntry.getKey(); Profile.Section section = stringSectionEntry.getValue(); - if (sectionName.startsWith("remote") || sectionName.startsWith("svn-remote")) { - Remote remote = parseRemoteSection(sectionName, section, classLoader); - if (remote != null) { - remotes.add(remote); - } + Remote remote = parseRemoteSection(sectionName, section, classLoader); + if (remote != null) { + remotes.add(remote); } - else if (sectionName.startsWith("url")) { + else { Url url = parseUrlSection(sectionName, section, classLoader); if (url != null) { urls.add(url); @@ -372,27 +370,19 @@ public class GitConfig { private static Remote parseRemoteSection(@NotNull String sectionName, @NotNull Profile.Section section, @NotNull ClassLoader classLoader) { - RemoteBean remoteBean = section.as(RemoteBean.class, classLoader); Matcher matcher = REMOTE_SECTION.matcher(sectionName); - if (matcher.matches()) { - String remoteName = matcher.group(1); - if (remoteName == null) { // e.g. remote.pushdefault generic setting not specific to any remote - return null; - } - return new Remote(remoteName, remoteBean); + if (matcher.matches() && matcher.groupCount() == 1) { + return new Remote(matcher.group(1), section.as(RemoteBean.class, classLoader)); } - LOG.error(String.format("Invalid remote section format in .git/config. sectionName: %s section: %s", sectionName, section)); return null; } @Nullable private static Url parseUrlSection(@NotNull String sectionName, @NotNull Profile.Section section, @NotNull ClassLoader classLoader) { - UrlBean urlBean = section.as(UrlBean.class, classLoader); Matcher matcher = URL_SECTION.matcher(sectionName); - if (matcher.matches()) { - return new Url(matcher.group(1), urlBean); + if (matcher.matches() && matcher.groupCount() == 1) { + return new Url(matcher.group(1), section.as(UrlBean.class, classLoader)); } - LOG.error(String.format("Invalid url section format in .git/config. sectionName: %s section: %s", sectionName, section)); return null; } diff --git a/plugins/git4idea/tests/git4idea/repo/GitConfigTest.java b/plugins/git4idea/tests/git4idea/repo/GitConfigTest.java index 1781a004a085..94bb705dd9c6 100644 --- a/plugins/git4idea/tests/git4idea/repo/GitConfigTest.java +++ b/plugins/git4idea/tests/git4idea/repo/GitConfigTest.java @@ -57,8 +57,8 @@ public class GitConfigTest extends GitPlatformTest { //inspired by IDEA-135557 public void test_branch_with_hash_symbol() throws IOException { - GitTestUtil.createRepository(myProject, myProjectPath, true); - git("remote add origin http://example.git"); // define a remote to be able to set up tracking + createRepository(); + addRemote("http://example.git"); git("update-ref refs/remotes/origin/a#branch HEAD"); git("branch --track a#branch origin/a#branch"); @@ -78,13 +78,30 @@ public class GitConfigTest extends GitPlatformTest { // IDEA-143363 Check that remote.pushdefault (generic, without remote name) doesn't fail the config parsing procedure public void test_remote_unspecified_section() throws Exception { - GitTestUtil.createRepository(myProject, myProjectPath, true); - git("remote add origin git@github.com:foo/bar.git"); + createRepository(); + addRemote("git@github.com:foo/bar.git"); git("config remote.pushdefault origin"); - File gitDir = new File(myProjectPath, ".git"); - GitConfig config = GitConfig.read(myPlatformFacade, new File(gitDir, "config")); - Collection remotes = config.parseRemotes(); + assertSingleRemoteInConfig(); + } + + public void test_invalid_section_with_remote_prefix_is_ignored() throws Exception { + createRepository(); + addRemote("git@github.com:foo/bar.git"); + git("config remote-cfg.newkey newval"); + + assertSingleRemoteInConfig(); + } + + private static void addRemote(@NotNull String url) { + git("remote add origin " + url); + } + + private void createRepository() { + GitTestUtil.createRepository(myProject, myProjectPath, true); + } + + private static void assertSingleRemote(@NotNull Collection remotes) { assertEquals(1, remotes.size()); GitRemote remote = ContainerUtil.getFirstItem(remotes); assertNotNull(remote); @@ -92,6 +109,12 @@ public class GitConfigTest extends GitPlatformTest { assertEquals("git@github.com:foo/bar.git", remote.getFirstUrl()); } + private void assertSingleRemoteInConfig() { + File gitDir = new File(myProjectPath, ".git"); + Collection remotes = GitConfig.read(myPlatformFacade, new File(gitDir, "config")).parseRemotes(); + assertSingleRemote(remotes); + } + private void doTestRemotes(String testName, File configFile, File resultFile) throws IOException { GitConfig config = GitConfig.read(myPlatformFacade, configFile); VcsTestUtil.assertEqualCollections(testName, config.parseRemotes(), readRemoteResults(resultFile)); From 59f25f978972e9302e4a746ef6de03ed9ec1cdcd Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 8 Aug 2015 21:51:46 +0200 Subject: [PATCH 02/99] generate default method and improved text & description for "delegated method with default parameter value" intentions --- .../DefineParamsDefaultValueAction.java | 44 +++++++++++++++---- ...eWithDefaultParamValueIntentionAction.java | 27 +++++++----- .../delegateWithDefaultValue/after1.java | 2 +- .../afterAbstractMethod.java | 2 +- .../afterCommentsInBody.java | 2 +- .../afterConstructor.java | 2 +- .../afterInterface.java | 8 ++++ .../afterJavadoc.java | 2 +- .../afterReturnValue.java | 2 +- .../afterTypeParams.java | 2 +- .../afterVarargs.java | 2 +- .../delegateWithDefaultValue/before1.java | 2 +- .../beforeAbstractMethod.java | 2 +- .../beforeCommentsInBody.java | 2 +- .../beforeConstructor.java | 2 +- .../beforeExistinMethod.java | 2 +- .../beforeInterface.java | 2 +- .../beforeJavadoc.java | 2 +- .../beforeReturnValue.java | 2 +- .../beforeTypeParams.java | 2 +- .../beforeVarargs.java | 2 +- .../after.java.template | 3 +- .../before.java.template | 2 +- .../description.html | 2 +- .../after.java.template | 3 +- .../before.java.template | 2 +- .../description.html | 2 +- 27 files changed, 85 insertions(+), 44 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterInterface.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefineParamsDefaultValueAction.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefineParamsDefaultValueAction.java index 02e4c3afcc69..7440f6feb0e8 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefineParamsDefaultValueAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefineParamsDefaultValueAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -17,10 +17,12 @@ package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.intention.impl.ParameterClassMember; import com.intellij.ide.util.MemberChooser; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.PsiParameter; +import com.intellij.lang.java.JavaLanguage; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -32,24 +34,42 @@ import java.util.List; */ public class DefineParamsDefaultValueAction extends DelegateWithDefaultParamValueIntentionAction { - @NotNull @Override - public String getText() { - return "Define params default value"; + public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { + if (!JavaLanguage.INSTANCE.equals(element.getLanguage())) { + return false; + } + final PsiElement parent = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiCodeBlock.class); + if (!(parent instanceof PsiMethod)) { + return false; + } + final PsiMethod method = (PsiMethod)parent; + final PsiParameterList parameterList = method.getParameterList(); + if (parameterList.getParametersCount() == 0) { + return false; + } + final PsiClass containingClass = method.getContainingClass(); + if (containingClass == null || (containingClass.isInterface() && !PsiUtil.isLanguageLevel8OrHigher(method))) { + return false; + } + setText("Generate overloaded " + (method.isConstructor() ? "constructor" : "method") + " with default parameter values"); + return true; } @Nullable @Override protected PsiParameter[] getParams(PsiElement element) { final PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class); + assert method != null; final PsiParameter[] parameters = method.getParameterList().getParameters(); final ParameterClassMember[] members = new ParameterClassMember[parameters.length]; for (int i = 0; i < members.length; i++) { members[i] = new ParameterClassMember(parameters[i]); } - final MemberChooser chooser = new MemberChooser(members, false, true, element.getProject()); + final MemberChooser chooser = + new MemberChooser(members, false, true, element.getProject()); chooser.selectElements(members); - chooser.setTitle("Choose " + (method.isConstructor() ? "Constructor" : "Method") + " Parameters"); + chooser.setTitle("Choose Default Value Parameters"); if (chooser.showAndGet()) { final List elements = chooser.getSelectedElements(); if (elements != null) { @@ -67,4 +87,10 @@ public class DefineParamsDefaultValueAction extends DelegateWithDefaultParamValu public boolean startInWriteAction() { return false; } + + @NotNull + @Override + public String getFamilyName() { + return "Generate overloaded method with default parameter values"; + } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DelegateWithDefaultParamValueIntentionAction.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DelegateWithDefaultParamValueIntentionAction.java index 856ffee4ef5d..45655508b787 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DelegateWithDefaultParamValueIntentionAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DelegateWithDefaultParamValueIntentionAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -33,6 +33,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; @@ -57,8 +58,12 @@ public class DelegateWithDefaultParamValueIntentionAction extends PsiElementBase if (declarationScope instanceof PsiMethod) { final PsiMethod method = (PsiMethod)declarationScope; final PsiClass containingClass = method.getContainingClass(); - if (containingClass != null && !containingClass.isInterface()) { - return containingClass.findMethodBySignature(generateMethodPrototype(method, parameter), false) == null; + if (containingClass != null && (!containingClass.isInterface() || PsiUtil.isLanguageLevel7OrHigher(method))) { + if (containingClass.findMethodBySignature(generateMethodPrototype(method, parameter), false) != null) { + return false; + } + setText("Generate overloaded " + (method.isConstructor() ? "constructor" : "method") + " with default parameter value"); + return true; } } } @@ -81,6 +86,11 @@ public class DelegateWithDefaultParamValueIntentionAction extends PsiElementBase prototype.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, false); prototype.addBefore(emptyBody, null); } + final PsiClass aClass = method.getContainingClass(); + if (aClass != null && aClass.isInterface()) { + prototype.getModifierList().setModifierProperty(PsiModifier.DEFAULT, true); + } + for (int i = params.length - 1; i >= 0; i--) { PsiParameter param = params[i]; final int parameterIndex = method.getParameterList().getParameterIndex(param); @@ -98,7 +108,8 @@ public class DelegateWithDefaultParamValueIntentionAction extends PsiElementBase final PsiMethod existingMethod = method.getContainingClass().findMethodBySignature(methodPrototype, false); if (existingMethod != null) { editor.getCaretModel().moveToOffset(existingMethod.getTextOffset()); - HintManager.getInstance().showErrorHint(editor, "Method with the chosen signature already exist"); + HintManager.getInstance().showErrorHint(editor, (existingMethod.isConstructor() ? "Constructor" : "Method") + + " with the chosen signature already exists"); return; } @@ -170,15 +181,9 @@ public class DelegateWithDefaultParamValueIntentionAction extends PsiElementBase return new PsiParameter[]{PsiTreeUtil.getParentOfType(element, PsiParameter.class)}; } - @NotNull - @Override - public String getText() { - return "Generate delegated method with default parameter value"; - } - @NotNull @Override public String getFamilyName() { - return getText(); + return "Generate overloaded method with default parameter value"; } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/after1.java index f37bae2df539..89683098fc6b 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/after1.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/after1.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded method with default parameter value" "true" class Test { void foo() { foo(); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterAbstractMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterAbstractMethod.java index 0ee8f0b4b26c..e72764fff0dc 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterAbstractMethod.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterAbstractMethod.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded method with default parameter value" "true" abstract class Test { int foo(boolean... args) { return foo(, args); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterCommentsInBody.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterCommentsInBody.java index a9044760f7bb..4844902fdf14 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterCommentsInBody.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterCommentsInBody.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded method with default parameter value" "true" class Test { int foo() { return foo(); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterConstructor.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterConstructor.java index 2ba4de2c87e2..b73c48ebd2df 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterConstructor.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterConstructor.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded constructor with default parameter value" "true" class Test { Test() { this(); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterInterface.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterInterface.java new file mode 100644 index 000000000000..decd3f141818 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterInterface.java @@ -0,0 +1,8 @@ +// "Generate overloaded method with default parameter value" "true" +interface Test { + default void foo() { + foo(); + } + + void foo(int ii); +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterJavadoc.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterJavadoc.java index 8637aaf12ea1..3f15183133d7 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterJavadoc.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterJavadoc.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded method with default parameter value" "true" class Test { /** */ diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterReturnValue.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterReturnValue.java index 39c8186309be..1e89e83a3cb7 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterReturnValue.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterReturnValue.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded method with default parameter value" "true" class Test { int foo() { return foo(); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterTypeParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterTypeParams.java index 76d6ebeb4c0b..57fb3563e0ac 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterTypeParams.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterTypeParams.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded method with default parameter value" "true" class Test { int foo(boolean... args) { return foo(, args); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterVarargs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterVarargs.java index f1645794d65b..68e2eaeec564 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterVarargs.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/afterVarargs.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded method with default parameter value" "true" class Test { int foo(boolean... args) { return foo(, args); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/before1.java index 22b77602b869..48895a8251b2 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/before1.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/before1.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded method with default parameter value" "true" class Test { void foo(int ii){ } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeAbstractMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeAbstractMethod.java index e298bc77f4a6..320debae10f2 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeAbstractMethod.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeAbstractMethod.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded method with default parameter value" "true" abstract class Test { abstract int foo(int ii, boolean... args); } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeCommentsInBody.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeCommentsInBody.java index bdd6fc83b075..9a6ad6184854 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeCommentsInBody.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeCommentsInBody.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded method with default parameter value" "true" class Test { int foo(int ii){ //comment1 diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeConstructor.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeConstructor.java index 0d75c3918ed8..7fe236b65cf4 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeConstructor.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeConstructor.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded constructor with default parameter value" "true" class Test { Test(int ii){} } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeExistinMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeExistinMethod.java index 0d5ff1b0782f..52fa17401c5d 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeExistinMethod.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeExistinMethod.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "false" +// "Generate overloaded method with default parameter value" "false" class Test { void foo(){} void foo(int ii){ diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeInterface.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeInterface.java index a18fdba97688..1f960d28b21d 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeInterface.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeInterface.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "false" +// "Generate overloaded method with default parameter value" "true" interface Test { void foo(int ii); } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeJavadoc.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeJavadoc.java index 76acc03eb3d5..267cdf9f901a 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeJavadoc.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeJavadoc.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded method with default parameter value" "true" class Test { /** * @param i diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeReturnValue.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeReturnValue.java index f77d174ad440..4df7057f4e31 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeReturnValue.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeReturnValue.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded method with default parameter value" "true" class Test { int foo(int ii){ return 1; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeTypeParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeTypeParams.java index 19e77d4724f4..e55000a24f37 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeTypeParams.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeTypeParams.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded method with default parameter value" "true" class Test { int foo(T ii, boolean... args){ return 1; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeVarargs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeVarargs.java index 865e86d13fd4..6ddbc5a9069c 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeVarargs.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/delegateWithDefaultValue/beforeVarargs.java @@ -1,4 +1,4 @@ -// "Generate delegated method with default parameter value" "true" +// "Generate overloaded method with default parameter value" "true" class Test { int foo(int ii, boolean... args){ return 1; diff --git a/resources-en/src/intentionDescriptions/DefineParamsDefaultValueAction/after.java.template b/resources-en/src/intentionDescriptions/DefineParamsDefaultValueAction/after.java.template index e14f067cdce2..5aeff4f6a7a5 100644 --- a/resources-en/src/intentionDescriptions/DefineParamsDefaultValueAction/after.java.template +++ b/resources-en/src/intentionDescriptions/DefineParamsDefaultValueAction/after.java.template @@ -2,7 +2,8 @@ class Test { void foo() { foo(|,); } - void foo(int a, int b){ + + void foo(int a, int b) { //do smth } } \ No newline at end of file diff --git a/resources-en/src/intentionDescriptions/DefineParamsDefaultValueAction/before.java.template b/resources-en/src/intentionDescriptions/DefineParamsDefaultValueAction/before.java.template index 90e1b2f320b2..967726ccb4de 100644 --- a/resources-en/src/intentionDescriptions/DefineParamsDefaultValueAction/before.java.template +++ b/resources-en/src/intentionDescriptions/DefineParamsDefaultValueAction/before.java.template @@ -1,5 +1,5 @@ class Test { - void foo(int a, int b){ + void foo(int a, int b) { //do smth } } \ No newline at end of file diff --git a/resources-en/src/intentionDescriptions/DefineParamsDefaultValueAction/description.html b/resources-en/src/intentionDescriptions/DefineParamsDefaultValueAction/description.html index 9d7a5b546eb4..2bd8b8ee307c 100644 --- a/resources-en/src/intentionDescriptions/DefineParamsDefaultValueAction/description.html +++ b/resources-en/src/intentionDescriptions/DefineParamsDefaultValueAction/description.html @@ -1,5 +1,5 @@ -This intention generates method which delegates to the current one setting the selected parameters with the default value. +Generates an overloaded method which delegates to the current one setting the selected parameters to the specified default values. diff --git a/resources-en/src/intentionDescriptions/DelegateWithDefaultParamValueIntentionAction/after.java.template b/resources-en/src/intentionDescriptions/DelegateWithDefaultParamValueIntentionAction/after.java.template index 97307fd767c3..8b1a0e1d4fe8 100644 --- a/resources-en/src/intentionDescriptions/DelegateWithDefaultParamValueIntentionAction/after.java.template +++ b/resources-en/src/intentionDescriptions/DelegateWithDefaultParamValueIntentionAction/after.java.template @@ -2,7 +2,8 @@ class Test { void foo(int a) { foo(a, |); } - void foo(int a, int b){ + + void foo(int a, int b) { //do smth } } \ No newline at end of file diff --git a/resources-en/src/intentionDescriptions/DelegateWithDefaultParamValueIntentionAction/before.java.template b/resources-en/src/intentionDescriptions/DelegateWithDefaultParamValueIntentionAction/before.java.template index 90e1b2f320b2..0ecad2088cdf 100644 --- a/resources-en/src/intentionDescriptions/DelegateWithDefaultParamValueIntentionAction/before.java.template +++ b/resources-en/src/intentionDescriptions/DelegateWithDefaultParamValueIntentionAction/before.java.template @@ -1,5 +1,5 @@ class Test { - void foo(int a, int b){ + void foo(int a, int b) { //do smth } } \ No newline at end of file diff --git a/resources-en/src/intentionDescriptions/DelegateWithDefaultParamValueIntentionAction/description.html b/resources-en/src/intentionDescriptions/DelegateWithDefaultParamValueIntentionAction/description.html index c476e38684df..821c26642038 100644 --- a/resources-en/src/intentionDescriptions/DelegateWithDefaultParamValueIntentionAction/description.html +++ b/resources-en/src/intentionDescriptions/DelegateWithDefaultParamValueIntentionAction/description.html @@ -1,5 +1,5 @@ -This intention generates method which delegates to the current one setting the selected parameter the default value. +Generates an overloaded method which delegates to the current one setting the selected parameter to the specified default value. From 220d8580674c193cec77a391fa089fa30697d73b Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 8 Aug 2015 23:08:54 +0200 Subject: [PATCH 03/99] IG: fix "Field accessed in both synchronized and unsynchronized contexts" inspection walking visitor problem --- .../ig/threading/VariableAccessVisitor.java | 16 ++++++++++------ ...AccessedSynchronizedAndUnsynchronized.java | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/VariableAccessVisitor.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/VariableAccessVisitor.java index 3c7f63982889..6060e3cc953a 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/VariableAccessVisitor.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/VariableAccessVisitor.java @@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.HashSet; import java.util.Set; +import java.util.Stack; class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor { @@ -44,6 +45,7 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor { private final Set usedMethods = new HashSet(); private boolean m_inInitializer; private int m_inSynchronizedContextCount; + private final Stack contextStack = new Stack(); private boolean privateMethodUsagesCalculated; private final boolean countGettersAndSetters; @@ -56,14 +58,16 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor { public void visitClass(PsiClass classToVisit) { calculatePrivateMethodUsagesIfNecessary(); if (!classToVisit.equals(aClass)) { - m_inSynchronizedContextCount -= 1000; + contextStack.push(m_inSynchronizedContextCount); + m_inSynchronizedContextCount = 0; } super.visitClass(classToVisit); } @Override public void visitLambdaExpression(PsiLambdaExpression expression) { - m_inSynchronizedContextCount -= 1000; + contextStack.push(m_inSynchronizedContextCount); + m_inSynchronizedContextCount = 0; super.visitLambdaExpression(expression); } @@ -127,7 +131,7 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor { @Override public void visitCodeBlock(PsiCodeBlock block) { if (block.getParent() instanceof PsiSynchronizedStatement) { - m_inSynchronizedContextCount ++; + m_inSynchronizedContextCount++; } super.visitCodeBlock(block); } @@ -137,7 +141,7 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor { public void visitAssertStatement(PsiAssertStatement statement) { final PsiExpression condition = statement.getAssertCondition(); if (SynchronizationUtil.isCallToHoldsLock(condition)) { - m_inSynchronizedContextCount ++; + m_inSynchronizedContextCount++; PsiElement codeBlock = statement.getParent(); if (codeBlock != null) { codeBlock.putUserData(CODE_BLOCK_CONTAINS_HOLDS_LOCK_CALL, true); @@ -349,11 +353,11 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor { m_inInitializer = false; } if (element instanceof PsiClass && !element.equals(aClass) || element instanceof PsiLambdaExpression) { - m_inSynchronizedContextCount += 1000; + m_inSynchronizedContextCount = contextStack.pop(); } if (element instanceof PsiCodeBlock && element.getParent() instanceof PsiSynchronizedStatement || element instanceof PsiMethod && ((PsiMethod)element).hasModifierProperty(PsiModifier.SYNCHRONIZED)) { - m_inSynchronizedContextCount --; + m_inSynchronizedContextCount--; } if (element.getUserData(CODE_BLOCK_CONTAINS_HOLDS_LOCK_CALL) != null) { m_inSynchronizedContextCount --; diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/threading/field_accessed_synchronized_and_unsynchronized/FieldAccessedSynchronizedAndUnsynchronized.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/threading/field_accessed_synchronized_and_unsynchronized/FieldAccessedSynchronizedAndUnsynchronized.java index a46cd52de9df..1011ef5c92c9 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/threading/field_accessed_synchronized_and_unsynchronized/FieldAccessedSynchronizedAndUnsynchronized.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/threading/field_accessed_synchronized_and_unsynchronized/FieldAccessedSynchronizedAndUnsynchronized.java @@ -54,4 +54,23 @@ class Test { synchronized void setObject(Object object) { this.object = object; } +} +class AAAAAAA { + + private boolean ready; + private final Object LOCK = new Object(); + + void h(int i) { + synchronized (LOCK) { + ready = true; + } + new Runnable () { + @Override + public void run() { + synchronized (LOCK) { + ready = false; + } + } + }; + } } \ No newline at end of file From 237f1e4c88e52fb6c1e33f67a25518d8bc4d322f Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Sun, 9 Aug 2015 01:16:11 +0200 Subject: [PATCH 04/99] duplicated code in type hierarchy --- .../python/hierarchy/PyTypeHierarchyBrowser.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/python/src/com/jetbrains/python/hierarchy/PyTypeHierarchyBrowser.java b/python/src/com/jetbrains/python/hierarchy/PyTypeHierarchyBrowser.java index 127630d7e73c..b066f303be4b 100644 --- a/python/src/com/jetbrains/python/hierarchy/PyTypeHierarchyBrowser.java +++ b/python/src/com/jetbrains/python/hierarchy/PyTypeHierarchyBrowser.java @@ -19,13 +19,8 @@ import com.intellij.ide.hierarchy.HierarchyNodeDescriptor; import com.intellij.ide.hierarchy.HierarchyTreeStructure; import com.intellij.ide.hierarchy.TypeHierarchyBrowserBase; import com.intellij.ide.util.treeView.NodeDescriptor; -import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.ActionPlaces; -import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiElement; -import com.intellij.ui.PopupHandler; import com.jetbrains.python.hierarchy.treestructures.PySubTypesHierarchyTreeStructure; import com.jetbrains.python.hierarchy.treestructures.PySuperTypesHierarchyTreeStructure; import com.jetbrains.python.hierarchy.treestructures.PyTypeHierarchyTreeStructure; @@ -59,8 +54,7 @@ public class PyTypeHierarchyBrowser extends TypeHierarchyBrowserBase { } protected void createTrees(@NotNull Map trees) { - ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction("PyTypeHierarchyPopupMenu"); - createTreeAndSetupCommonActions(trees, group); + createTreeAndSetupCommonActions(trees, "PyTypeHierarchyPopupMenu"); } @Nullable From 11576f44b95525eb00a21e28797fdff8a7ee84df Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 6 Aug 2015 11:18:16 +0200 Subject: [PATCH 05/99] =?UTF-8?q?get=20rid=20of=20FileBasedStorage.getFile?= =?UTF-8?q?Path=20=E2=80=94=20storageManager.expandMacros=20should=20be=20?= =?UTF-8?q?used=20instead=20(now=20it=20guaranteed=20that=20expanded=20pat?= =?UTF-8?q?h=20is=20system-independent)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../configuration-store-impl/src/ProjectStoreImpl.kt | 11 ++++------- .../com/intellij/openapi/module/impl/ModuleImpl.java | 2 +- .../components/impl/stores/FileBasedStorage.java | 9 ++------- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/platform/configuration-store-impl/src/ProjectStoreImpl.kt b/platform/configuration-store-impl/src/ProjectStoreImpl.kt index 4b028c73f10e..50cf54e49384 100644 --- a/platform/configuration-store-impl/src/ProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/ProjectStoreImpl.kt @@ -148,7 +148,7 @@ open class ProjectStoreImpl(override val project: ProjectImpl, pathMacroManager: return baseDir.getName().replace(":", "") } else { - var temp = PathUtilRt.getFileName(getProjectFileStorage().getFilePath()) + var temp = PathUtilRt.getFileName(getProjectFilePath()) val fileType = FileTypeManager.getInstance().getFileTypeByFileName(temp) if (fileType is ProjectFileType) { temp = temp.substring(0, temp.length() - fileType.getDefaultExtension().length() - 1) @@ -175,16 +175,13 @@ open class ProjectStoreImpl(override val project: ProjectImpl, pathMacroManager: override fun getProjectFile() = getProjectFileStorage().getVirtualFile() - override fun getProjectFilePath() = getProjectFileStorage().getFilePath() + override fun getProjectFilePath() = storageManager.expandMacros(StoragePathMacros.PROJECT_FILE) private fun getProjectFileStorage() = storageManager.getStateStorage(StoragePathMacros.PROJECT_FILE, RoamingType.PER_USER) as FileBasedStorage - override fun getWorkspaceFile() = workspaceStorage?.getVirtualFile() + override fun getWorkspaceFile() = (storageManager.getStateStorage(StoragePathMacros.WORKSPACE_FILE, RoamingType.DISABLED) as FileBasedStorage?)?.getVirtualFile() - override fun getWorkspaceFilePath() = workspaceStorage?.getFilePath() - - private val workspaceStorage: FileBasedStorage? - get() = storageManager.getStateStorage(StoragePathMacros.WORKSPACE_FILE, RoamingType.DISABLED) as FileBasedStorage? + override fun getWorkspaceFilePath() = storageManager.expandMacros(StoragePathMacros.WORKSPACE_FILE) override fun loadProjectFromTemplate(defaultProject: Project) { defaultProject.save() diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java index d2a3076dcb3e..809ebddc80e0 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java @@ -150,7 +150,7 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx @Override @NotNull public String getModuleFilePath() { - return getMainStorage(this).getFilePath(); + return ComponentsPackage.getStateStore(this).getStateStorageManager().expandMacros(StoragePathMacros.MODULE_FILE); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java index bc0cf171bee3..a440dd45cbd1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java @@ -23,12 +23,12 @@ import com.intellij.openapi.components.RoamingType; import com.intellij.openapi.components.StoragePathMacros; import com.intellij.openapi.components.TrackingPathMacroSubstitutor; import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.LineSeparator; -import com.intellij.util.PathUtil; import org.jdom.Element; import org.jdom.JDOMException; import org.jetbrains.annotations.NotNull; @@ -120,11 +120,6 @@ public class FileBasedStorage extends XmlElementStorage { return myFile; } - @NotNull - public String getFilePath() { - return PathUtil.toSystemIndependentName(myFile.getPath()); - } - @Override @Nullable protected Element loadLocalData() { @@ -207,6 +202,6 @@ public class FileBasedStorage extends XmlElementStorage { @Override public String toString() { - return getFilePath(); + return FileUtilRt.toSystemIndependentName(myFile.getPath()); } } From d858efd28ab04f9be5cf964f266edc17095e0925 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 6 Aug 2015 11:30:18 +0200 Subject: [PATCH 06/99] move field myBlockSavingTheContent to FileBasedStorage --- .../components/impl/stores/FileBasedStorage.java | 13 ++++++++++--- .../components/impl/stores/XmlElementStorage.java | 7 +------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java index a440dd45cbd1..9ec622040a71 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java @@ -44,6 +44,7 @@ public class FileBasedStorage extends XmlElementStorage { private File myFile; private volatile VirtualFile myCachedVirtualFile; private LineSeparator myLineSeparator; + private boolean myBlockSavingTheContent; public FileBasedStorage(@NotNull File file, @NotNull String fileSpec, @@ -83,6 +84,13 @@ public class FileBasedStorage extends XmlElementStorage { super(storageData); } + @Override + public void save() throws IOException { + if (!myBlockSavingTheContent) { + super.save(); + } + } + @Override protected void doSave(@Nullable Element element) throws IOException { if (myStreamProvider != null && myStreamProvider.getEnabled()) { @@ -157,9 +165,8 @@ public class FileBasedStorage extends XmlElementStorage { LOG.info(e); } new Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, "Load Settings", - "Cannot load settings from file '" + - myFile + "': " + - (e == null ? "content truncated" : e.getMessage()) + "\n" + + "Cannot load settings from file '" + myFile + "': " + + (contentTruncated ? "content truncated" : e.getMessage()) + "\n" + (myBlockSavingTheContent ? "Please correct the file content" : "File content will be recreated"), NotificationType.WARNING).notify(null); } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java index 52fa97fea64a..3783758be6f0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java @@ -34,7 +34,6 @@ public abstract class XmlElementStorage extends StateStorageBase { @NotNull protected final String myRootElementName; protected final StreamProvider myStreamProvider; protected final String myFileSpec; - protected boolean myBlockSavingTheContent = false; protected final RoamingType myRoamingType; @@ -185,11 +184,7 @@ public abstract class XmlElementStorage extends StateStorageBase { } @Override - public final void save() throws IOException { - if (myBlockSavingTheContent) { - return; - } - + public void save() throws IOException { StorageData storageData = myCopiedStorageData; if (storageData == null) { storageData = myOriginalStorageData; From 3d1dba174574754e986c561d12a207629e22d2b1 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 6 Aug 2015 11:46:22 +0200 Subject: [PATCH 07/99] hide FileBasedStorage implementation --- .../src/DefaultProjectStoreImpl.kt | 4 +- .../src/ProjectStoreImpl.kt | 1 - .../src/StateStorageManagerImpl.kt | 2 +- .../src/StorageVirtualFileTracker.kt | 1 - .../DefaultProjectStorage.java | 1 - .../configurationStore}/FileBasedStorage.java | 8 +++- .../testSrc/ModuleStoreTest.kt | 1 - .../openapi/module/impl/ModuleImpl.java | 6 +-- .../components/impl/stores/FileStorage.java | 37 +++++++++++++++++++ .../impl/stores/StateStorageManager.java | 2 +- .../project/impl/ProjectManagerImpl.java | 4 +- plugins/settings-repository/src/sync.kt | 6 ++- 12 files changed, 56 insertions(+), 17 deletions(-) rename platform/{platform-impl/src/com/intellij/openapi/components/impl/stores => configuration-store-impl/src/com/intellij/configurationStore}/FileBasedStorage.java (97%) create mode 100644 platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileStorage.java diff --git a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt index ee55c711c0fc..207f179f114c 100644 --- a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt @@ -17,7 +17,7 @@ package com.intellij.configurationStore import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.* -import com.intellij.openapi.components.impl.stores.FileBasedStorage +import com.intellij.openapi.components.impl.stores.FileStorage import com.intellij.openapi.components.impl.stores.StateStorageManager import com.intellij.openapi.components.impl.stores.StreamProvider import com.intellij.openapi.project.Project @@ -48,7 +48,7 @@ class DefaultProjectStoreImpl(override val project: ProjectImpl, private val pat override fun getStateStorage(fileSpec: String, roamingType: RoamingType) = storage - override fun getCachedFileStateStorages(changed: Collection, deleted: Collection): Couple> = Couple(emptyList(), emptyList()) + override fun getCachedFileStateStorages(changed: Collection, deleted: Collection): Couple> = Couple(emptyList(), emptyList()) override fun startExternalization(): StateStorageManager.ExternalizationSession? { val externalizationSession = storage.startExternalization() diff --git a/platform/configuration-store-impl/src/ProjectStoreImpl.kt b/platform/configuration-store-impl/src/ProjectStoreImpl.kt index 50cf54e49384..11fb7cd0c0a5 100644 --- a/platform/configuration-store-impl/src/ProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/ProjectStoreImpl.kt @@ -23,7 +23,6 @@ import com.intellij.openapi.application.ReadAction import com.intellij.openapi.application.invokeAndWaitIfNeed import com.intellij.openapi.components.* import com.intellij.openapi.components.StateStorage.SaveSession -import com.intellij.openapi.components.impl.stores.FileBasedStorage import com.intellij.openapi.components.impl.stores.IComponentStore import com.intellij.openapi.components.impl.stores.IProjectStore import com.intellij.openapi.fileTypes.FileTypeManager diff --git a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt index 945e7f3ae16f..d74762d4ee1e 100644 --- a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt +++ b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt @@ -155,7 +155,7 @@ open class StateStorageManagerImpl(protected val rootTagName: String, override final fun getCachedFileStateStorages(changed: MutableCollection, deleted: MutableCollection) = storageLock.withLock { Couple.of(getCachedFileStorages(changed), getCachedFileStorages(deleted)) } - fun getCachedFileStorages(fileSpecs: Collection): Collection { + fun getCachedFileStorages(fileSpecs: Collection): Collection { if (fileSpecs.isEmpty()) { return emptyList() } diff --git a/platform/configuration-store-impl/src/StorageVirtualFileTracker.kt b/platform/configuration-store-impl/src/StorageVirtualFileTracker.kt index 2edb9ac11edf..7b6e811e2081 100644 --- a/platform/configuration-store-impl/src/StorageVirtualFileTracker.kt +++ b/platform/configuration-store-impl/src/StorageVirtualFileTracker.kt @@ -2,7 +2,6 @@ package com.intellij.configurationStore import com.intellij.openapi.components.StateStorage import com.intellij.openapi.components.impl.stores.DirectoryBasedStorage -import com.intellij.openapi.components.impl.stores.FileBasedStorage import com.intellij.openapi.components.impl.stores.StateStorageManager import com.intellij.openapi.components.impl.stores.StorageUtil import com.intellij.openapi.util.text.StringUtilRt diff --git a/platform/configuration-store-impl/src/com/intellij/configurationStore/DefaultProjectStorage.java b/platform/configuration-store-impl/src/com/intellij/configurationStore/DefaultProjectStorage.java index 11b877f959a4..28a4ab5186b9 100644 --- a/platform/configuration-store-impl/src/com/intellij/configurationStore/DefaultProjectStorage.java +++ b/platform/configuration-store-impl/src/com/intellij/configurationStore/DefaultProjectStorage.java @@ -2,7 +2,6 @@ package com.intellij.configurationStore; import com.intellij.openapi.components.PathMacroManager; import com.intellij.openapi.components.RoamingType; -import com.intellij.openapi.components.impl.stores.FileBasedStorage; import com.intellij.openapi.components.impl.stores.StorageData; import org.jdom.Element; import org.jetbrains.annotations.NotNull; diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java b/platform/configuration-store-impl/src/com/intellij/configurationStore/FileBasedStorage.java similarity index 97% rename from platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java rename to platform/configuration-store-impl/src/com/intellij/configurationStore/FileBasedStorage.java index 9ec622040a71..2d50a4e31ed8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java +++ b/platform/configuration-store-impl/src/com/intellij/configurationStore/FileBasedStorage.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.components.impl.stores; +package com.intellij.configurationStore; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; @@ -22,6 +22,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.RoamingType; import com.intellij.openapi.components.StoragePathMacros; import com.intellij.openapi.components.TrackingPathMacroSubstitutor; +import com.intellij.openapi.components.impl.stores.*; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.text.StringUtil; @@ -40,7 +41,7 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.util.Set; -public class FileBasedStorage extends XmlElementStorage { +public class FileBasedStorage extends XmlElementStorage implements FileStorage { private File myFile; private volatile VirtualFile myCachedVirtualFile; private LineSeparator myLineSeparator; @@ -62,6 +63,7 @@ public class FileBasedStorage extends XmlElementStorage { } // we never set io file to null + @Override public void setFile(@Nullable VirtualFile file, @Nullable File ioFileIfChanged) { myCachedVirtualFile = file; if (ioFileIfChanged != null) { @@ -114,6 +116,7 @@ public class FileBasedStorage extends XmlElementStorage { } } + @Override @Nullable public VirtualFile getVirtualFile() { VirtualFile virtualFile = myCachedVirtualFile; @@ -123,6 +126,7 @@ public class FileBasedStorage extends XmlElementStorage { return virtualFile; } + @Override @NotNull public File getFile() { return myFile; diff --git a/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt b/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt index 17e7acceb4c0..4e285ffd2c18 100644 --- a/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt @@ -7,7 +7,6 @@ import com.intellij.openapi.application.invokeAndWaitIfNeed import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.components.RoamingType import com.intellij.openapi.components.StoragePathMacros -import com.intellij.openapi.components.impl.stores.FileBasedStorage import com.intellij.openapi.components.impl.stores.StoreUtil import com.intellij.openapi.components.stateStore import com.intellij.openapi.module.ModifiableModuleModel diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java index 809ebddc80e0..c3530848b03f 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java @@ -22,7 +22,7 @@ import com.intellij.openapi.application.impl.ApplicationInfoImpl; import com.intellij.openapi.components.*; import com.intellij.openapi.components.impl.ModuleServiceManagerImpl; import com.intellij.openapi.components.impl.PlatformComponentManagerImpl; -import com.intellij.openapi.components.impl.stores.FileBasedStorage; +import com.intellij.openapi.components.impl.stores.FileStorage; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.AreaInstance; import com.intellij.openapi.extensions.ExtensionPointName; @@ -83,8 +83,8 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx } @NotNull - private static FileBasedStorage getMainStorage(@NotNull Module module) { - return (FileBasedStorage)ComponentsPackage.getStateStore(module).getStateStorageManager().getStateStorage(StoragePathMacros.MODULE_FILE, RoamingType.PER_USER); + private static FileStorage getMainStorage(@NotNull Module module) { + return (FileStorage)ComponentsPackage.getStateStore(module).getStateStorageManager().getStateStorage(StoragePathMacros.MODULE_FILE, RoamingType.PER_USER); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileStorage.java new file mode 100644 index 000000000000..06e2d00d3236 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileStorage.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.components.impl.stores; + +import com.intellij.openapi.components.StateStorage; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; + +public interface FileStorage extends StateStorage { + @Nullable + VirtualFile getVirtualFile(); + + @NotNull + File getFile(); + + // todo remove + StorageData getStorageData(); + + // todo remove + void setFile(@Nullable VirtualFile file, @Nullable File ioFileIfChanged); +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java index b9f50f389b0e..dc631ec0a3f2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java @@ -38,7 +38,7 @@ public interface StateStorageManager { StateStorage getStateStorage(@NotNull String fileSpec, @NotNull RoamingType roamingType); @NotNull - Couple> getCachedFileStateStorages(@NotNull Collection changed, @NotNull Collection deleted); + Couple> getCachedFileStateStorages(@NotNull Collection changed, @NotNull Collection deleted); /** * Rename file diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java index bdbf1b57368a..17117b22af2a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java @@ -695,8 +695,8 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable { public void saveChangedProjectFile(@NotNull VirtualFile file, @NotNull Project project) { StateStorageManager storageManager = ComponentsPackage.getStateStore(project).getStateStorageManager(); String fileSpec = storageManager.collapseMacros(file.getPath()); - Couple> storages = storageManager.getCachedFileStateStorages(Collections.singletonList(fileSpec), Collections.emptyList()); - FileBasedStorage storage = ContainerUtil.getFirstItem(storages.first); + Couple> storages = storageManager.getCachedFileStateStorages(Collections.singletonList(fileSpec), Collections.emptyList()); + FileStorage storage = ContainerUtil.getFirstItem(storages.first); // if empty, so, storage is not yet loaded, so, we don't have to reload if (storage != null) { registerProjectToReload(project, storage); diff --git a/plugins/settings-repository/src/sync.kt b/plugins/settings-repository/src/sync.kt index bfdc57dd3f7d..bd54f22bfdfc 100644 --- a/plugins/settings-repository/src/sync.kt +++ b/plugins/settings-repository/src/sync.kt @@ -16,10 +16,12 @@ package org.jetbrains.settingsRepository import com.intellij.configurationStore.ComponentStoreImpl +import com.intellij.configurationStore.FileBasedStorage import com.intellij.configurationStore.SchemeManagerFactoryBase import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.WriteAction import com.intellij.openapi.application.impl.ApplicationImpl +import com.intellij.openapi.components.impl.stores.FileStorage import com.intellij.openapi.components.StateStorage import com.intellij.openapi.components.impl.stores.FileBasedStorage import com.intellij.openapi.components.impl.stores.IComponentStore @@ -183,10 +185,10 @@ private fun updateStoragesFromStreamProvider(store: IComponentStore, updateResul })!! } -private fun updateStateStorage(changedComponentNames: Set, stateStorages: Collection, deleted: Boolean) { +private fun updateStateStorage(changedComponentNames: Set, stateStorages: Collection, deleted: Boolean) { for (stateStorage in stateStorages) { try { - stateStorage.updatedFromStreamProvider(changedComponentNames, deleted) + (stateStorage as FileBasedStorage).updatedFromStreamProvider(changedComponentNames, deleted) } catch (e: Throwable) { LOG.error(e) From ed04d7e805c78f96c9a80c789716ad6950c5048b Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 6 Aug 2015 11:54:45 +0200 Subject: [PATCH 08/99] move XmlElementStorage to configuration-store module --- .../com/intellij/configurationStore}/XmlElementStorage.java | 3 ++- .../configurationStore}/ProjectStoreBaseTestCase.java | 2 +- .../configurationStore}/ProjectStoreImplIdeaDirTest.java | 2 +- .../configurationStore}/ProjectStoreImplIprFileTest.java | 2 +- .../intellij/configurationStore}/XmlElementStorageTest.java | 3 +-- .../openapi/components/impl/stores/SaveSessionBase.java | 2 +- .../openapi/components/impl/stores/StorageData.java | 6 +++--- 7 files changed, 10 insertions(+), 10 deletions(-) rename platform/{platform-impl/src/com/intellij/openapi/components/impl/stores => configuration-store-impl/src/com/intellij/configurationStore}/XmlElementStorage.java (98%) rename platform/{platform-tests/testSrc/com/intellij/openapi/components/impl => configuration-store-impl/testSrc/com/intellij/configurationStore}/ProjectStoreBaseTestCase.java (98%) rename platform/{platform-tests/testSrc/com/intellij/openapi/components/impl => configuration-store-impl/testSrc/com/intellij/configurationStore}/ProjectStoreImplIdeaDirTest.java (97%) rename platform/{platform-tests/testSrc/com/intellij/openapi/components/impl => configuration-store-impl/testSrc/com/intellij/configurationStore}/ProjectStoreImplIprFileTest.java (96%) rename platform/{platform-tests/testSrc/com/intellij/openapi/components/impl => configuration-store-impl/testSrc/com/intellij/configurationStore}/XmlElementStorageTest.java (97%) diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java b/platform/configuration-store-impl/src/com/intellij/configurationStore/XmlElementStorage.java similarity index 98% rename from platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java rename to platform/configuration-store-impl/src/com/intellij/configurationStore/XmlElementStorage.java index 3783758be6f0..a83037add451 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java +++ b/platform/configuration-store-impl/src/com/intellij/configurationStore/XmlElementStorage.java @@ -13,10 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.components.impl.stores; +package com.intellij.configurationStore; import com.intellij.openapi.components.RoamingType; import com.intellij.openapi.components.TrackingPathMacroSubstitutor; +import com.intellij.openapi.components.impl.stores.*; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; import com.intellij.util.containers.ContainerUtil; diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ProjectStoreBaseTestCase.java b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreBaseTestCase.java similarity index 98% rename from platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ProjectStoreBaseTestCase.java rename to platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreBaseTestCase.java index 3e9d4bd380bf..f23116183908 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ProjectStoreBaseTestCase.java +++ b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreBaseTestCase.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.components.impl; +package com.intellij.configurationStore; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.State; diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ProjectStoreImplIdeaDirTest.java b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreImplIdeaDirTest.java similarity index 97% rename from platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ProjectStoreImplIdeaDirTest.java rename to platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreImplIdeaDirTest.java index c408ec21e794..553b46f9f1a1 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ProjectStoreImplIdeaDirTest.java +++ b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreImplIdeaDirTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.components.impl; +package com.intellij.configurationStore; import com.intellij.openapi.components.ComponentsPackage; import com.intellij.openapi.project.Project; diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ProjectStoreImplIprFileTest.java b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreImplIprFileTest.java similarity index 96% rename from platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ProjectStoreImplIprFileTest.java rename to platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreImplIprFileTest.java index 1a732c2fab3a..24328b4da88c 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ProjectStoreImplIprFileTest.java +++ b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreImplIprFileTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.components.impl; +package com.intellij.configurationStore; import com.intellij.openapi.components.ComponentsPackage; import com.intellij.openapi.project.ex.ProjectEx; diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/XmlElementStorageTest.java b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/XmlElementStorageTest.java similarity index 97% rename from platform/platform-tests/testSrc/com/intellij/openapi/components/impl/XmlElementStorageTest.java rename to platform/configuration-store-impl/testSrc/com/intellij/configurationStore/XmlElementStorageTest.java index 001361010703..352eafcb4b09 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/XmlElementStorageTest.java +++ b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/XmlElementStorageTest.java @@ -13,14 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.components.impl; +package com.intellij.configurationStore; import com.intellij.openapi.Disposable; import com.intellij.openapi.components.RoamingType; import com.intellij.openapi.components.StateStorage; import com.intellij.openapi.components.TrackingPathMacroSubstitutor; import com.intellij.openapi.components.impl.stores.StorageData; -import com.intellij.openapi.components.impl.stores.XmlElementStorage; import com.intellij.openapi.util.Disposer; import com.intellij.testFramework.LightPlatformTestCase; import org.jdom.Element; diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/SaveSessionBase.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/SaveSessionBase.java index 63e5b3e85b8f..344d589102aa 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/SaveSessionBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/SaveSessionBase.java @@ -26,7 +26,7 @@ import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -abstract class SaveSessionBase implements StateStorage.SaveSession, StateStorage.ExternalizationSession, SafeWriteRequestor { +public abstract class SaveSessionBase implements StateStorage.SaveSession, StateStorage.ExternalizationSession, SafeWriteRequestor { private SkipDefaultsSerializationFilter serializationFilter; @SuppressWarnings("deprecation") diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java index 3d792dbd86d7..7bd082c75e87 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java @@ -107,7 +107,7 @@ public class StorageData extends StorageDataBase { } @Nullable - protected Element save(@NotNull Map newLiveStates) throws IOException { + public Element save(@NotNull Map newLiveStates) throws IOException { if (myStates.isEmpty()) { return null; } @@ -154,7 +154,7 @@ public class StorageData extends StorageDataBase { } @Nullable - static StorageData setStateAndCloneIfNeed(@NotNull String componentName, @Nullable Element newState, @NotNull StorageData storageData, @NotNull Map newLiveStates) { + public static StorageData setStateAndCloneIfNeed(@NotNull String componentName, @Nullable Element newState, @NotNull StorageData storageData, @NotNull Map newLiveStates) { Object oldState = storageData.myStates.get(componentName); if (newState == null || JDOMUtil.isEmpty(newState)) { if (oldState == null) { @@ -189,7 +189,7 @@ public class StorageData extends StorageDataBase { } @Nullable - final Object setState(@NotNull String componentName, @Nullable Element newState, @NotNull Map newLiveStates) { + public final Object setState(@NotNull String componentName, @Nullable Element newState, @NotNull Map newLiveStates) { if (newState == null || JDOMUtil.isEmpty(newState)) { return myStates.remove(componentName); } From 67a448b2fb0ec34f07261f2dcfeceed9315b8a64 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 6 Aug 2015 17:40:53 +0200 Subject: [PATCH 09/99] FileStorage in kotlin, thread-safe StateStorageBase.getStorageData (initial, will be addressed and tested later) --- .../src/BaseFileConfigurableStoreImpl.kt | 10 +- .../src/DefaultProjectStoreImpl.kt | 21 ++ .../src/ModuleFileData.kt | 2 +- .../src/ModuleStateStorageManager.kt | 2 +- .../src/ProjectStateStorageManager.kt | 2 +- .../src/StateStorageManagerImpl.kt | 21 +- .../DefaultProjectStorage.java | 45 --- .../DefaultStorageAnnotation.java | 5 - .../configurationStore/FileBasedStorage.java | 243 ++++++---------- .../configurationStore/XmlElementStorage.java | 271 ++++++++---------- .../testSrc/MockStreamProvider.kt | 2 - .../XmlElementStorageTest.java | 151 ---------- .../XmlElementStorageTest.kt | 65 +++++ .../roots/impl/storage/ClasspathStorage.java | 10 +- .../impl/stores/DirectoryBasedStorage.java | 16 +- .../impl/stores/StateStorageBase.java | 24 +- .../components/impl/stores/StorageUtil.java | 9 - .../components/impl/stores/StreamProvider.kt | 5 - .../intellij/openapi/components/Storage.java | 3 - .../com/intellij/core/CoreProjectLoader.java | 4 +- .../impl/stores/DirectoryStorageData.java | 9 +- .../components/impl/stores/StorageData.java | 27 +- .../impl/stores/StorageDataBase.java | 22 +- plugins/settings-repository/src/sync.kt | 9 +- 24 files changed, 374 insertions(+), 604 deletions(-) delete mode 100644 platform/configuration-store-impl/src/com/intellij/configurationStore/DefaultProjectStorage.java delete mode 100644 platform/configuration-store-impl/testSrc/com/intellij/configurationStore/XmlElementStorageTest.java create mode 100644 platform/configuration-store-impl/testSrc/com/intellij/configurationStore/XmlElementStorageTest.kt diff --git a/platform/configuration-store-impl/src/BaseFileConfigurableStoreImpl.kt b/platform/configuration-store-impl/src/BaseFileConfigurableStoreImpl.kt index 4dac9820e73c..b45082f19b70 100644 --- a/platform/configuration-store-impl/src/BaseFileConfigurableStoreImpl.kt +++ b/platform/configuration-store-impl/src/BaseFileConfigurableStoreImpl.kt @@ -19,6 +19,7 @@ import com.intellij.openapi.components.PathMacroManager import com.intellij.openapi.components.PathMacroSubstitutor import com.intellij.openapi.components.impl.stores.StorageData import org.jdom.Element +import org.jetbrains.annotations.NotNull import kotlin.properties.Delegates abstract class BaseFileConfigurableStoreImpl(protected val pathMacroManager: PathMacroManager) : ComponentStoreImpl() { @@ -39,7 +40,7 @@ open class ProjectStorageData : StorageData { private var version = CURRENT_FORMAT_VERSION - constructor(rootElementName: String) : super(rootElementName) { + constructor() : super() { } protected constructor(storageData: ProjectStorageData) : super(storageData) { @@ -51,11 +52,8 @@ open class ProjectStorageData : StorageData { version = rootElement.getAttributeValue(VERSION_OPTION)?.toInt() ?: CURRENT_FORMAT_VERSION } - override fun save(newLiveStates: Map): Element { - var root = super.save(newLiveStates) - if (root == null) { - root = Element(myRootElementName) - } + override fun save(newLiveStates: Map, rootElementName: String): Element { + val root = super.save(newLiveStates, rootElementName) ?: Element(rootElementName) writeOptions(root) return root } diff --git a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt index 207f179f114c..de3fe586b195 100644 --- a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt @@ -19,11 +19,13 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.* import com.intellij.openapi.components.impl.stores.FileStorage import com.intellij.openapi.components.impl.stores.StateStorageManager +import com.intellij.openapi.components.impl.stores.StorageData import com.intellij.openapi.components.impl.stores.StreamProvider import com.intellij.openapi.project.Project import com.intellij.openapi.project.impl.ProjectImpl import com.intellij.openapi.util.Couple import com.intellij.util.containers.ContainerUtil +import org.jdom.Element import java.io.File import kotlin.properties.Delegates @@ -38,6 +40,25 @@ class DefaultProjectStoreImpl(override val project: ProjectImpl, private val pat private val storage by Delegates.lazy { DefaultProjectStorage(File(ApplicationManager.getApplication().stateStore.getStateStorageManager().expandMacros(FILE_SPEC)), FILE_SPEC, pathMacroManager) } + private class DefaultProjectStorage(file: File, fileSpec: String, pathMacroManager: PathMacroManager) : FileBasedStorage(file, fileSpec, "defaultProject", pathMacroManager.createTrackingSubstitutor(), RoamingType.DISABLED) { + override public fun loadLocalData(): Element? { + val element = super.loadLocalData() ?: return null + try { + return element.getChild("component").getChild("defaultProject") + } + catch (e: NullPointerException) { + LOG.warn("Cannot read default project") + return null + } + } + + override fun createSaveSession(storageData: StorageData) = object : FileBasedStorage.FileSaveSession(storageData, this) { + override fun saveLocally(element: Element?) { + super.saveLocally(Element("application").addContent(Element("component").setAttribute("name", "ProjectManager").addContent(element))) + } + } + } + private val storageManager = object : StateStorageManager { override fun rename(path: String, newName: String) { } diff --git a/platform/configuration-store-impl/src/ModuleFileData.kt b/platform/configuration-store-impl/src/ModuleFileData.kt index 6a5a74e48b10..0eafe980b971 100644 --- a/platform/configuration-store-impl/src/ModuleFileData.kt +++ b/platform/configuration-store-impl/src/ModuleFileData.kt @@ -29,7 +29,7 @@ class ModuleFileData : ProjectStorageData, OptionManager { override fun isDirty() = dirty - public constructor(rootElementName: String) : super(rootElementName) { + public constructor() : super() { options = TreeMap() } diff --git a/platform/configuration-store-impl/src/ModuleStateStorageManager.kt b/platform/configuration-store-impl/src/ModuleStateStorageManager.kt index 7938aede9c78..a59b13b3dbf3 100644 --- a/platform/configuration-store-impl/src/ModuleStateStorageManager.kt +++ b/platform/configuration-store-impl/src/ModuleStateStorageManager.kt @@ -29,7 +29,7 @@ import com.intellij.util.PathUtilRt import com.intellij.util.containers.ContainerUtil class ModuleStateStorageManager(macroSubstitutor: TrackingPathMacroSubstitutor, module: Module) : StateStorageManagerImpl("module", macroSubstitutor, module) { - override fun createStorageData(fileSpec: String) = ModuleFileData(rootTagName) + override fun createStorageData(fileSpec: String) = ModuleFileData() override fun startExternalization() = MyStateStorageManagerExternalizationSession(this) diff --git a/platform/configuration-store-impl/src/ProjectStateStorageManager.kt b/platform/configuration-store-impl/src/ProjectStateStorageManager.kt index dcb6814139fd..7aaea45ede0a 100644 --- a/platform/configuration-store-impl/src/ProjectStateStorageManager.kt +++ b/platform/configuration-store-impl/src/ProjectStateStorageManager.kt @@ -22,7 +22,7 @@ import com.intellij.openapi.components.TrackingPathMacroSubstitutor import com.intellij.openapi.project.impl.ProjectImpl class ProjectStateStorageManager(macroSubstitutor: TrackingPathMacroSubstitutor, private val project: ProjectImpl) : StateStorageManagerImpl("project", macroSubstitutor, project) { - override fun createStorageData(fileSpec: String) = ProjectStorageData(rootTagName) + override fun createStorageData(fileSpec: String) = ProjectStorageData() override fun getOldStorageSpec(component: Any, componentName: String, operation: StateStorageOperation): String? { val workspace = project.isWorkspaceComponent(component.javaClass) diff --git a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt index d74762d4ee1e..3ab69bf21d90 100644 --- a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt +++ b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt @@ -46,7 +46,7 @@ import kotlin.reflect.jvm.java /** * If componentManager not specified, storage will not add file tracker (see VirtualFileTracker) */ -open class StateStorageManagerImpl(protected val rootTagName: String, +open class StateStorageManagerImpl(private val rootTagName: String, private val pathMacroSubstitutor: TrackingPathMacroSubstitutor? = null, val componentManager: ComponentManager? = null, private val virtualFileTracker: StorageVirtualFileTracker? = StateStorageManagerImpl.createDefaultVirtualTracker(componentManager) ) : StateStorageManager { @@ -214,15 +214,16 @@ open class StateStorageManagerImpl(protected val rootTagName: String, private class MyDirectoryStorage(override val storageManager: StateStorageManagerImpl, file: File, splitter: StateSplitter) : DirectoryBasedStorage(storageManager.pathMacroSubstitutor, file, splitter), StorageVirtualFileTracker.TrackedStorage private class MyFileStorage(override val storageManager: StateStorageManagerImpl, - file: File, - fileSpec: String, - rootElementName: String, - roamingType: RoamingType? = null, - pathMacroManager: TrackingPathMacroSubstitutor? = null, - streamProvider: StreamProvider? = null) : FileBasedStorage(file, fileSpec, roamingType, pathMacroManager, rootElementName, streamProvider), StorageVirtualFileTracker.TrackedStorage { - override fun createStorageData() = storageManager.createStorageData(myFileSpec) + file: File, + fileSpec: String, + rootElementName: String, + roamingType: RoamingType? = null, + pathMacroManager: TrackingPathMacroSubstitutor? = null, + streamProvider: StreamProvider? = null) : FileBasedStorage(file, fileSpec, rootElementName, pathMacroManager, roamingType, streamProvider), StorageVirtualFileTracker.TrackedStorage { + override val isUseXmlProlog: Boolean + get() = storageManager.isUseXmlProlog - override fun isUseXmlProlog() = storageManager.isUseXmlProlog + override fun createStorageData() = storageManager.createStorageData(fileSpec) } private fun String.normalizePath(): String { @@ -272,7 +273,7 @@ open class StateStorageManagerImpl(protected val rootTagName: String, protected open fun getMacroSubstitutor(fileSpec: String): TrackingPathMacroSubstitutor? = pathMacroSubstitutor - protected open fun createStorageData(fileSpec: String): StorageData = StorageData(rootTagName) + protected open fun createStorageData(fileSpec: String): StorageData = StorageData() override final fun expandMacros(path: String): String { // replacement can contains $ (php tests), so, this check must be performed before expand diff --git a/platform/configuration-store-impl/src/com/intellij/configurationStore/DefaultProjectStorage.java b/platform/configuration-store-impl/src/com/intellij/configurationStore/DefaultProjectStorage.java deleted file mode 100644 index 28a4ab5186b9..000000000000 --- a/platform/configuration-store-impl/src/com/intellij/configurationStore/DefaultProjectStorage.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.intellij.configurationStore; - -import com.intellij.openapi.components.PathMacroManager; -import com.intellij.openapi.components.RoamingType; -import com.intellij.openapi.components.impl.stores.StorageData; -import org.jdom.Element; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.File; -import java.io.IOException; - -public class DefaultProjectStorage extends FileBasedStorage { - public DefaultProjectStorage(@NotNull File file, @NotNull String fileSpec, PathMacroManager pathMacroManager) { - super(file, fileSpec, RoamingType.DISABLED, pathMacroManager.createTrackingSubstitutor(), "defaultProject", null); - } - - @Nullable - @Override - protected Element loadLocalData() { - Element element = super.loadLocalData(); - if (element == null) { - return null; - } - - try { - return element.getChild("component").getChild("defaultProject"); - } - catch (NullPointerException e) { - LOG.warn("Cannot read default project"); - return null; - } - } - - @NotNull - @Override - protected XmlElementStorageSaveSession createSaveSession(@NotNull StorageData storageData) { - return new FileSaveSession(storageData) { - @Override - protected void doSave(@Nullable Element element) throws IOException { - super.doSave(new Element("application").addContent(new Element("component").setAttribute("name", "ProjectManager").addContent(element))); - } - }; - } -} \ No newline at end of file diff --git a/platform/configuration-store-impl/src/com/intellij/configurationStore/DefaultStorageAnnotation.java b/platform/configuration-store-impl/src/com/intellij/configurationStore/DefaultStorageAnnotation.java index b9b89f475341..c06bad4fc0ad 100644 --- a/platform/configuration-store-impl/src/com/intellij/configurationStore/DefaultStorageAnnotation.java +++ b/platform/configuration-store-impl/src/com/intellij/configurationStore/DefaultStorageAnnotation.java @@ -12,11 +12,6 @@ public final class DefaultStorageAnnotation implements Storage { return "___Default___"; } - @Override - public boolean isDefault() { - return true; - } - @Override public String file() { return StoragePathMacros.PROJECT_FILE; diff --git a/platform/configuration-store-impl/src/com/intellij/configurationStore/FileBasedStorage.java b/platform/configuration-store-impl/src/com/intellij/configurationStore/FileBasedStorage.java index 2d50a4e31ed8..dabbc0ffc2c4 100644 --- a/platform/configuration-store-impl/src/com/intellij/configurationStore/FileBasedStorage.java +++ b/platform/configuration-store-impl/src/com/intellij/configurationStore/FileBasedStorage.java @@ -13,206 +13,131 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.configurationStore; +package com.intellij.configurationStore -import com.intellij.notification.Notification; -import com.intellij.notification.NotificationType; -import com.intellij.notification.Notifications; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.RoamingType; -import com.intellij.openapi.components.StoragePathMacros; -import com.intellij.openapi.components.TrackingPathMacroSubstitutor; -import com.intellij.openapi.components.impl.stores.*; -import com.intellij.openapi.util.JDOMUtil; -import com.intellij.openapi.util.io.FileUtilRt; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.CharsetToolkit; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.LineSeparator; -import org.jdom.Element; -import org.jdom.JDOMException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import com.intellij.notification.Notification +import com.intellij.notification.NotificationType +import com.intellij.notification.Notifications +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.components.RoamingType +import com.intellij.openapi.components.StoragePathMacros +import com.intellij.openapi.components.TrackingPathMacroSubstitutor +import com.intellij.openapi.components.impl.stores.* +import com.intellij.openapi.util.JDOMUtil +import com.intellij.openapi.util.io.FileUtilRt +import com.intellij.openapi.util.io.systemIndependentPath +import com.intellij.openapi.util.text.StringUtil +import com.intellij.openapi.vfs.CharsetToolkit +import com.intellij.openapi.vfs.LocalFileSystem +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.util.LineSeparator +import org.jdom.Element +import org.jdom.JDOMException -import java.io.File; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.util.Set; +import java.io.File +import java.io.IOException +import java.nio.ByteBuffer +import java.nio.CharBuffer -public class FileBasedStorage extends XmlElementStorage implements FileStorage { - private File myFile; - private volatile VirtualFile myCachedVirtualFile; - private LineSeparator myLineSeparator; - private boolean myBlockSavingTheContent; +open class FileBasedStorage(private volatile var file: File, + fileSpec: String, + rootElementName: String, + pathMacroManager: TrackingPathMacroSubstitutor? = null, + roamingType: RoamingType? = null, + provider: StreamProvider? = null) : XmlElementStorage(fileSpec, rootElementName, pathMacroManager, roamingType, provider), FileStorage { + private volatile var cachedVirtualFile: VirtualFile? = null + private var lineSeparator: LineSeparator? = null + private var blockSavingTheContent = false - public FileBasedStorage(@NotNull File file, - @NotNull String fileSpec, - @Nullable RoamingType roamingType, - @Nullable TrackingPathMacroSubstitutor pathMacroManager, - @NotNull String rootElementName, - @Nullable StreamProvider streamProvider) { - super(fileSpec, roamingType, pathMacroManager, rootElementName, streamProvider); - - if (ApplicationManager.getApplication().isUnitTestMode() && StringUtil.startsWithChar(file.getPath(), '$')) { - throw new AssertionError("It seems like some macros were not expanded for path: " + file); + init { + if (ApplicationManager.getApplication().isUnitTestMode() && file.getPath().startsWith('$')) { + throw AssertionError("It seems like some macros were not expanded for path: $file") } - - myFile = file; } + protected open val isUseXmlProlog: Boolean = false + // we never set io file to null - @Override - public void setFile(@Nullable VirtualFile file, @Nullable File ioFileIfChanged) { - myCachedVirtualFile = file; + override fun setFile(virtualFile: VirtualFile?, ioFileIfChanged: File?) { + cachedVirtualFile = virtualFile if (ioFileIfChanged != null) { - myFile = ioFileIfChanged; + file = ioFileIfChanged } } - protected boolean isUseXmlProlog() { - return false; - } + override fun createSaveSession(storageData: StorageData) = FileSaveSession(storageData, this) - @NotNull - @Override - protected XmlElementStorageSaveSession createSaveSession(@NotNull StorageData storageData) { - return new FileSaveSession(storageData); - } - - protected class FileSaveSession extends XmlElementStorageSaveSession { - protected FileSaveSession(@NotNull StorageData storageData) { - super(storageData); - } - - @Override - public void save() throws IOException { - if (!myBlockSavingTheContent) { - super.save(); + protected open class FileSaveSession(storageData: StorageData, storage: FileBasedStorage) : XmlElementStorage.XmlElementStorageSaveSession(storageData, storage) { + override fun save() { + if (!storage.blockSavingTheContent) { + super.save() } } - @Override - protected void doSave(@Nullable Element element) throws IOException { - if (myStreamProvider != null && myStreamProvider.getEnabled()) { - // stream provider always use LF separator - saveForProvider(element == null ? null : StorageUtil.writeToBytes(element, LineSeparator.LF.getSeparatorString()), element); + override fun saveLocally(element: Element?) { + if (storage.lineSeparator == null) { + storage.lineSeparator = if (storage.isUseXmlProlog) LineSeparator.LF else LineSeparator.getSystemLineSeparator() + } + + val virtualFile = storage.getVirtualFile() + if (element == null) { + StorageUtil.deleteFile(storage.file, this, virtualFile) + storage.cachedVirtualFile = null } else { - if (myLineSeparator == null) { - myLineSeparator = isUseXmlProlog() ? LineSeparator.LF : LineSeparator.getSystemLineSeparator(); - } - - VirtualFile virtualFile = getVirtualFile(); - if (element == null) { - StorageUtil.deleteFile(myFile, this, virtualFile); - myCachedVirtualFile = null; - } - else { - myCachedVirtualFile = StorageUtil.writeFile(myFile, this, virtualFile, element, isUseXmlProlog() ? myLineSeparator : LineSeparator.LF, isUseXmlProlog()); - } + storage.cachedVirtualFile = StorageUtil.writeFile(storage.file, this, virtualFile, element, if (storage.isUseXmlProlog) storage.lineSeparator!! else LineSeparator.LF, storage.isUseXmlProlog) } } } - @Override - @Nullable - public VirtualFile getVirtualFile() { - VirtualFile virtualFile = myCachedVirtualFile; - if (virtualFile == null) { - myCachedVirtualFile = virtualFile = LocalFileSystem.getInstance().findFileByIoFile(myFile); + override fun getVirtualFile(): VirtualFile? { + var result = cachedVirtualFile + if (result == null) { + result = LocalFileSystem.getInstance().findFileByIoFile(file) + cachedVirtualFile = result } - return virtualFile; + return cachedVirtualFile } - @Override - @NotNull - public File getFile() { - return myFile; - } + override fun getFile() = file - @Override - @Nullable - protected Element loadLocalData() { - myBlockSavingTheContent = false; + override fun loadLocalData(): Element? { + blockSavingTheContent = false try { - VirtualFile file = getVirtualFile(); + val file = getVirtualFile() if (file == null || file.isDirectory() || !file.isValid()) { if (LOG.isDebugEnabled()) { - LOG.debug("Document was not loaded for " + myFileSpec + " file is " + (file == null ? "null" : "directory")); + LOG.debug("Document was not loaded for $fileSpec file is ${if (file == null) "null" else "directory"}") } - return null; } - if (file.getLength() == 0) { - return processReadException(null); + else if (file.getLength() == 0L) { + processReadException(null) + } + else { + val charBuffer = CharsetToolkit.UTF8_CHARSET.decode(ByteBuffer.wrap(file.contentsToByteArray())) + lineSeparator = StorageUtil.detectLineSeparators(charBuffer, if (isUseXmlProlog) null else LineSeparator.LF) + return JDOMUtil.loadDocument(charBuffer).detachRootElement() } - - CharBuffer charBuffer = CharsetToolkit.UTF8_CHARSET.decode(ByteBuffer.wrap(file.contentsToByteArray())); - myLineSeparator = StorageUtil.detectLineSeparators(charBuffer, isUseXmlProlog() ? null : LineSeparator.LF); - return JDOMUtil.loadDocument(charBuffer).detachRootElement(); } - catch (JDOMException e) { - return processReadException(e); + catch (e: JDOMException) { + processReadException(e) } - catch (IOException e) { - return processReadException(e); + catch (e: IOException) { + processReadException(e) } + return null } - @Nullable - private Element processReadException(@Nullable Exception e) { - boolean contentTruncated = e == null; - myBlockSavingTheContent = !contentTruncated && (StorageUtil.isProjectOrModuleFile(myFileSpec) || myFileSpec.equals(StoragePathMacros.WORKSPACE_FILE)); + private fun processReadException(e: Exception?) { + val contentTruncated = e == null + blockSavingTheContent = !contentTruncated && (StorageUtil.isProjectOrModuleFile(fileSpec) || fileSpec == StoragePathMacros.WORKSPACE_FILE) if (!ApplicationManager.getApplication().isUnitTestMode() && !ApplicationManager.getApplication().isHeadlessEnvironment()) { if (e != null) { - LOG.info(e); + LOG.info(e) } - new Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, "Load Settings", - "Cannot load settings from file '" + myFile + "': " + - (contentTruncated ? "content truncated" : e.getMessage()) + "\n" + - (myBlockSavingTheContent ? "Please correct the file content" : "File content will be recreated"), - NotificationType.WARNING).notify(null); - } - return null; - } - - @Override - public void setDefaultState(@NotNull Element element) { - element.setName(myRootElementName); - super.setDefaultState(element); - } - - public void updatedFromStreamProvider(@NotNull Set changedComponentNames, boolean deleted) { - if (myRoamingType == RoamingType.DISABLED) { - // storage roaming was changed to DISABLED, but settings repository has old state - return; - } - - try { - Element newElement = deleted ? null : loadDataFromStreamProvider(); - if (newElement == null) { - StorageUtil.deleteFile(myFile, this, myCachedVirtualFile); - // if data was loaded, mark as changed all loaded components - if (myStorageData != null) { - changedComponentNames.addAll(myStorageData.getComponentNames()); - myStorageData = null; - } - } - else if (myStorageData != null) { - StorageData newStorageData = createStorageData(); - loadState(newStorageData, newElement); - changedComponentNames.addAll(myStorageData.getChangedComponentNames(newStorageData, myPathMacroSubstitutor)); - myStorageData = newStorageData; - } - } - catch (Throwable e) { - LOG.error(e); + Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, "Load Settings", "Cannot load settings from file '$file': ${if (contentTruncated) "content truncated" else e!!.getMessage()}\n${if (blockSavingTheContent) "Please correct the file content" else "File content will be recreated"}", NotificationType.WARNING).notify(null) } } - @Override - public String toString() { - return FileUtilRt.toSystemIndependentName(myFile.getPath()); - } + override fun toString() = file.systemIndependentPath } diff --git a/platform/configuration-store-impl/src/com/intellij/configurationStore/XmlElementStorage.java b/platform/configuration-store-impl/src/com/intellij/configurationStore/XmlElementStorage.java index a83037add451..e9d014936447 100644 --- a/platform/configuration-store-impl/src/com/intellij/configurationStore/XmlElementStorage.java +++ b/platform/configuration-store-impl/src/com/intellij/configurationStore/XmlElementStorage.java @@ -13,213 +13,190 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.configurationStore; +package com.intellij.configurationStore -import com.intellij.openapi.components.RoamingType; -import com.intellij.openapi.components.TrackingPathMacroSubstitutor; -import com.intellij.openapi.components.impl.stores.*; -import com.intellij.openapi.util.JDOMUtil; -import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; -import com.intellij.util.containers.ContainerUtil; -import gnu.trove.THashMap; -import org.jdom.Element; -import org.jdom.JDOMException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import com.intellij.openapi.components.RoamingType +import com.intellij.openapi.components.StateStorage +import com.intellij.openapi.components.TrackingPathMacroSubstitutor +import com.intellij.openapi.components.impl.stores.* +import com.intellij.openapi.util.JDOMUtil +import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream +import com.intellij.util.LineSeparator +import com.intellij.util.containers.ContainerUtil +import gnu.trove.THashMap +import org.jdom.Element +import org.jdom.JDOMException -import java.io.IOException; -import java.util.Map; -import java.util.Set; +import java.io.IOException -public abstract class XmlElementStorage extends StateStorageBase { - @NotNull protected final String myRootElementName; - protected final StreamProvider myStreamProvider; - protected final String myFileSpec; +abstract class XmlElementStorage protected constructor(protected val fileSpec: String, + protected val rootElementName: String, + protected val pathMacroSubstitutor: TrackingPathMacroSubstitutor?, + roamingType: RoamingType?, + provider: StreamProvider?) : StateStorageBase() { + protected val roamingType: RoamingType = roamingType ?: RoamingType.PER_USER + private val provider: StreamProvider? = if (provider == null || roamingType == RoamingType.DISABLED || !provider.isApplicable(fileSpec, this.roamingType)) null else provider - protected final RoamingType myRoamingType; + protected abstract fun loadLocalData(): Element? - protected XmlElementStorage(@NotNull String fileSpec, - @Nullable RoamingType roamingType, - @Nullable TrackingPathMacroSubstitutor pathMacroSubstitutor, - @NotNull String rootElementName, - @Nullable StreamProvider streamProvider) { - super(pathMacroSubstitutor); + override fun getStateAndArchive(storageData: StorageData, component: Any, componentName: String) = storageData.getStateAndArchive(componentName) - myFileSpec = fileSpec; - myRoamingType = roamingType == null ? RoamingType.PER_USER : roamingType; - myRootElementName = rootElementName; - myStreamProvider = myRoamingType == RoamingType.DISABLED ? null : streamProvider; - } - - @Nullable - protected abstract Element loadLocalData(); - - @Nullable - @Override - protected Element getStateAndArchive(@NotNull StorageData storageData, Object component, @NotNull String componentName) { - return storageData.getStateAndArchive(componentName); - } - - @Override - @NotNull - protected StorageData loadData() { - StorageData result = createStorageData(); - Element element; + override fun loadData(): StorageData { + val storageData = createStorageData() + val element: Element? // we don't use local data if has stream provider - if (myStreamProvider != null && myStreamProvider.getEnabled()) { + if (provider != null && provider.enabled) { try { - element = loadDataFromStreamProvider(); + element = loadDataFromProvider() if (element != null) { - loadState(result, element); + storageData.loadState(element) } } - catch (Exception e) { - LOG.error(e); - element = null; + catch (e: Exception) { + LOG.error(e) + element = null } } else { - element = loadLocalData(); + element = loadLocalData() } if (element != null) { - loadState(result, element); + storageData.loadState(element) } - return result; + return storageData } - @Nullable - protected final Element loadDataFromStreamProvider() throws IOException, JDOMException { - assert myStreamProvider != null; - return JDOMUtil.load(myStreamProvider.loadContent(myFileSpec, myRoamingType)); + throws(IOException::class, JDOMException::class) + private fun loadDataFromProvider() = JDOMUtil.load(provider!!.loadContent(fileSpec, roamingType)) + + private fun StorageData.loadState(element: Element) { + load(element, pathMacroSubstitutor, true) } - protected final void loadState(@NotNull StorageData result, @NotNull Element element) { - result.load(element, myPathMacroSubstitutor, true); + protected open fun createStorageData(): StorageData = StorageData() + + fun setDefaultState(element: Element) { + element.setName(rootElementName) + val storageData = createStorageData() + storageData.loadState(element) + storageDataRef.set(storageData) } - @NotNull - protected StorageData createStorageData() { - return new StorageData(myRootElementName); - } + override fun startExternalization() = if (checkIsSavingDisabled()) null else createSaveSession(getStorageData()) - public void setDefaultState(@NotNull Element element) { - myStorageData = createStorageData(); - loadState(myStorageData, element); - } + protected abstract fun createSaveSession(storageData: StorageData): StateStorage.ExternalizationSession - @Override - @Nullable - public final XmlElementStorageSaveSession startExternalization() { - return checkIsSavingDisabled() ? null : createSaveSession(getStorageData()); - } - - @NotNull - protected abstract XmlElementStorageSaveSession createSaveSession(@NotNull StorageData storageData); - - @Nullable - protected final Element getElement(@NotNull StorageData data, @NotNull Map newLiveStates) throws IOException { - Element element = data.save(newLiveStates); - if (element == null || JDOMUtil.isEmpty(element)) { - return null; - } - - if (myPathMacroSubstitutor != null) { - try { - myPathMacroSubstitutor.collapsePaths(element); - } - finally { - myPathMacroSubstitutor.reset(); - } - } - - return element; - } - - @Override - public void analyzeExternalChangesAndUpdateIfNeed(@NotNull Set componentNames) { - StorageData oldData = myStorageData; - StorageData newData = getStorageData(true); + override fun analyzeExternalChangesAndUpdateIfNeed(componentNames: MutableSet) { + val oldData = storageDataRef.get() + val newData = getStorageData(true) if (oldData == null) { if (LOG.isDebugEnabled()) { - LOG.debug("analyzeExternalChangesAndUpdateIfNeed: old data null, load new for " + toString()); + LOG.debug("analyzeExternalChangesAndUpdateIfNeed: old data null, load new for ${toString()}") } - componentNames.addAll(newData.getComponentNames()); + componentNames.addAll(newData.getComponentNames()) } else { - Set changedComponentNames = oldData.getChangedComponentNames(newData, myPathMacroSubstitutor); + val changedComponentNames = oldData.getChangedComponentNames(newData, pathMacroSubstitutor) if (LOG.isDebugEnabled()) { - LOG.debug("analyzeExternalChangesAndUpdateIfNeed: changedComponentNames + " + changedComponentNames + " for " + toString()); + LOG.debug("analyzeExternalChangesAndUpdateIfNeed: changedComponentNames $changedComponentNames for ${toString()}") } if (!ContainerUtil.isEmpty(changedComponentNames)) { - componentNames.addAll(changedComponentNames); + componentNames.addAll(changedComponentNames) } } } - public abstract class XmlElementStorageSaveSession extends SaveSessionBase { - private final StorageData myOriginalStorageData; - @Nullable - private StorageData myCopiedStorageData; - - private final Map myNewLiveStates = new THashMap(); - - public XmlElementStorageSaveSession(@NotNull StorageData storageData) { - myOriginalStorageData = storageData; + private fun setStorageData(oldStorageData: StorageData, newStorageData: StorageData?) { + if (oldStorageData !== newStorageData && storageDataRef.getAndSet(newStorageData) !== oldStorageData) { + LOG.warn("Old storage data is not equal to current, new storage data was set anyway") } + } - @Nullable - @Override - public final SaveSession createSaveSession() { - return checkIsSavingDisabled() || (myCopiedStorageData == null && !myOriginalStorageData.isDirty()) ? null : this; - } + abstract class XmlElementStorageSaveSession(private val originalStorageData: StorageData, protected val storage: T) : SaveSessionBase() { + private var copiedStorageData: StorageData? = null - @Override - protected void setSerializedState(@NotNull Object component, @NotNull String componentName, @Nullable Element element) { - if (myCopiedStorageData == null) { - myCopiedStorageData = StorageData.setStateAndCloneIfNeed(componentName, element, myOriginalStorageData, myNewLiveStates); + private val newLiveStates = THashMap() + + override fun createSaveSession() = if (storage.checkIsSavingDisabled() || (copiedStorageData == null && !originalStorageData.isDirty())) null else this + + override fun setSerializedState(component: Any, componentName: String, element: Element?) { + if (copiedStorageData == null) { + copiedStorageData = StorageData.setStateAndCloneIfNeed(componentName, element, originalStorageData, newLiveStates) } else { - myCopiedStorageData.setState(componentName, element, myNewLiveStates); + copiedStorageData!!.setState(componentName, element, newLiveStates) } } - @Override - public void save() throws IOException { - StorageData storageData = myCopiedStorageData; + override fun save() { + var storageData = copiedStorageData if (storageData == null) { - storageData = myOriginalStorageData; + storageData = originalStorageData if (!storageData.isDirty()) { - LOG.warn("Copied storage data must be not null because original storage data is not dirty"); + LOG.warn("Copied storage data must be not null because original storage data is not dirty") } } - doSave(getElement(storageData, myNewLiveStates)); - myStorageData = storageData; - } - - protected abstract void doSave(@Nullable Element element) throws IOException; - - protected final void saveForProvider(@Nullable BufferExposingByteArrayOutputStream content, @Nullable Element element) throws IOException { - if (!myStreamProvider.isApplicable(myFileSpec, myRoamingType)) { - return; + var element = storageData.save(newLiveStates, storage.rootElementName) + if (element == null || JDOMUtil.isEmpty(element)) { + element = null + } + else if (storage.pathMacroSubstitutor != null) { + try { + storage.pathMacroSubstitutor.collapsePaths(element) + } + finally { + storage.pathMacroSubstitutor.reset() + } } - if (element == null) { - myStreamProvider.delete(myFileSpec, myRoamingType); + val provider = storage.provider + if (provider != null && provider.enabled) { + if (element == null) { + provider.delete(storage.fileSpec, storage.roamingType) + } + else { + // we should use standard line-separator (\n) - stream provider can share file content on any OS + val content = StorageUtil.writeToBytes(element, "\n") + provider.saveContent(storage.fileSpec, content.getInternalBuffer(), content.size(), storage.roamingType) + } } else { - doSaveForProvider(element, myRoamingType, content); + saveLocally(element) } + storage.setStorageData(originalStorageData, storageData) } - private void doSaveForProvider(@NotNull Element element, @NotNull RoamingType roamingType, @Nullable BufferExposingByteArrayOutputStream content) throws IOException { - if (content == null) { - StorageUtil.sendContent(myStreamProvider, myFileSpec, element, roamingType); + throws(IOException::class) + protected abstract fun saveLocally(element: Element?) + } + + public fun updatedFromStreamProvider(changedComponentNames: MutableSet, deleted: Boolean) { + if (roamingType == RoamingType.DISABLED) { + // storage roaming was changed to DISABLED, but settings repository has old state + return + } + + try { + val newElement = if (deleted) null else loadDataFromProvider() + val storageData = storageDataRef.get() + if (newElement == null) { + // if data was loaded, mark as changed all loaded components + if (storageData != null) { + changedComponentNames.addAll(storageData.getComponentNames()) + setStorageData(storageData, null) + } } - else { - myStreamProvider.saveContent(myFileSpec, content.getInternalBuffer(), content.size(), myRoamingType); + else if (storageData != null) { + val newStorageData = createStorageData() + newStorageData.loadState(newElement) + changedComponentNames.addAll(storageData.getChangedComponentNames(newStorageData, pathMacroSubstitutor)) + setStorageData(storageData, newStorageData) } } + catch (e: Throwable) { + LOG.error(e) + } } } diff --git a/platform/configuration-store-impl/testSrc/MockStreamProvider.kt b/platform/configuration-store-impl/testSrc/MockStreamProvider.kt index 4e813445c43f..d383107dd0fc 100644 --- a/platform/configuration-store-impl/testSrc/MockStreamProvider.kt +++ b/platform/configuration-store-impl/testSrc/MockStreamProvider.kt @@ -9,8 +9,6 @@ import java.io.FileInputStream import java.io.InputStream class MockStreamProvider(private val myBaseDir: File) : StreamProvider { - override fun isApplicable(fileSpec: String, roamingType: RoamingType) = roamingType === RoamingType.PER_USER - override fun saveContent(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) { FileUtil.writeToFile(File(myBaseDir, fileSpec), content, 0, size) } diff --git a/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/XmlElementStorageTest.java b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/XmlElementStorageTest.java deleted file mode 100644 index 352eafcb4b09..000000000000 --- a/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/XmlElementStorageTest.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2000-2015 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.configurationStore; - -import com.intellij.openapi.Disposable; -import com.intellij.openapi.components.RoamingType; -import com.intellij.openapi.components.StateStorage; -import com.intellij.openapi.components.TrackingPathMacroSubstitutor; -import com.intellij.openapi.components.impl.stores.StorageData; -import com.intellij.openapi.util.Disposer; -import com.intellij.testFramework.LightPlatformTestCase; -import org.jdom.Element; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Collection; -import java.util.Collections; -import java.util.Set; - -import static com.intellij.openapi.util.JDOMBuilder.attr; -import static com.intellij.openapi.util.JDOMBuilder.tag; - -/** - * @author mike - */ -public class XmlElementStorageTest extends LightPlatformTestCase { - private Disposable myParentDisposable; - - @Override - public void setUp() throws Exception { - super.setUp(); - myParentDisposable = Disposer.newDisposable(); - } - - @Override - public void tearDown() throws Exception { - Disposer.dispose(myParentDisposable); - super.tearDown(); - } - - public void testGetStateSucceeded() throws Exception { - MyXmlElementStorage storage = - new MyXmlElementStorage(tag("root", tag("component", attr("name", "test"), tag("foo")))); - Element state = storage.getState(this, "test", Element.class, null); - assertNotNull(state); - assertEquals("component", state.getName()); - assertNotNull(state.getChild("foo")); - } - - public void testGetStateNotSucceeded() throws Exception { - MyXmlElementStorage storage = new MyXmlElementStorage(tag("root")); - Element state = storage.getState(this, "test", Element.class, null); - assertNull(state); - } - - public void testSetStateOverridesOldState() throws Exception { - MyXmlElementStorage storage = - new MyXmlElementStorage(tag("root", tag("component", attr("name", "test"), tag("foo")))); - Element newState = tag("component", attr("name", "test"), tag("bar")); - StateStorage.ExternalizationSession externalizationSession = storage.startExternalization(); - externalizationSession.setState(this, "test", newState, null); - externalizationSession.createSaveSession().save(); - assertNotNull(storage.mySavedElement); - assertNotNull(storage.mySavedElement.getChild("component").getChild("bar")); - assertNull(storage.mySavedElement.getChild("component").getChild("foo")); - } - - - private static class MyXmlElementStorage extends XmlElementStorage { - private final Element myElement; - private Element mySavedElement; - - public MyXmlElementStorage(Element element) { - super("", RoamingType.PER_USER, new MyPathMacroManager(), "root", null); - myElement = element; - } - - @Override - protected Element loadLocalData() { - return myElement; - } - - @NotNull - @Override - protected XmlElementStorageSaveSession createSaveSession(@NotNull StorageData storageData) { - return new XmlElementStorageSaveSession(storageData) { - @Override - protected void doSave(@Nullable Element element) { - mySavedElement = element == null ? null : element.clone(); - } - }; - } - } - - private static class MyPathMacroManager implements TrackingPathMacroSubstitutor { - @Override - public void expandPaths(@NotNull final Element element) { - } - - @Override - public void reset() { - } - - @NotNull - @Override - public Collection getComponents(@NotNull Collection macros) { - return Collections.emptyList(); - } - - @Override - public void collapsePaths(@NotNull final Element element) { - } - - @Override - public String expandPath(final String path) { - throw new UnsupportedOperationException("Method expandPath not implemented in " + getClass()); - } - - @Override - public String collapsePath(@Nullable String path) { - throw new UnsupportedOperationException("Method collapsePath not implemented in " + getClass()); - } - - @NotNull - @Override - public Collection getUnknownMacros(final String componentName) { - return Collections.emptySet(); - } - - @Override - public void invalidateUnknownMacros(@NotNull Set macros) { - } - - @Override - public void addUnknownMacros(@NotNull String componentName, @NotNull Collection unknownMacros) { - } - } -} diff --git a/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/XmlElementStorageTest.kt b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/XmlElementStorageTest.kt new file mode 100644 index 000000000000..1c027bc43b2b --- /dev/null +++ b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/XmlElementStorageTest.kt @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2015 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.configurationStore + +import com.intellij.openapi.Disposable +import com.intellij.openapi.components.impl.stores.StorageData +import com.intellij.openapi.util.Disposer +import com.intellij.openapi.util.JDOMBuilder.attr +import com.intellij.openapi.util.JDOMBuilder.tag +import com.intellij.testFramework.LightPlatformTestCase +import junit.framework.TestCase +import org.jdom.Element + +class XmlElementStorageTest : LightPlatformTestCase() { + public fun testGetStateSucceeded() { + val storage = MyXmlElementStorage(tag("root", tag("component", attr("name", "test"), tag("foo")))) + val state = storage.getState(this, "test", javaClass(), null) + TestCase.assertNotNull(state) + TestCase.assertEquals("component", state.getName()) + TestCase.assertNotNull(state.getChild("foo")) + } + + public fun testGetStateNotSucceeded() { + val storage = MyXmlElementStorage(tag("root")) + val state = storage.getState(this, "test", javaClass(), null) + TestCase.assertNull(state) + } + + public fun testSetStateOverridesOldState() { + val storage = MyXmlElementStorage(tag("root", tag("component", attr("name", "test"), tag("foo")))) + val newState = tag("component", attr("name", "test"), tag("bar")) + val externalizationSession = storage.startExternalization()!! + externalizationSession.setState(this, "test", newState, null) + externalizationSession.createSaveSession()!!.save() + TestCase.assertNotNull(storage.mySavedElement) + TestCase.assertNotNull(storage.mySavedElement!!.getChild("component").getChild("bar")) + TestCase.assertNull(storage.mySavedElement!!.getChild("component").getChild("foo")) + } + + + private class MyXmlElementStorage(private val myElement: Element) : XmlElementStorage("", "root", null, null, null) { + var mySavedElement: Element? = null + + override fun loadLocalData() = myElement + + override fun createSaveSession(storageData: StorageData) = object : XmlElementStorage.XmlElementStorageSaveSession(storageData, this) { + override fun saveLocally(element: Element?) { + mySavedElement = element?.clone() + } + } + } +} diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java index ca5e1cfa4754..fb3628e5a135 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java @@ -19,6 +19,7 @@ import com.intellij.application.options.PathMacrosCollector; import com.intellij.ide.highlighter.ModuleFileType; import com.intellij.openapi.components.ComponentManager; import com.intellij.openapi.components.StateStorage; +import com.intellij.openapi.components.TrackingPathMacroSubstitutor; import com.intellij.openapi.components.impl.stores.StateStorageBase; import com.intellij.openapi.components.impl.stores.StateStorageManager; import com.intellij.openapi.components.impl.stores.StorageDataBase; @@ -57,8 +58,10 @@ public class ClasspathStorage extends StateStorageBase componentNames) { // if some file changed, so, changed componentNames.add("NewModuleRootManager"); - if (myStorageData != null) { - myStorageData.loaded = false; + MyStorageData storageData = storageDataRef.get(); + if (storageData != null) { + storageData.loaded = false; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java index e78af518779c..11c7b079119c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java @@ -43,8 +43,10 @@ public class DirectoryBasedStorage extends StateStorageBase componentNames) { // todo reload only changed file, compute diff - DirectoryStorageData oldData = myStorageData; + DirectoryStorageData oldData = storageDataRef.get(); DirectoryStorageData newData = loadData(); - myStorageData = newData; + storageDataRef.set(newData); if (oldData == null) { componentNames.addAll(newData.getComponentNames()); } @@ -155,7 +157,7 @@ public class DirectoryBasedStorage extends StateStorageBase() { @@ -192,7 +194,7 @@ public class DirectoryBasedStorage extends StateStorageBase implements StateStorage { protected static final Logger LOG = Logger.getInstance(StateStorageBase.class); private boolean mySavingDisabled = false; - protected final TrackingPathMacroSubstitutor myPathMacroSubstitutor; - protected T myStorageData; - - protected StateStorageBase(@Nullable TrackingPathMacroSubstitutor trackingPathMacroSubstitutor) { - myPathMacroSubstitutor = trackingPathMacroSubstitutor; - } + protected final AtomicReference storageDataRef = new AtomicReference(); @Override @Nullable @@ -60,12 +56,18 @@ public abstract class StateStorageBase implements Sta @NotNull protected final T getStorageData(boolean reload) { - if (myStorageData != null && !reload) { - return myStorageData; + final T storageData = storageDataRef.get(); + if (storageData != null && !reload) { + return storageData; } - myStorageData = loadData(); - return myStorageData; + T newStorageData = loadData(); + if (storageDataRef.compareAndSet(storageData, newStorageData)) { + return newStorageData; + } + else { + return getStorageData(false); + } } protected abstract T loadData(); diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java index 77a753d80ded..428783737fb8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java @@ -349,15 +349,6 @@ public class StorageUtil { } } - /** - * You must call {@link StreamProvider#isApplicable(String, com.intellij.openapi.components.RoamingType)} before - */ - public static void sendContent(@NotNull StreamProvider provider, @NotNull String fileSpec, @NotNull Element element, @NotNull RoamingType type) throws IOException { - // we should use standard line-separator (\n) - stream provider can share file content on any OS - BufferExposingByteArrayOutputStream content = writeToBytes(element, "\n"); - provider.saveContent(fileSpec, content.getInternalBuffer(), content.size(), type); - } - public static boolean isProjectOrModuleFile(@NotNull String fileSpec) { return StoragePathMacros.PROJECT_FILE.equals(fileSpec) || fileSpec.startsWith(StoragePathMacros.PROJECT_CONFIG_DIR) || fileSpec.equals(StoragePathMacros.MODULE_FILE); } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt index 9482b774c358..6767af9599cb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt @@ -23,16 +23,11 @@ public interface StreamProvider { public open val enabled: Boolean get() = true - /** - * fileSpec Only main fileSpec, not version - */ public open fun isApplicable(fileSpec: String, roamingType: RoamingType): Boolean = true /** * @param fileSpec - * * * @param content bytes of content, size of array is not actual size of data, you must use `size` - * * * @param size actual size of data */ public fun saveContent(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) diff --git a/platform/projectModel-api/src/com/intellij/openapi/components/Storage.java b/platform/projectModel-api/src/com/intellij/openapi/components/Storage.java index 38771e8b2bd8..0e27bb2bc05d 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/components/Storage.java +++ b/platform/projectModel-api/src/com/intellij/openapi/components/Storage.java @@ -25,9 +25,6 @@ import java.lang.annotation.RetentionPolicy; public @interface Storage { @NonNls String id() default "default"; - @Deprecated - boolean isDefault() default true; - @NonNls String file() default ""; StorageScheme scheme() default StorageScheme.DEFAULT; diff --git a/platform/projectModel-impl/src/com/intellij/core/CoreProjectLoader.java b/platform/projectModel-impl/src/com/intellij/core/CoreProjectLoader.java index a94f8daa11f6..24bf0829035c 100644 --- a/platform/projectModel-impl/src/com/intellij/core/CoreProjectLoader.java +++ b/platform/projectModel-impl/src/com/intellij/core/CoreProjectLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -95,7 +95,7 @@ public class CoreProjectLoader { @NotNull public static StorageData loadStorageFile(@NotNull ComponentManager componentManager, @NotNull VirtualFile modulesXml) throws JDOMException, IOException { - StorageData storageData = new StorageData("project"); + StorageData storageData = new StorageData(); storageData.load(JDOMUtil.loadDocument(modulesXml.contentsToByteArray()).getRootElement(), PathMacroManager.getInstance(componentManager), false); return storageData; } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DirectoryStorageData.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DirectoryStorageData.java index 9f8818fb2193..b936e5f03a26 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DirectoryStorageData.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DirectoryStorageData.java @@ -19,7 +19,6 @@ import com.intellij.application.options.PathMacrosCollector; import com.intellij.openapi.components.StateSplitter; import com.intellij.openapi.components.StateSplitterEx; import com.intellij.openapi.components.TrackingPathMacroSubstitutor; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.text.StringUtilRt; import com.intellij.openapi.vfs.VirtualFile; @@ -40,8 +39,6 @@ import java.util.Set; import static com.intellij.openapi.components.impl.stores.StateMap.getNewByteIfDiffers; public class DirectoryStorageData extends StorageDataBase { - private static final Logger LOG = Logger.getInstance(DirectoryStorageData.class); - public static final String DEFAULT_EXT = ".xml"; private final Map myStates; @@ -87,12 +84,12 @@ public class DirectoryStorageData extends StorageDataBase { } Element element = JDOMUtil.load(file.getInputStream()); - String name = StorageData.getComponentNameIfValid(element); + String name = getComponentNameIfValid(element); if (name == null) { continue; } - if (!element.getName().equals(StorageData.COMPONENT)) { + if (!element.getName().equals(COMPONENT)) { LOG.error("Incorrect root tag name (" + element.getName() + ") in " + file.getPresentableUrl()); continue; } @@ -249,7 +246,7 @@ public class DirectoryStorageData extends StorageDataBase { @Nullable public Element getCompositeStateAndArchive(@NotNull String componentName, @SuppressWarnings("deprecation") @NotNull StateSplitter splitter) { StateMap fileToState = myStates.get(componentName); - Element state = new Element(StorageData.COMPONENT); + Element state = new Element(COMPONENT); if (fileToState == null || fileToState.isEmpty()) { return state; } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java index 7bd082c75e87..b01347330cbd 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java @@ -20,7 +20,6 @@ import com.intellij.openapi.components.PathMacroSubstitutor; import com.intellij.openapi.components.TrackingPathMacroSubstitutor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.JDOMUtil; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.SmartHashSet; import com.intellij.util.containers.StringInterner; @@ -36,28 +35,18 @@ import static com.intellij.openapi.components.impl.stores.StateMap.getNewByteIfD public class StorageData extends StorageDataBase { private static final Logger LOG = Logger.getInstance(StorageData.class); - public static final String COMPONENT = "component"; - public static final String NAME = "name"; private final StateMap myStates; - protected final String myRootElementName; - - public StorageData() { - this(COMPONENT); - } - public boolean isDirty() { return false; } - public StorageData(@NotNull String rootElementName) { + public StorageData() { myStates = new StateMap(); - myRootElementName = rootElementName; } protected StorageData(@NotNull StorageData storageData) { - myRootElementName = storageData.myRootElementName; myStates = new StateMap(storageData.myStates); } @@ -97,22 +86,12 @@ public class StorageData extends StorageDataBase { } @Nullable - static String getComponentNameIfValid(@NotNull Element element) { - String name = element.getAttributeValue(NAME); - if (StringUtil.isEmpty(name)) { - LOG.warn("No name attribute for component in " + JDOMUtil.writeElement(element)); - return null; - } - return name; - } - - @Nullable - public Element save(@NotNull Map newLiveStates) throws IOException { + public Element save(@NotNull Map newLiveStates, @NotNull String rootElementName) throws IOException { if (myStates.isEmpty()) { return null; } - Element rootElement = new Element(myRootElementName); + Element rootElement = new Element(rootElementName); String[] componentNames = ArrayUtil.toStringArray(myStates.keys()); Arrays.sort(componentNames); for (String componentName : componentNames) { diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageDataBase.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageDataBase.java index f28b3da1900a..1f659ebfaa48 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageDataBase.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageDataBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -15,13 +15,33 @@ */ package com.intellij.openapi.components.impl.stores; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.text.StringUtil; +import org.jdom.Element; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Set; public abstract class StorageDataBase { + protected static final Logger LOG = Logger.getInstance(StorageDataBase.class); + + public static final String COMPONENT = "component"; + public static final String NAME = "name"; + @NotNull public abstract Set getComponentNames(); public abstract boolean hasState(@NotNull String componentName); + + @Nullable + static String getComponentNameIfValid(@NotNull Element element) { + String name = element.getAttributeValue(NAME); + if (StringUtil.isEmpty(name)) { + LOG.warn("No name attribute for component in " + JDOMUtil.writeElement(element)); + return null; + } + return name; + } } \ No newline at end of file diff --git a/plugins/settings-repository/src/sync.kt b/plugins/settings-repository/src/sync.kt index bd54f22bfdfc..da1955841877 100644 --- a/plugins/settings-repository/src/sync.kt +++ b/plugins/settings-repository/src/sync.kt @@ -16,14 +16,13 @@ package org.jetbrains.settingsRepository import com.intellij.configurationStore.ComponentStoreImpl -import com.intellij.configurationStore.FileBasedStorage import com.intellij.configurationStore.SchemeManagerFactoryBase +import com.intellij.configurationStore.XmlElementStorage import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.WriteAction import com.intellij.openapi.application.impl.ApplicationImpl -import com.intellij.openapi.components.impl.stores.FileStorage import com.intellij.openapi.components.StateStorage -import com.intellij.openapi.components.impl.stores.FileBasedStorage +import com.intellij.openapi.components.impl.stores.FileStorage import com.intellij.openapi.components.impl.stores.IComponentStore import com.intellij.openapi.components.impl.stores.StoreUtil import com.intellij.openapi.components.stateStore @@ -185,10 +184,10 @@ private fun updateStoragesFromStreamProvider(store: IComponentStore, updateResul })!! } -private fun updateStateStorage(changedComponentNames: Set, stateStorages: Collection, deleted: Boolean) { +private fun updateStateStorage(changedComponentNames: MutableSet, stateStorages: Collection, deleted: Boolean) { for (stateStorage in stateStorages) { try { - (stateStorage as FileBasedStorage).updatedFromStreamProvider(changedComponentNames, deleted) + (stateStorage as XmlElementStorage).updatedFromStreamProvider(changedComponentNames, deleted) } catch (e: Throwable) { LOG.error(e) From 8b71dd29dad9f89ab693dd681c2c3e01af35d32e Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 6 Aug 2015 17:41:42 +0200 Subject: [PATCH 10/99] FileStorage in kotlin, thread-safe StateStorageBase.getStorageData (initial, will be addressed and tested later) --- .../{FileBasedStorage.java => FileBasedStorage.kt} | 0 .../{XmlElementStorage.java => XmlElementStorage.kt} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename platform/configuration-store-impl/src/com/intellij/configurationStore/{FileBasedStorage.java => FileBasedStorage.kt} (100%) rename platform/configuration-store-impl/src/com/intellij/configurationStore/{XmlElementStorage.java => XmlElementStorage.kt} (100%) diff --git a/platform/configuration-store-impl/src/com/intellij/configurationStore/FileBasedStorage.java b/platform/configuration-store-impl/src/com/intellij/configurationStore/FileBasedStorage.kt similarity index 100% rename from platform/configuration-store-impl/src/com/intellij/configurationStore/FileBasedStorage.java rename to platform/configuration-store-impl/src/com/intellij/configurationStore/FileBasedStorage.kt diff --git a/platform/configuration-store-impl/src/com/intellij/configurationStore/XmlElementStorage.java b/platform/configuration-store-impl/src/com/intellij/configurationStore/XmlElementStorage.kt similarity index 100% rename from platform/configuration-store-impl/src/com/intellij/configurationStore/XmlElementStorage.java rename to platform/configuration-store-impl/src/com/intellij/configurationStore/XmlElementStorage.kt From de0d88a78023f4ce5fc02908bbbee7f9e469ce08 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 6 Aug 2015 18:43:31 +0200 Subject: [PATCH 11/99] =?UTF-8?q?ComponentStore=20=E2=80=94=20load=20state?= =?UTF-8?q?=20without=20read=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/artifacts/ArtifactManagerImpl.java | 19 +++-- .../src/ComponentStoreImpl.kt | 73 +++++++++---------- .../roots/impl/storage/ClasspathStorage.java | 12 ++- .../impl/stores/DirectoryBasedStorage.java | 9 +-- .../impl/stores/DirectoryStorageData.java | 4 +- .../components/impl/stores/StateMap.java | 26 ++++--- .../roots/impl/ModuleRootManagerImpl.java | 12 ++- .../breakpoints/XBreakpointManagerImpl.java | 58 ++++++++------- 8 files changed, 123 insertions(+), 90 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java index 490bb8a9666c..dffdbaba8aa1 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java @@ -16,9 +16,7 @@ package com.intellij.packaging.impl.artifacts; import com.intellij.compiler.server.BuildManager; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.Result; -import com.intellij.openapi.application.WriteAction; +import com.intellij.openapi.application.*; import com.intellij.openapi.components.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.ProjectLoadingErrorsNotifier; @@ -193,9 +191,18 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo @Override public void loadState(ArtifactManagerState managerState) { - final List artifacts = new ArrayList(); - for (ArtifactState state : managerState.getArtifacts()) { - artifacts.add(loadArtifact(state)); + List artifactStates = managerState.getArtifacts(); + final List artifacts = new ArrayList(artifactStates.size()); + if (!artifactStates.isEmpty()) { + AccessToken token = ReadAction.start(); + try { + for (ArtifactState state : artifactStates) { + artifacts.add(loadArtifact(state)); + } + } + finally { + token.finish(); + } } if (myLoaded) { diff --git a/platform/configuration-store-impl/src/ComponentStoreImpl.kt b/platform/configuration-store-impl/src/ComponentStoreImpl.kt index 7a16920da5c7..57e177df897d 100644 --- a/platform/configuration-store-impl/src/ComponentStoreImpl.kt +++ b/platform/configuration-store-impl/src/ComponentStoreImpl.kt @@ -19,7 +19,6 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.PathManager import com.intellij.openapi.application.WriteAction import com.intellij.openapi.application.ex.DecodeDefaultsUtil -import com.intellij.openapi.application.runReadAction import com.intellij.openapi.components.* import com.intellij.openapi.components.StateStorage.SaveSession import com.intellij.openapi.components.StateStorageChooserEx.Resolution @@ -197,22 +196,20 @@ public abstract class ComponentStoreImpl : IComponentStore { return null } - runReadAction { - try { - getDefaultState(component, componentName, javaClass())?.let { component.readExternal(it) } - } - catch (e: Throwable) { - LOG.error(e) - } + try { + getDefaultState(component, componentName, javaClass())?.let { component.readExternal(it) } + } + catch (e: Throwable) { + LOG.error(e) + } - val element = getStateStorageManager().getOldStorage(component, componentName, StateStorageOperation.READ)?.getState(component, componentName, javaClass(), null) ?: return null - try { - component.readExternal(element) - } - catch (e: InvalidDataException) { - LOG.error(e) - return null - } + val element = getStateStorageManager().getOldStorage(component, componentName, StateStorageOperation.READ)?.getState(component, componentName, javaClass(), null) ?: return null + try { + component.readExternal(element) + } + catch (e: InvalidDataException) { + LOG.error(e) + return null } return componentName } @@ -243,33 +240,31 @@ public abstract class ComponentStoreImpl : IComponentStore { val defaultState = if (stateSpec.defaultStateAsResource) getDefaultState(component, name, stateClass) else null val storageSpecs = getStorageSpecs(component, stateSpec, StateStorageOperation.READ) val stateStorageChooser = component as? StateStorageChooserEx - runReadAction { - for (storageSpec in storageSpecs) { - val resolution = if (stateStorageChooser == null) Resolution.DO else stateStorageChooser.getResolution(storageSpec, StateStorageOperation.READ) - if (resolution === Resolution.SKIP) { + for (storageSpec in storageSpecs) { + val resolution = if (stateStorageChooser == null) Resolution.DO else stateStorageChooser.getResolution(storageSpec, StateStorageOperation.READ) + if (resolution === Resolution.SKIP) { + continue + } + + val storage = getStateStorageManager().getStateStorage(storageSpec) + var state = storage.getState(component, name, stateClass, defaultState) + if (state == null) { + if (changedStorages != null && changedStorages.contains(storage)) { + // state will be null if file deleted + // we must create empty (initial) state to reinit component + state = DefaultStateSerializer.deserializeState(Element("state"), stateClass, null)!! + } + else { continue } - - val storage = getStateStorageManager().getStateStorage(storageSpec) - var state = storage.getState(component, name, stateClass, defaultState) - if (state == null) { - if (changedStorages != null && changedStorages.contains(storage)) { - // state will be null if file deleted - // we must create empty (initial) state to reinit component - state = DefaultStateSerializer.deserializeState(Element("state"), stateClass, null)!! - } - else { - continue - } - } - - component.loadState(state) - return name } - if (defaultState != null) { - component.loadState(defaultState) - } + component.loadState(state) + return name + } + + if (defaultState != null) { + component.loadState(defaultState) } return name } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java index fb3628e5a135..d12449f476fe 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java @@ -17,6 +17,8 @@ package com.intellij.openapi.roots.impl.storage; import com.intellij.application.options.PathMacrosCollector; import com.intellij.ide.highlighter.ModuleFileType; +import com.intellij.openapi.application.AccessToken; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.components.ComponentManager; import com.intellij.openapi.components.StateStorage; import com.intellij.openapi.components.TrackingPathMacroSubstitutor; @@ -152,6 +154,7 @@ public class ClasspathStorage extends StateStorageBase() { + copiedStorageData.processComponent(componentName, new PairConsumer() { @Override - public boolean execute(String fileName, Object state) { + public void consume(String fileName, Object state) { if (!dirtyFileNames.contains(fileName)) { - return true; + return; } Element element = null; @@ -210,7 +210,6 @@ public class DirectoryBasedStorage extends StateStorageBase consumer) { + void processComponent(@NotNull String componentName, @NotNull PairConsumer consumer) { StateMap map = myStates.get(componentName); if (map != null) { map.forEachEntry(consumer); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StateMap.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StateMap.java index 69c4edf02a21..21faf8231b66 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StateMap.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StateMap.java @@ -21,9 +21,9 @@ import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.util.ArrayUtil; +import com.intellij.util.PairConsumer; import com.intellij.util.SystemProperties; -import gnu.trove.THashMap; -import gnu.trove.TObjectObjectProcedure; +import com.intellij.util.containers.ContainerUtil; import org.iq80.snappy.SnappyInputStream; import org.iq80.snappy.SnappyOutputStream; import org.jdom.Element; @@ -40,6 +40,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentMap; @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") public final class StateMap { @@ -50,14 +51,15 @@ public final class StateMap { setOmitEncoding(true). setOmitDeclaration(true); - private final THashMap states; + private final ConcurrentMap states; public StateMap() { - states = new THashMap(); + states = ContainerUtil.newConcurrentMap(); } public StateMap(StateMap stateMap) { - states = new THashMap((Map)stateMap.states); + states = ContainerUtil.newConcurrentMap(stateMap.states.size()); + states.putAll(stateMap.states); } @NotNull @@ -194,8 +196,12 @@ public final class StateMap { return null; } - states.put(key, archiveState((Element)state)); - return (Element)state; + if (states.replace(key, state, archiveState((Element)state))) { + return (Element)state; + } + else { + return getStateAndArchive(key); + } } @NotNull @@ -230,7 +236,9 @@ public final class StateMap { return states.size(); } - public void forEachEntry(@NotNull TObjectObjectProcedure consumer) { - states.forEachEntry(consumer); + public void forEachEntry(@NotNull PairConsumer consumer) { + for (Map.Entry entry : states.entrySet()) { + consumer.consume(entry.getKey(), entry.getValue()); + } } } \ No newline at end of file diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java index 1d590146419a..8bb4106692b0 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java @@ -16,7 +16,9 @@ package com.intellij.openapi.roots.impl; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.*; import com.intellij.openapi.project.Project; @@ -338,8 +340,14 @@ public class ModuleRootManagerImpl extends ModuleRootManager implements ModuleCo } public void loadState(ModuleRootManagerState object) { - loadState(object, myLoaded || isModuleAdded); - myLoaded = true; + AccessToken token = ReadAction.start(); + try { + loadState(object, myLoaded || isModuleAdded); + myLoaded = true; + } + finally { + token.finish(); + } } protected void loadState(ModuleRootManagerState object, boolean throwEvent) { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java index 0c669f7b691a..fed4cdc556c7 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,9 @@ package com.intellij.xdebugger.impl.breakpoints; import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -405,33 +407,39 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta myDefaultBreakpoints.clear(); myBreakpointsDefaults.clear(); - for (BreakpointState breakpointState : state.getDefaultBreakpoints()) { - loadBreakpoint(breakpointState, true); - } - for (XBreakpointType type : XBreakpointUtil.getBreakpointTypes()) { - if (!myDefaultBreakpoints.containsKey(type)) { - addDefaultBreakpoint(type); + AccessToken token = ReadAction.start(); + try { + for (BreakpointState breakpointState : state.getDefaultBreakpoints()) { + loadBreakpoint(breakpointState, true); } - } - - for (XBreakpointBase breakpoint : myBreakpoints.values()) { - doRemoveBreakpoint(breakpoint); - } - for (BreakpointState breakpointState : state.getBreakpoints()) { - loadBreakpoint(breakpointState, false); - } - - for (BreakpointState defaults : state.getBreakpointsDefaults()) { - XBreakpointType type = XBreakpointUtil.findType(defaults.getTypeId()); - if (type != null) { - myBreakpointsDefaults.put(type, defaults); + for (XBreakpointType type : XBreakpointUtil.getBreakpointTypes()) { + if (!myDefaultBreakpoints.containsKey(type)) { + addDefaultBreakpoint(type); + } } - else { - LOG.warn("Unknown breakpoint type " + defaults.getTypeId()); - } - } - myDependentBreakpointManager.loadState(); + for (XBreakpointBase breakpoint : myBreakpoints.values()) { + doRemoveBreakpoint(breakpoint); + } + for (BreakpointState breakpointState : state.getBreakpoints()) { + loadBreakpoint(breakpointState, false); + } + + for (BreakpointState defaults : state.getBreakpointsDefaults()) { + XBreakpointType type = XBreakpointUtil.findType(defaults.getTypeId()); + if (type != null) { + myBreakpointsDefaults.put(type, defaults); + } + else { + LOG.warn("Unknown breakpoint type " + defaults.getTypeId()); + } + } + + myDependentBreakpointManager.loadState(); + } + finally { + token.finish(); + } myLineBreakpointManager.updateBreakpointsUI(); myTime = state.getTime(); myDefaultGroup = state.getDefaultGroup(); From 6a260f239b2917a65dd14d242e97d2247f0c7b54 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 7 Aug 2015 08:37:57 +0200 Subject: [PATCH 12/99] use.read.action.to.init.service = false by default --- .../intellij/openapi/components/impl/ServiceManagerImpl.java | 4 +--- platform/util/resources/misc/registry.properties | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java index 10db5de0a74c..b8bc987fd22f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java @@ -18,7 +18,6 @@ package com.intellij.openapi.components.impl; import com.intellij.ide.plugins.PluginManager; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.AccessToken; -import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.components.BaseComponent; @@ -289,7 +288,6 @@ public class ServiceManagerImpl implements BaseComponent { } public static boolean isUseReadActionToInitService() { - Application app = ApplicationManager.getApplication(); - return Registry.is("use.read.action.to.init.service", !(app.isUnitTestMode() || app.isInternal())); + return Registry.is("use.read.action.to.init.service", false); } } diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 5affd420ca95..f99f1d195d4d 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -639,7 +639,7 @@ editor.breadcrumbs.highlight.on.hover.description=Highlight corresponding ranges testDiscovery.enabled=false ruby.remote.debugger.supports.catchpoint.removal=true -use.read.action.to.init.service=true +use.read.action.to.init.service=false ruby.debugger.support.file.filtering=false color.blindness= From bda0b50c80da98a821ae08bd8da148c5ce689f67 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 8 Aug 2015 16:45:05 +0300 Subject: [PATCH 13/99] [git] IDEA-143674 Split command parameters into several commands when needed --- .../git4idea/commands/GitCommandResult.java | 21 +++++++++ .../src/git4idea/commands/GitImpl.java | 46 +++++++++++++++---- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/plugins/git4idea/src/git4idea/commands/GitCommandResult.java b/plugins/git4idea/src/git4idea/commands/GitCommandResult.java index 0683d738a9bf..e031fe47b72c 100644 --- a/plugins/git4idea/src/git4idea/commands/GitCommandResult.java +++ b/plugins/git4idea/src/git4idea/commands/GitCommandResult.java @@ -17,6 +17,7 @@ package git4idea.commands; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Function; +import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import git4idea.GitUtil; import org.jetbrains.annotations.NotNull; @@ -49,6 +50,26 @@ public class GitCommandResult { myException = exception; } + @NotNull + public static GitCommandResult merge(@Nullable GitCommandResult first, @NotNull GitCommandResult second) { + if (first == null) return second; + + int mergedExitCode; + if (first.myExitCode == 0) { + mergedExitCode = second.myExitCode; + } + else if (second.myExitCode == 0) { + mergedExitCode = first.myExitCode; + } + else { + mergedExitCode = second.myExitCode; // take exit code of the latest command + } + return new GitCommandResult(first.success() && second.success(), mergedExitCode, + ContainerUtil.concat(first.myErrorOutput, second.myErrorOutput), + ContainerUtil.concat(first.myOutput, second.myOutput), + ObjectUtils.chooseNotNull(second.myException, first.myException)); + } + /** * @return we think that the operation succeeded */ diff --git a/plugins/git4idea/src/git4idea/commands/GitImpl.java b/plugins/git4idea/src/git4idea/commands/GitImpl.java index e9da68d2e065..db3f45b77aa9 100644 --- a/plugins/git4idea/src/git4idea/commands/GitImpl.java +++ b/plugins/git4idea/src/git4idea/commands/GitImpl.java @@ -23,8 +23,13 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Function; +import com.intellij.util.ObjectUtils; +import com.intellij.util.containers.ContainerUtil; import com.intellij.vcsUtil.VcsFileUtil; -import git4idea.*; +import git4idea.GitCommit; +import git4idea.GitExecutionException; +import git4idea.GitVcs; import git4idea.config.GitVersionSpecialty; import git4idea.history.GitHistoryUtils; import git4idea.repo.GitRemote; @@ -50,7 +55,7 @@ import static java.util.Collections.singleton; @SuppressWarnings("StringToUpperCaseOrToLowerCaseWithoutLocale") public class GitImpl implements Git { - private final Logger LOG = Logger.getInstance(Git.class); + private static final Logger LOG = Logger.getInstance(Git.class); public GitImpl() { } @@ -173,13 +178,25 @@ public class GitImpl implements Git { @NotNull @Override - public GitCommandResult checkAttr(@NotNull GitRepository repository, @NotNull Collection attributes, + public GitCommandResult checkAttr(@NotNull final GitRepository repository, + @NotNull final Collection attributes, @NotNull Collection files) { - final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CHECK_ATTR); - h.addParameters(new ArrayList(attributes)); - h.endOptions(); - h.addRelativeFiles(files); - return run(h); + List> listOfPaths = VcsFileUtil.chunkFiles(repository.getRoot(), files); + return runAll(ContainerUtil.map(listOfPaths, new Function, Computable>() { + @Override + public Computable fun(final List relativePaths) { + return new Computable() { + @Override + public GitCommandResult compute() { + final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CHECK_ATTR); + h.addParameters(new ArrayList(attributes)); + h.endOptions(); + h.addParameters(relativePaths); + return run(h); + } + }; + } + })); } @NotNull @@ -638,6 +655,19 @@ public class GitImpl implements Git { }); } + @NotNull + private static GitCommandResult runAll(@NotNull List> commands) { + if (commands.isEmpty()) { + LOG.error("List of commands should not be empty", new Exception()); + return GitCommandResult.error("Internal error"); + } + GitCommandResult compoundResult = null; + for (Computable command : commands) { + compoundResult = GitCommandResult.merge(compoundResult, command.compute()); + } + return ObjectUtils.assertNotNull(compoundResult); + } + /** * Check if the line looks line an error message */ From d2220f8e91d2ee6b12198009b5ba89f410189913 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Sun, 9 Aug 2015 15:20:10 +0200 Subject: [PATCH 14/99] IDEA-143673 Incorrect duplicate: filling fields in similar constructors --- .../src/com/intellij/dupLocator/index/DuplicatesIndex.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java index cf0219e4e7b4..cead2d1bd109 100644 --- a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java +++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java @@ -56,7 +56,7 @@ public class DuplicatesIndex extends FileBasedIndexExtension NAME = ID.create("DuplicatesIndex"); - private static final int myBaseVersion = 20; + private static final int myBaseVersion = 21; private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() { @Override From b78c7213aa2a891d33df358803aa374731c1caac Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Sun, 9 Aug 2015 12:07:09 +0200 Subject: [PATCH 15/99] fix "getting service from write-action" warns in compiler tests --- .../src/com/intellij/compiler/CompilerTestUtil.java | 8 ++++---- .../src/com/intellij/testFramework/CompilerTester.java | 2 +- .../src/com/intellij/testFramework/PsiTestUtil.java | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java b/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java index 73613644878f..60c06b99de2c 100644 --- a/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java +++ b/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java @@ -79,23 +79,23 @@ public class CompilerTestUtil { } public static void enableExternalCompiler() { + ApplicationManagerEx.getApplicationEx().doNotSave(false); + final JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx(); new WriteAction() { @Override protected void run(@NotNull final Result result) { - ApplicationManagerEx.getApplicationEx().doNotSave(false); - JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx(); table.addJdk(table.getInternalJdk()); } }.execute(); } public static void disableExternalCompiler(final Project project) { + ApplicationManagerEx.getApplicationEx().doNotSave(true); + final JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx(); new WriteAction() { @Override protected void run(@NotNull final Result result) { - ApplicationManagerEx.getApplicationEx().doNotSave(true); Module[] modules = ModuleManager.getInstance(project).getModules(); - JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx(); Sdk internalJdk = table.getInternalJdk(); List modulesToRestore = new ArrayList(); for (Module module : modules) { diff --git a/java/testFramework/src/com/intellij/testFramework/CompilerTester.java b/java/testFramework/src/com/intellij/testFramework/CompilerTester.java index 09f5532c4b1d..ab85a3fabbee 100644 --- a/java/testFramework/src/com/intellij/testFramework/CompilerTester.java +++ b/java/testFramework/src/com/intellij/testFramework/CompilerTester.java @@ -69,12 +69,12 @@ public class CompilerTester { myMainOutput = new TempDirTestFixtureImpl(); myMainOutput.setUp(); + CompilerTestUtil.enableExternalCompiler(); new WriteCommandAction(getProject()) { @Override protected void run(@NotNull Result result) throws Throwable { //noinspection ConstantConditions CompilerProjectExtension.getInstance(getProject()).setCompilerOutputUrl(myMainOutput.findOrCreateDir("out").getUrl()); - CompilerTestUtil.enableExternalCompiler(); for (Module module : myModules) { ModuleRootModificationUtil.setModuleSdk(module, JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk()); } diff --git a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java index 624d25c8c782..afa500ee4c7e 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java +++ b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -299,10 +299,10 @@ public class PsiTestUtil { final String libName, final List classesRoots, final List sourceRoots) { + final LibraryTable libraryTable = ProjectLibraryTable.getInstance(module.getProject()); RunResult result = new WriteAction() { @Override protected void run(@NotNull Result result) throws Throwable { - LibraryTable libraryTable = ProjectLibraryTable.getInstance(module.getProject()); Library library = libraryTable.createLibrary(libName); Library.ModifiableModel libraryModel = library.getModifiableModel(); try { From 7ed2345402297544655886ee12477cda8a84a537 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Sun, 9 Aug 2015 12:07:29 +0200 Subject: [PATCH 16/99] fix NPE in tests --- .../com/intellij/execution/impl/ExecutionManagerImpl.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java index 63a11eda9f76..ad841c1d1c98 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java @@ -574,7 +574,10 @@ public class ExecutionManagerImpl extends ExecutionManager implements Disposable myProject.getMessageBus().syncPublisher(EXECUTION_TOPIC).processTerminated(myProfile, myProcessHandler); - SaveAndSyncHandler.getInstance().scheduleRefresh(); + SaveAndSyncHandler saveAndSyncHandler = SaveAndSyncHandler.getInstance(); + if (saveAndSyncHandler != null) { + saveAndSyncHandler.scheduleRefresh(); + } } @Override From 2890defc934f086f1419146193986c458b568787 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Sun, 9 Aug 2015 14:08:45 +0200 Subject: [PATCH 17/99] fix "getting service from write-action" warns in CodeInsightTestFixtureImpl --- .../fixtures/impl/CodeInsightTestFixtureImpl.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index a850c0424dba..e89f250a6559 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -56,9 +56,7 @@ import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.Result; -import com.intellij.openapi.application.WriteAction; +import com.intellij.openapi.application.*; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.*; @@ -1540,16 +1538,20 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig private PsiFile configureInner(@NotNull final VirtualFile copy, @NotNull final SelectionAndCaretMarkupLoader loader) { assertInitialized(); - new WriteCommandAction.Simple(getProject()) { + ApplicationManager.getApplication().invokeAndWait(new Runnable() { @Override public void run() { if (!copy.getFileType().isBinary()) { + AccessToken token = WriteAction.start(); try { copy.setBinaryContent(loader.newFileText.getBytes(copy.getCharset())); } catch (IOException e) { throw new RuntimeException(e); } + finally { + token.finish(); + } } myFile = copy; myEditor = createEditor(copy); @@ -1571,7 +1573,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig setupEditorForInjectedLanguage(); } } - }.execute().throwException(); + }, ModalityState.any()); return getFile(); } From ef4cb21533811a3f7d1d0c69443fb35790e86603 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Sun, 9 Aug 2015 16:46:51 +0200 Subject: [PATCH 18/99] set use.read.action.to.init.service to true again, until it is not clear why tests failed today --- .../src/ComponentStoreImpl.kt | 73 ++++++++++--------- .../components/impl/ServiceManagerImpl.java | 2 +- .../util/resources/misc/registry.properties | 2 +- 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/platform/configuration-store-impl/src/ComponentStoreImpl.kt b/platform/configuration-store-impl/src/ComponentStoreImpl.kt index 57e177df897d..7a16920da5c7 100644 --- a/platform/configuration-store-impl/src/ComponentStoreImpl.kt +++ b/platform/configuration-store-impl/src/ComponentStoreImpl.kt @@ -19,6 +19,7 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.PathManager import com.intellij.openapi.application.WriteAction import com.intellij.openapi.application.ex.DecodeDefaultsUtil +import com.intellij.openapi.application.runReadAction import com.intellij.openapi.components.* import com.intellij.openapi.components.StateStorage.SaveSession import com.intellij.openapi.components.StateStorageChooserEx.Resolution @@ -196,20 +197,22 @@ public abstract class ComponentStoreImpl : IComponentStore { return null } - try { - getDefaultState(component, componentName, javaClass())?.let { component.readExternal(it) } - } - catch (e: Throwable) { - LOG.error(e) - } + runReadAction { + try { + getDefaultState(component, componentName, javaClass())?.let { component.readExternal(it) } + } + catch (e: Throwable) { + LOG.error(e) + } - val element = getStateStorageManager().getOldStorage(component, componentName, StateStorageOperation.READ)?.getState(component, componentName, javaClass(), null) ?: return null - try { - component.readExternal(element) - } - catch (e: InvalidDataException) { - LOG.error(e) - return null + val element = getStateStorageManager().getOldStorage(component, componentName, StateStorageOperation.READ)?.getState(component, componentName, javaClass(), null) ?: return null + try { + component.readExternal(element) + } + catch (e: InvalidDataException) { + LOG.error(e) + return null + } } return componentName } @@ -240,31 +243,33 @@ public abstract class ComponentStoreImpl : IComponentStore { val defaultState = if (stateSpec.defaultStateAsResource) getDefaultState(component, name, stateClass) else null val storageSpecs = getStorageSpecs(component, stateSpec, StateStorageOperation.READ) val stateStorageChooser = component as? StateStorageChooserEx - for (storageSpec in storageSpecs) { - val resolution = if (stateStorageChooser == null) Resolution.DO else stateStorageChooser.getResolution(storageSpec, StateStorageOperation.READ) - if (resolution === Resolution.SKIP) { - continue - } - - val storage = getStateStorageManager().getStateStorage(storageSpec) - var state = storage.getState(component, name, stateClass, defaultState) - if (state == null) { - if (changedStorages != null && changedStorages.contains(storage)) { - // state will be null if file deleted - // we must create empty (initial) state to reinit component - state = DefaultStateSerializer.deserializeState(Element("state"), stateClass, null)!! - } - else { + runReadAction { + for (storageSpec in storageSpecs) { + val resolution = if (stateStorageChooser == null) Resolution.DO else stateStorageChooser.getResolution(storageSpec, StateStorageOperation.READ) + if (resolution === Resolution.SKIP) { continue } + + val storage = getStateStorageManager().getStateStorage(storageSpec) + var state = storage.getState(component, name, stateClass, defaultState) + if (state == null) { + if (changedStorages != null && changedStorages.contains(storage)) { + // state will be null if file deleted + // we must create empty (initial) state to reinit component + state = DefaultStateSerializer.deserializeState(Element("state"), stateClass, null)!! + } + else { + continue + } + } + + component.loadState(state) + return name } - component.loadState(state) - return name - } - - if (defaultState != null) { - component.loadState(defaultState) + if (defaultState != null) { + component.loadState(defaultState) + } } return name } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java index b8bc987fd22f..1faa0919f336 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java @@ -288,6 +288,6 @@ public class ServiceManagerImpl implements BaseComponent { } public static boolean isUseReadActionToInitService() { - return Registry.is("use.read.action.to.init.service", false); + return Registry.is("use.read.action.to.init.service", true); } } diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index f99f1d195d4d..5affd420ca95 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -639,7 +639,7 @@ editor.breadcrumbs.highlight.on.hover.description=Highlight corresponding ranges testDiscovery.enabled=false ruby.remote.debugger.supports.catchpoint.removal=true -use.read.action.to.init.service=false +use.read.action.to.init.service=true ruby.debugger.support.file.filtering=false color.blindness= From 3a67448f7561f00b2feb6cb87ab9c8f2b3296809 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Sun, 9 Aug 2015 18:52:44 +0300 Subject: [PATCH 19/99] =?UTF-8?q?fixed=20EDU-386=C3=97=20waiting=20for=20p?= =?UTF-8?q?ush=20Bring=20progress=20bar=20back?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/META-INF/plugin.xml | 1 + .../edu/learning/StudyProjectComponent.java | 19 ++++- .../jetbrains/edu/learning/StudyUtils.java | 14 ++-- .../learning/actions/StudyCheckAction.java | 2 +- .../actions/StudyRefreshTaskFileAction.java | 2 +- .../editor/StudyEditorFactoryListener.java | 2 +- .../ui/ProgressToolWindowFactory.java | 78 +++++++++++++++++++ .../edu/learning/ui/StudyProgressBar.java | 13 +++- .../edu/learning/ui/StudyToolWindow.java | 1 - 9 files changed, 116 insertions(+), 16 deletions(-) create mode 100644 python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/ProgressToolWindowFactory.java diff --git a/python/educational/interactive-learning/resources/META-INF/plugin.xml b/python/educational/interactive-learning/resources/META-INF/plugin.xml index 829febfd5e29..415a3729f1ca 100644 --- a/python/educational/interactive-learning/resources/META-INF/plugin.xml +++ b/python/educational/interactive-learning/resources/META-INF/plugin.xml @@ -70,6 +70,7 @@ serviceImplementation="com.jetbrains.edu.learning.stepic.StudySettings"/> + shortcut : myDeletedShortcuts.entrySet()) { final Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyUtils.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyUtils.java index 7bc796002890..73ba099fbc2e 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyUtils.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyUtils.java @@ -35,6 +35,7 @@ import com.jetbrains.edu.courseFormat.*; import com.jetbrains.edu.learning.editor.StudyEditor; import com.jetbrains.edu.learning.run.StudyExecutor; import com.jetbrains.edu.learning.run.StudyTestRunner; +import com.jetbrains.edu.learning.ui.ProgressToolWindowFactory; import com.jetbrains.edu.learning.ui.StudyToolWindowFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -118,12 +119,15 @@ public class StudyUtils { } } - public static void updateStudyToolWindow(@NotNull final Project project) { - ToolWindowManager.getInstance(project).getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW). - getContentManager().removeAllContents(false); + public static void updateToolWindows(@NotNull final Project project) { + final ToolWindowManager windowManager = ToolWindowManager.getInstance(project); + windowManager.getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW).getContentManager().removeAllContents(false); StudyToolWindowFactory factory = new StudyToolWindowFactory(); - factory.createToolWindowContent(project, ToolWindowManager.getInstance(project). - getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW)); + factory.createToolWindowContent(project, windowManager.getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW)); + + windowManager.getToolWindow(ProgressToolWindowFactory.ID).getContentManager().removeAllContents(false); + ProgressToolWindowFactory windowFactory = new ProgressToolWindowFactory(); + windowFactory.createToolWindowContent(project, windowManager.getToolWindow(ProgressToolWindowFactory.ID)); } public static void deleteFile(@NotNull final VirtualFile file) { diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java index f170f468cf60..f920f21d83c1 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java @@ -195,7 +195,7 @@ public class StudyCheckAction extends DumbAwareAction { return new com.intellij.openapi.progress.Task.Backgroundable(project, "Checking task", true) { @Override public void onSuccess() { - StudyUtils.updateStudyToolWindow(project); + StudyUtils.updateToolWindows(project); drawAllPlaceholders(project, task, taskDir); ProjectView.getInstance(project).refresh(); EduUtils.deleteWindowDescriptions(task, taskDir); diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java index 151aec37dd85..f36e544c1e4f 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java @@ -101,7 +101,7 @@ public class StudyRefreshTaskFileAction extends DumbAwareAction { } resetAnswerPlaceholders(taskFile, project); ProjectView.getInstance(project).refresh(); - StudyUtils.updateStudyToolWindow(project); + StudyUtils.updateToolWindows(project); return true; } diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyEditorFactoryListener.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyEditorFactoryListener.java index 9a5be326b733..37fbd9ada832 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyEditorFactoryListener.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyEditorFactoryListener.java @@ -82,7 +82,7 @@ public class StudyEditorFactoryListener implements EditorFactoryListener { editor.addEditorMouseListener(new WindowSelectionListener(taskFile)); final ToolWindow studyToolWindow = ToolWindowManager.getInstance(project).getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW); if (studyToolWindow != null) { - StudyUtils.updateStudyToolWindow(project); + StudyUtils.updateToolWindows(project); studyToolWindow.show(null); } diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/ProgressToolWindowFactory.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/ProgressToolWindowFactory.java new file mode 100644 index 000000000000..69d6f59980aa --- /dev/null +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/ProgressToolWindowFactory.java @@ -0,0 +1,78 @@ +package com.jetbrains.edu.learning.ui; + +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowFactory; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentFactory; +import com.intellij.util.ui.UIUtil; +import com.jetbrains.edu.EduNames; +import com.jetbrains.edu.courseFormat.Course; +import com.jetbrains.edu.courseFormat.Lesson; +import com.jetbrains.edu.courseFormat.Task; +import com.jetbrains.edu.learning.StudyTaskManager; +import com.jetbrains.edu.learning.courseFormat.StudyStatus; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.*; +import java.util.List; + +public class ProgressToolWindowFactory implements ToolWindowFactory, DumbAware { + public static final String ID = "Course Progress"; + + + @Override + public void createToolWindowContent(@NotNull final Project project, @NotNull final ToolWindow toolWindow) { + JPanel contentPanel = new JPanel(); + StudyTaskManager taskManager = StudyTaskManager.getInstance(project); + if (taskManager.getCourse() != null) { + contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.PAGE_AXIS)); + contentPanel.add(Box.createRigidArea(new Dimension(10, 0))); + + Course course = taskManager.getCourse(); + if (course == null) { + return; + } + int taskNum = 0; + int taskSolved = 0; + List lessons = course.getLessons(); + for (Lesson lesson : lessons) { + if (lesson.getName().equals(EduNames.PYCHARM_ADDITIONAL)) continue; + taskNum += lesson.getTaskList().size(); + taskSolved += getSolvedTasks(lesson, taskManager); + } + String completedTasks = String.format("%d of %d tasks completed", taskSolved, taskNum); + + double percent = (taskSolved * 100.0) / taskNum; + contentPanel.add(Box.createRigidArea(new Dimension(0, 10))); + StudyProgressBar studyProgressBar = new StudyProgressBar(percent / 100, 40, 10); + contentPanel.add(studyProgressBar); + contentPanel.add(Box.createRigidArea(new Dimension(0, 10))); + addStatistics(completedTasks, contentPanel); + contentPanel.setPreferredSize(new Dimension(100, 50)); + ContentFactory contentFactory = ContentFactory.SERVICE.getInstance(); + Content content = contentFactory.createContent(contentPanel, "", false); + contentPanel.setMinimumSize(new Dimension(300, 100)); + toolWindow.getContentManager().addContent(content); + } + } + + private static void addStatistics(String statistics, JPanel contentPanel) { + String labelText = UIUtil.toHtml(statistics, 5); + contentPanel.add(Box.createRigidArea(new Dimension(0, 10))); + JLabel statisticLabel = new JLabel(labelText); + contentPanel.add(statisticLabel); + } + + private static int getSolvedTasks(@NotNull final Lesson lesson, StudyTaskManager taskManager) { + int solved = 0; + for (Task task : lesson.getTaskList()) { + if (taskManager.getStatus(task) == StudyStatus.Solved) { + solved += 1; + } + } + return solved; + } +} diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyProgressBar.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyProgressBar.java index 2935d76e6691..c21aef13acb7 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyProgressBar.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyProgressBar.java @@ -20,11 +20,10 @@ public class StudyProgressBar extends JComponent implements DumbAware { private final int myHeight; private final int myIndent; private double myFraction = 0.0; - private Color myColor = JBColor.BLUE; + private static Color myColor = JBColor.GREEN; public StudyProgressBar(double fraction, int height, int indent) { myFraction = fraction; - myColor = JBColor.GREEN; myHeight = height; myIndent = indent; } @@ -43,7 +42,7 @@ public class StudyProgressBar extends JComponent implements DumbAware { Dimension size = getSize(); double width = size.getWidth() - 2*myIndent; - g2.setPaint(UIUtil.getListBackground()); + g2.setPaint(UIUtil.getTextFieldBackground()); Rectangle2D rect = new Rectangle2D.Double(myIndent, 0, width, myHeight); g2.fill(rect); @@ -53,7 +52,6 @@ public class StudyProgressBar extends JComponent implements DumbAware { int arcHeight = 5; g2.drawRoundRect(myIndent, 0, (int)width, myHeight, arcWidth, arcHeight); g2.setPaint(SHADOW2); - g2.drawRoundRect(myIndent, 0, (int)width, myHeight, arcWidth, arcHeight); int y_center = myHeight / 2; int y_steps = myHeight / 2 - 3; @@ -82,6 +80,13 @@ public class StudyProgressBar extends JComponent implements DumbAware { config.restore(); } + @Override + public Dimension getPreferredSize() { + Dimension dimension = super.getPreferredSize(); + dimension.height = myHeight + 10; + return dimension; + } + @Override public Dimension getMaximumSize() { Dimension dimension = super.getMaximumSize(); diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java index 9b2c505cb343..9703f587c109 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java @@ -68,7 +68,6 @@ public class StudyToolWindow extends SimpleToolWindowPanel implements DataProvid final FileEditorManagerListener listener = new StudyFileEditorManagerListener(project, taskTextPane); project.getMessageBus().connect().subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, listener); } - } public void dispose() { From d15589a4b6f20adb1b10a92025f93bf46d812b9e Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Sun, 9 Aug 2015 19:24:07 +0300 Subject: [PATCH 20/99] added authors to the courses according to new API --- .../resources/META-INF/plugin.xml | 4 +-- .../learning/actions/StudyCheckAction.java | 2 +- .../StudyProjectGenerator.java | 8 ++--- .../learning/stepic/StudySettingsPanel.java | 5 ++- .../edu/learning/ui/StudyNewProjectPanel.java | 11 ++++--- .../jetbrains/edu/courseFormat/Course.java | 21 ++++++------ .../com/jetbrains/edu/stepic/CourseInfo.java | 33 ++++++++++++------- .../edu/stepic/EduStepicConnector.java | 26 +++++++++++++-- .../com/jetbrains/edu/stepic/LoginDialog.java | 2 ++ .../jetbrains/edu}/stepic/StudySettings.java | 4 +-- 10 files changed, 77 insertions(+), 39 deletions(-) rename python/educational/{interactive-learning/src/com/jetbrains/edu/learning => src/com/jetbrains/edu}/stepic/StudySettings.java (97%) diff --git a/python/educational/interactive-learning/resources/META-INF/plugin.xml b/python/educational/interactive-learning/resources/META-INF/plugin.xml index 415a3729f1ca..d657d2f94516 100644 --- a/python/educational/interactive-learning/resources/META-INF/plugin.xml +++ b/python/educational/interactive-learning/resources/META-INF/plugin.xml @@ -66,8 +66,8 @@ - + diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java index f920f21d83c1..88ea6492ec32 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java @@ -47,7 +47,7 @@ import com.jetbrains.edu.learning.editor.StudyEditor; import com.jetbrains.edu.learning.navigation.StudyNavigator; import com.jetbrains.edu.learning.run.StudySmartChecker; import com.jetbrains.edu.learning.run.StudyTestRunner; -import com.jetbrains.edu.learning.stepic.StudySettings; +import com.jetbrains.edu.stepic.StudySettings; import com.jetbrains.edu.stepic.EduStepicConnector; import icons.InteractiveLearningIcons; import org.jetbrains.annotations.NotNull; diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java index 0d9821f94450..7bd9054b647b 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java @@ -467,12 +467,12 @@ public class StudyProjectGenerator { courseInfo = new CourseInfo(); courseInfo.setName(courseName); courseInfo.setDescription(courseDescription); - final ArrayList instructors = new ArrayList(); + final ArrayList authors = new ArrayList(); for (JsonElement author : courseAuthors) { - final String authorAsString = author.getAsString(); - instructors.add(new CourseInfo.Instructor(authorAsString)); + final JsonObject authorAsJsonObject = author.getAsJsonObject(); + authors.add(new CourseInfo.Author(authorAsJsonObject.get("first_name").getAsString(), authorAsJsonObject.get("last_name").getAsString())); } - courseInfo.setInstructors(instructors); + courseInfo.setAuthors(authors); } } catch (Exception e) { diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/stepic/StudySettingsPanel.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/stepic/StudySettingsPanel.java index c1fad93a3938..b3295c2d9ad8 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/stepic/StudySettingsPanel.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/stepic/StudySettingsPanel.java @@ -18,6 +18,7 @@ package com.jetbrains.edu.learning.stepic; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.DocumentAdapter; import com.jetbrains.edu.stepic.EduStepicConnector; +import com.jetbrains.edu.stepic.StudySettings; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -112,7 +113,9 @@ public class StudySettingsPanel { final StudySettings studySettings = StudySettings.getInstance(); studySettings.setLogin(getLogin()); studySettings.setPassword(getPassword()); - EduStepicConnector.login(getLogin(), getPassword()); + if (!StringUtil.isEmptyOrSpaces(getLogin()) && !StringUtil.isEmptyOrSpaces(getPassword())) { + EduStepicConnector.login(getLogin(), getPassword()); + } } resetCredentialsModification(); } diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java index a005bd7714c8..7fff347c61a6 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java @@ -16,7 +16,7 @@ import com.intellij.util.Consumer; import com.jetbrains.edu.courseFormat.Course; import com.jetbrains.edu.learning.StudyUtils; import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator; -import com.jetbrains.edu.learning.stepic.StudySettings; +import com.jetbrains.edu.stepic.StudySettings; import com.jetbrains.edu.stepic.CourseInfo; import com.jetbrains.edu.stepic.EduStepicConnector; import icons.InteractiveLearningIcons; @@ -58,10 +58,11 @@ public class StudyNewProjectPanel{ for (CourseInfo courseInfo : myAvailableCourses) { myCoursesComboBox.addItem(courseInfo); } - myAuthorLabel.setText("Author: " + Course.getAuthorsString(StudyUtils.getFirst(myAvailableCourses).getInstructors())); - myDescriptionLabel.setText(StudyUtils.getFirst(myAvailableCourses).getDescription()); + final CourseInfo selectedCourse = StudyUtils.getFirst(myAvailableCourses); + myAuthorLabel.setText("Author: " + Course.getAuthorsString(selectedCourse.getAuthors())); + myDescriptionLabel.setText(selectedCourse.getDescription()); //setting the first course in list as selected - myGenerator.setSelectedCourse(StudyUtils.getFirst(myAvailableCourses)); + myGenerator.setSelectedCourse(selectedCourse); setOK(); } initListeners(); @@ -208,7 +209,7 @@ public class StudyNewProjectPanel{ myDescriptionLabel.setText(""); return; } - myAuthorLabel.setText("Author: " + Course.getAuthorsString(selectedCourse.getInstructors())); + myAuthorLabel.setText("Author: " + Course.getAuthorsString(selectedCourse.getAuthors())); myCoursesComboBox.removeItem(CourseInfo.INVALID_COURSE); myDescriptionLabel.setText(selectedCourse.getDescription()); myGenerator.setSelectedCourse(selectedCourse); diff --git a/python/educational/src/com/jetbrains/edu/courseFormat/Course.java b/python/educational/src/com/jetbrains/edu/courseFormat/Course.java index 98fdc0ea0e68..f891962d084a 100644 --- a/python/educational/src/com/jetbrains/edu/courseFormat/Course.java +++ b/python/educational/src/com/jetbrains/edu/courseFormat/Course.java @@ -20,7 +20,7 @@ public class Course implements Named { @Expose private String description; @Expose private String name; private String myCourseDirectory = ""; - @Expose private List authors = new ArrayList(); + @Expose private List authors = new ArrayList(); private boolean myUpToDate; @Expose @SerializedName("language") @@ -62,23 +62,24 @@ public class Course implements Named { } @NotNull - public List getAuthors() { + public List getAuthors() { return authors; } - public static String getAuthorsString(@NotNull List authors) { - return StringUtil.join(authors, new Function() { + public static String getAuthorsString(@NotNull List authors) { + return StringUtil.join(authors, new Function() { @Override - public String fun(CourseInfo.Instructor instructor) { - return instructor.getName(); + public String fun(CourseInfo.Author author) { + return author.getName(); } }, ", "); } public void setAuthors(String[] authors) { - this.authors = new ArrayList(); + this.authors = new ArrayList(); for (String name : authors) { - this.authors.add(new CourseInfo.Instructor(name)); + final List pair = StringUtil.split(name, " "); + this.authors.add(new CourseInfo.Author(pair.get(0), pair.size() > 1 ? pair.get(1) : "")); } } @@ -126,8 +127,8 @@ public class Course implements Named { myLanguage = language; } - public void setAuthors(List instructors) { - this.authors = instructors; + public void setAuthors(List authors) { + this.authors = authors; } public String getCourseType() { diff --git a/python/educational/src/com/jetbrains/edu/stepic/CourseInfo.java b/python/educational/src/com/jetbrains/edu/stepic/CourseInfo.java index 95a33aaf4ec3..195ea0dccf87 100644 --- a/python/educational/src/com/jetbrains/edu/stepic/CourseInfo.java +++ b/python/educational/src/com/jetbrains/edu/stepic/CourseInfo.java @@ -1,6 +1,7 @@ package com.jetbrains.edu.stepic; import com.google.gson.annotations.SerializedName; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -21,8 +22,9 @@ public class CourseInfo { //course type in format "pycharm " private String myType = "pycharm Python"; - @SerializedName("instructors_deprecated") - List myInstructors = new ArrayList(); + List instructors = new ArrayList(); + + List myAuthors = new ArrayList(); int id; public static CourseInfo INVALID_COURSE = new CourseInfo(); @@ -32,8 +34,8 @@ public class CourseInfo { } @NotNull - public List getInstructors() { - return myInstructors; + public List getAuthors() { + return myAuthors; } public String getDescription() { @@ -66,15 +68,17 @@ public class CourseInfo { return result; } - public static class Instructor { - String name; + public static class Author { + String first_name; + String last_name; - public Instructor(String name) { - this.name = name; + public Author(String firstName, String lastName) { + first_name = firstName; + last_name = lastName; } public String getName() { - return name; + return StringUtil.join(new String[]{first_name, last_name}, " "); } } @@ -82,8 +86,15 @@ public class CourseInfo { myName = name; } - public void setInstructors(List instructors) { - myInstructors = instructors; + public void setAuthors(List authors) { + myAuthors = authors; + } + + public void addAuthor(Author author) { + if (myAuthors == null) { + myAuthors = new ArrayList(); + } + myAuthors.add(author); } public void setDescription(String description) { diff --git a/python/educational/src/com/jetbrains/edu/stepic/EduStepicConnector.java b/python/educational/src/com/jetbrains/edu/stepic/EduStepicConnector.java index d9dcf15df729..1546b88d225c 100644 --- a/python/educational/src/com/jetbrains/edu/stepic/EduStepicConnector.java +++ b/python/educational/src/com/jetbrains/edu/stepic/EduStepicConnector.java @@ -57,7 +57,6 @@ public class EduStepicConnector { private static final String stepicUrl = "https://stepic.org/"; private static final String stepicApiUrl = stepicUrl + "api/"; private static final Logger LOG = Logger.getInstance(EduStepicConnector.class.getName()); - private static final String ourDomain = "stepic.org"; private static String ourCSRFToken = ""; private static CloseableHttpClient ourClient; @@ -139,6 +138,7 @@ public class EduStepicConnector { try { final CloseableHttpResponse response = ourClient.execute(request); + final String s = EntityUtils.toString(response.getEntity()); saveCSRFToken(); final StatusLine line = response.getStatusLine(); if (line.getStatusCode() != 302) { @@ -191,6 +191,12 @@ public class EduStepicConnector { if (StringUtil.isEmptyOrSpaces(courseType)) continue; final List typeLanguage = StringUtil.split(courseType, " "); if (typeLanguage.size() == 2 && PYCHARM_PREFIX.equals(typeLanguage.get(0))) { + + for (Integer instructor : info.instructors) { + final CourseInfo.Author author = getFromStepic("users/" + String.valueOf(instructor), AuthorWrapper.class).users.get(0); + info.addAuthor(author); + } + result.add(info); } } @@ -199,7 +205,7 @@ public class EduStepicConnector { public static Course getCourse(@NotNull final CourseInfo info) { final Course course = new Course(); - course.setAuthors(info.getInstructors()); + course.setAuthors(info.getAuthors()); course.setDescription(info.getDescription()); course.setName(info.getName()); String courseType = info.getType(); @@ -330,7 +336,17 @@ public class EduStepicConnector { public static void postCourse(Project project, @NotNull final Course course) { final HttpPost request = new HttpPost(stepicApiUrl + "courses"); if (ourClient == null) { - showLoginDialog(); + final String login = StudySettings.getInstance().getLogin(); + if (StringUtil.isEmptyOrSpaces(login)) { + showLoginDialog(); + } + else { + final boolean success = login(login, StudySettings.getInstance().getPassword()); + if (!success) { + LOG.error("Failed to push course. Failed to login."); // TODO: show notification + return; + } + } } setHeaders(request, "application/json"); @@ -692,6 +708,10 @@ public class EduStepicConnector { } } + static class AuthorWrapper { + List users; + } + static class SubmissionWrapper { Submission submission; diff --git a/python/educational/src/com/jetbrains/edu/stepic/LoginDialog.java b/python/educational/src/com/jetbrains/edu/stepic/LoginDialog.java index a670e83bc1b0..d71c6206bf86 100644 --- a/python/educational/src/com/jetbrains/edu/stepic/LoginDialog.java +++ b/python/educational/src/com/jetbrains/edu/stepic/LoginDialog.java @@ -39,6 +39,8 @@ public class LoginDialog extends DialogWrapper { @Override protected void doOKAction() { AuthDataHolder authData = myLoginPanel.getAuthData(); + StudySettings.getInstance().setLogin(authData.email); + StudySettings.getInstance().setPassword(authData.password); final boolean success = EduStepicConnector.login(authData.email, authData.password); if (!success) { setErrorText("Log in failed"); diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/stepic/StudySettings.java b/python/educational/src/com/jetbrains/edu/stepic/StudySettings.java similarity index 97% rename from python/educational/interactive-learning/src/com/jetbrains/edu/learning/stepic/StudySettings.java rename to python/educational/src/com/jetbrains/edu/stepic/StudySettings.java index 466dd681e7d9..c3f673149d54 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/stepic/StudySettings.java +++ b/python/educational/src/com/jetbrains/edu/stepic/StudySettings.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.jetbrains.edu.learning.stepic; +package com.jetbrains.edu.stepic; import com.intellij.ide.passwordSafe.PasswordSafe; import com.intellij.ide.passwordSafe.PasswordSafeException; @@ -25,7 +25,7 @@ import org.jetbrains.annotations.Nullable; @SuppressWarnings("MethodMayBeStatic") @State( - name = "GithubSettings", + name = "StudySettings", storages = {@Storage( file = StoragePathMacros.APP_CONFIG + "/stepic_settings.xml")}) public class StudySettings implements PersistentStateComponent { From 98456a25c2324f7298abd54de1ec6ed0d14064b9 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 10 Aug 2015 08:05:13 +0200 Subject: [PATCH 21/99] speedup vcs tests by doing change refresh immediately --- .../intellij/openapi/vcs/changes/UpdateRequestsQueue.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java index dfe9c9b8474d..9b064f67b38c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java @@ -158,6 +158,10 @@ public class UpdateRequestsQueue { return; } + if (!myRequestRunning) { + myExecutor.get().schedule(new MyRunnable(), 0, TimeUnit.MILLISECONDS); + } + semaphore.down(); myWaitingUpdateCompletionSemaphores.add(semaphore); } @@ -236,6 +240,8 @@ public class UpdateRequestsQueue { final List copy = new ArrayList(myWaitingUpdateCompletionQueue.size()); try { synchronized (myLock) { + if (!myRequestSubmitted) return; + LOG.assertTrue(!myRequestRunning); myRequestRunning = true; if (myStopped) { From 7c75890433e520198a8753e572c71116e62cdb74 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Sun, 9 Aug 2015 12:48:40 +0200 Subject: [PATCH 22/99] use StateMap directly (if you need only load, it is enough) --- .../src/ModuleStateStorageManager.kt | 3 +- .../components/impl/stores/FileStorage.java | 2 +- .../com/intellij/core/CoreModuleManager.java | 4 +-- .../com/intellij/core/CoreProjectLoader.java | 13 +++---- .../components/impl/stores/StorageData.java | 35 +++---------------- .../impl/stores/StorageDataBase.java | 34 ++++++++++++++++++ 6 files changed, 51 insertions(+), 40 deletions(-) diff --git a/platform/configuration-store-impl/src/ModuleStateStorageManager.kt b/platform/configuration-store-impl/src/ModuleStateStorageManager.kt index a59b13b3dbf3..2b5e5563bcf3 100644 --- a/platform/configuration-store-impl/src/ModuleStateStorageManager.kt +++ b/platform/configuration-store-impl/src/ModuleStateStorageManager.kt @@ -20,6 +20,7 @@ import com.intellij.openapi.components.StateStorage import com.intellij.openapi.components.StateStorageOperation import com.intellij.openapi.components.StoragePathMacros import com.intellij.openapi.components.TrackingPathMacroSubstitutor +import com.intellij.openapi.components.impl.stores.StorageData import com.intellij.openapi.module.Module import com.intellij.openapi.module.impl.ModuleEx import com.intellij.openapi.module.impl.ModuleManagerImpl @@ -36,7 +37,7 @@ class ModuleStateStorageManager(macroSubstitutor: TrackingPathMacroSubstitutor, private class MyStateStorageManagerExternalizationSession(storageManager: StateStorageManagerImpl) : StateStorageManagerImpl.StateStorageManagerExternalizationSession(storageManager) { override fun createSaveSessions(): List { val storage = ContainerUtil.getFirstItem(storageManager.getCachedFileStorages(listOf(StoragePathMacros.MODULE_FILE))) - if (storage != null && storage.getStorageData().isDirty()) { + if (storage != null && (storage.getStorageData() as StorageData).isDirty()) { // force XmlElementStorageSaveSession creation getExternalizationSession(storage) } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileStorage.java index 06e2d00d3236..ce74a828eb32 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileStorage.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileStorage.java @@ -30,7 +30,7 @@ public interface FileStorage extends StateStorage { File getFile(); // todo remove - StorageData getStorageData(); + StorageDataBase getStorageData(); // todo remove void setFile(@Nullable VirtualFile file, @Nullable File ioFileIfChanged); diff --git a/platform/projectModel-impl/src/com/intellij/core/CoreModuleManager.java b/platform/projectModel-impl/src/com/intellij/core/CoreModuleManager.java index e3b9a2380066..c16de22e8a39 100644 --- a/platform/projectModel-impl/src/com/intellij/core/CoreModuleManager.java +++ b/platform/projectModel-impl/src/com/intellij/core/CoreModuleManager.java @@ -16,7 +16,7 @@ package com.intellij.core; import com.intellij.openapi.Disposable; -import com.intellij.openapi.components.impl.stores.StorageData; +import com.intellij.openapi.components.impl.stores.StateMap; import com.intellij.openapi.module.impl.ModuleEx; import com.intellij.openapi.module.impl.ModuleManagerImpl; import com.intellij.openapi.project.Project; @@ -53,7 +53,7 @@ public class CoreModuleManager extends ModuleManagerImpl { VirtualFile vFile = StandardFileSystems.local().findFileByPath(filePath); try { assert vFile != null; - StorageData storageData = CoreProjectLoader.loadStorageFile(module, vFile); + StateMap storageData = CoreProjectLoader.loadStorageFile(module, vFile); ModuleRootManagerImpl.ModuleRootManagerState state = new ModuleRootManagerImpl.ModuleRootManagerState(); state.readExternal(storageData.getState("NewModuleRootManager")); ((ModuleRootManagerImpl) ModuleRootManager.getInstance(module)).loadState(state); diff --git a/platform/projectModel-impl/src/com/intellij/core/CoreProjectLoader.java b/platform/projectModel-impl/src/com/intellij/core/CoreProjectLoader.java index 24bf0829035c..0c6f3543044d 100644 --- a/platform/projectModel-impl/src/com/intellij/core/CoreProjectLoader.java +++ b/platform/projectModel-impl/src/com/intellij/core/CoreProjectLoader.java @@ -20,7 +20,8 @@ import com.intellij.openapi.components.ComponentManager; import com.intellij.openapi.components.PathMacroManager; import com.intellij.openapi.components.impl.stores.DefaultStateSerializer; import com.intellij.openapi.components.impl.stores.DirectoryStorageData; -import com.intellij.openapi.components.impl.stores.StorageData; +import com.intellij.openapi.components.impl.stores.StateMap; +import com.intellij.openapi.components.impl.stores.StorageDataBase; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; @@ -63,7 +64,7 @@ public class CoreProjectLoader { if (modulesXml == null) throw new FileNotFoundException("Missing 'modules.xml' in " + dotIdea.getPath()); - StorageData storageData = loadStorageFile(project, modulesXml); + StateMap storageData = loadStorageFile(project, modulesXml); final Element moduleManagerState = storageData.getState("ProjectModuleManager"); if (moduleManagerState == null) { throw new JDOMException("cannot find ProjectModuleManager state in modules.xml"); @@ -94,9 +95,9 @@ public class CoreProjectLoader { } @NotNull - public static StorageData loadStorageFile(@NotNull ComponentManager componentManager, @NotNull VirtualFile modulesXml) throws JDOMException, IOException { - StorageData storageData = new StorageData(); - storageData.load(JDOMUtil.loadDocument(modulesXml.contentsToByteArray()).getRootElement(), PathMacroManager.getInstance(componentManager), false); - return storageData; + public static StateMap loadStorageFile(@NotNull ComponentManager componentManager, @NotNull VirtualFile modulesXml) throws JDOMException, IOException { + StateMap states = new StateMap(); + StorageDataBase.load(states, JDOMUtil.loadDocument(modulesXml.contentsToByteArray()).getRootElement(), PathMacroManager.getInstance(componentManager), false); + return states; } } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java index b01347330cbd..a741fc582e5b 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java @@ -15,21 +15,21 @@ */ package com.intellij.openapi.components.impl.stores; -import com.intellij.application.options.PathMacrosCollector; import com.intellij.openapi.components.PathMacroSubstitutor; -import com.intellij.openapi.components.TrackingPathMacroSubstitutor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.JDOMUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.SmartHashSet; -import com.intellij.util.containers.StringInterner; import org.jdom.Attribute; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; -import java.util.*; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; import static com.intellij.openapi.components.impl.stores.StateMap.getNewByteIfDiffers; @@ -57,32 +57,7 @@ public class StorageData extends StorageDataBase { } public void load(@NotNull Element rootElement, @Nullable PathMacroSubstitutor pathMacroSubstitutor, boolean intern) { - if (pathMacroSubstitutor != null) { - pathMacroSubstitutor.expandPaths(rootElement); - } - - StringInterner interner = intern ? new StringInterner() : null; - for (Iterator iterator = rootElement.getChildren(COMPONENT).iterator(); iterator.hasNext(); ) { - Element element = iterator.next(); - String name = getComponentNameIfValid(element); - if (name == null || !(element.getAttributes().size() > 1 || !element.getChildren().isEmpty())) { - continue; - } - - iterator.remove(); - if (interner != null) { - JDOMUtil.internElement(element, interner); - } - - myStates.put(name, element); - - if (pathMacroSubstitutor instanceof TrackingPathMacroSubstitutor) { - ((TrackingPathMacroSubstitutor)pathMacroSubstitutor).addUnknownMacros(name, PathMacrosCollector.getMacroNames(element)); - } - - // remove only after "getMacroNames" - some PathMacroFilter requires element name attribute - element.removeAttribute(NAME); - } + load(myStates, rootElement, pathMacroSubstitutor, intern); } @Nullable diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageDataBase.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageDataBase.java index 1f659ebfaa48..4815faf1c4df 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageDataBase.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageDataBase.java @@ -15,13 +15,18 @@ */ package com.intellij.openapi.components.impl.stores; +import com.intellij.application.options.PathMacrosCollector; +import com.intellij.openapi.components.PathMacroSubstitutor; +import com.intellij.openapi.components.TrackingPathMacroSubstitutor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.StringInterner; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Iterator; import java.util.Set; public abstract class StorageDataBase { @@ -44,4 +49,33 @@ public abstract class StorageDataBase { } return name; } + + public static void load(@NotNull StateMap states, @NotNull Element rootElement, @Nullable PathMacroSubstitutor pathMacroSubstitutor, boolean intern) { + if (pathMacroSubstitutor != null) { + pathMacroSubstitutor.expandPaths(rootElement); + } + + StringInterner interner = intern ? new StringInterner() : null; + for (Iterator iterator = rootElement.getChildren(COMPONENT).iterator(); iterator.hasNext(); ) { + Element element = iterator.next(); + String name = getComponentNameIfValid(element); + if (name == null || !(element.getAttributes().size() > 1 || !element.getChildren().isEmpty())) { + continue; + } + + iterator.remove(); + if (interner != null) { + JDOMUtil.internElement(element, interner); + } + + states.put(name, element); + + if (pathMacroSubstitutor instanceof TrackingPathMacroSubstitutor) { + ((TrackingPathMacroSubstitutor)pathMacroSubstitutor).addUnknownMacros(name, PathMacrosCollector.getMacroNames(element)); + } + + // remove only after "getMacroNames" - some PathMacroFilter requires element name attribute + element.removeAttribute(NAME); + } + } } \ No newline at end of file From 3adb49379e1cc9f04e2609573878a9226b620265 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Sun, 9 Aug 2015 13:08:24 +0200 Subject: [PATCH 23/99] =?UTF-8?q?comment=20registerProjectLevelProviders?= =?UTF-8?q?=20=E2=80=94=20not=20yet=20supported=20in=20any=20case?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/StateStorageManagerImpl.kt | 16 ++++++---------- plugins/settings-repository/src/IcsManager.kt | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt index 3ab69bf21d90..49286cfe0e37 100644 --- a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt +++ b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt @@ -185,13 +185,7 @@ open class StateStorageManagerImpl(private val rootTagName: String, val file = File(filePath) if (isUseVfsListener == ThreeState.UNSURE) { - if (streamProvider != null && streamProvider!!.enabled) { - isUseVfsListener = ThreeState.NO - } - else { - isUseVfsListener = ThreeState.YES -// addVfsChangesListener(componentManager!!) - } + isUseVfsListener = ThreeState.fromBoolean(streamProvider == null || !streamProvider!!.enabled) } //noinspection deprecation @@ -207,7 +201,9 @@ open class StateStorageManagerImpl(private val rootTagName: String, val effectiveRoamingType = if (roamingType == RoamingType.PER_USER && fileSpec == StoragePathMacros.WORKSPACE_FILE) RoamingType.DISABLED else roamingType val storage = MyFileStorage(this, file, fileSpec, rootTagName, effectiveRoamingType, getMacroSubstitutor(fileSpec), streamProvider) - virtualFileTracker?.put(filePath.normalizePath(), storage) + if (isUseVfsListener == ThreeState.YES) { + virtualFileTracker?.put(filePath.normalizePath(), storage) + } return storage } @@ -217,9 +213,9 @@ open class StateStorageManagerImpl(private val rootTagName: String, file: File, fileSpec: String, rootElementName: String, - roamingType: RoamingType? = null, + roamingType: RoamingType, pathMacroManager: TrackingPathMacroSubstitutor? = null, - streamProvider: StreamProvider? = null) : FileBasedStorage(file, fileSpec, rootElementName, pathMacroManager, roamingType, streamProvider), StorageVirtualFileTracker.TrackedStorage { + provider: StreamProvider? = null) : FileBasedStorage(file, fileSpec, rootElementName, pathMacroManager, roamingType, provider), StorageVirtualFileTracker.TrackedStorage { override val isUseXmlProlog: Boolean get() = storageManager.isUseXmlProlog diff --git a/plugins/settings-repository/src/IcsManager.kt b/plugins/settings-repository/src/IcsManager.kt index 2ed16ba1592a..04a3074f9997 100644 --- a/plugins/settings-repository/src/IcsManager.kt +++ b/plugins/settings-repository/src/IcsManager.kt @@ -184,7 +184,7 @@ class IcsManager(dir: File) { return } - registerProjectLevelProviders(project) + //registerProjectLevelProviders(project) autoSyncManager.registerListeners(project) } From 26e53b01754f88a4a88bf00820d9c63276e017a3 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Sun, 9 Aug 2015 14:42:36 +0200 Subject: [PATCH 24/99] cleanup --- .../ProjectStoreBaseTestCase.java | 25 ++++++------------- .../ProjectStoreImplIdeaDirTest.java | 8 +++--- .../ProjectStoreImplIprFileTest.java | 6 ++--- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreBaseTestCase.java b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreBaseTestCase.java index f23116183908..60b27370ba14 100644 --- a/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreBaseTestCase.java +++ b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreBaseTestCase.java @@ -20,8 +20,6 @@ import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ex.ProjectManagerEx; -import com.intellij.openapi.util.JDOMBuilder; -import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.testFramework.PlatformTestCase; @@ -35,23 +33,16 @@ public abstract class ProjectStoreBaseTestCase extends PlatformTestCase { } protected byte[] getIprFileContent() throws UnsupportedEncodingException { - final String iprContent = JDOMUtil.writeDocument( - JDOMBuilder.document(JDOMBuilder.tag("project", - JDOMBuilder.attr("version", "4"), - JDOMBuilder.tag("component", JDOMBuilder.attr("name", "TestIprComponent"), - JDOMBuilder.tag("option", JDOMBuilder.attr("name", "VALUE"), JDOMBuilder.attr("value", "true"))) - )), - "\n"); - return iprContent.getBytes(CharsetToolkit.UTF8); + return ("" + + "" + + " " + + " " + + "").getBytes(CharsetToolkit.UTF8); } - @State( - name = "TestIprComponent", - storages = { - @Storage(file = "$PROJECT_FILE$") - } - ) - public static class TestIprComponent implements PersistentStateComponent { + @State(name = "TestComponent", storages = @Storage(file = "$PROJECT_FILE$")) + public static class TestComponent implements PersistentStateComponent { ProjectStoreBaseTestCase.DataBean myState; @Override diff --git a/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreImplIdeaDirTest.java b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreImplIdeaDirTest.java index 553b46f9f1a1..f583a302f00d 100644 --- a/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreImplIdeaDirTest.java +++ b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreImplIdeaDirTest.java @@ -26,7 +26,7 @@ import java.io.IOException; public class ProjectStoreImplIdeaDirTest extends ProjectStoreBaseTestCase { @Override protected File getIprFile() throws IOException { - final File projectDir = FileUtil.createTempDirectory(getTestName(true), "project"); + File projectDir = FileUtil.createTempDirectory(getTestName(true), "project"); File ideaDir = new File(projectDir, Project.DIRECTORY_STORE_FOLDER); assertTrue(ideaDir.mkdir() || ideaDir.isDirectory()); File iprFile = new File(ideaDir, "misc.xml"); @@ -39,8 +39,8 @@ public class ProjectStoreImplIdeaDirTest extends ProjectStoreBaseTestCase { public void testLoadFromDirectoryStorage() throws Exception { ((ProjectEx)myProject).setOptimiseTestLoadSpeed(false); - final TestIprComponent testIprComponent = new TestIprComponent(); - ComponentsPackage.getStateStore(myProject).initComponent(testIprComponent, false); - assertNotNull(testIprComponent.myState); + TestComponent testComponent = new TestComponent(); + ComponentsPackage.getStateStore(myProject).initComponent(testComponent, false); + assertNotNull(testComponent.myState); } } diff --git a/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreImplIprFileTest.java b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreImplIprFileTest.java index 24328b4da88c..2de8713e3958 100644 --- a/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreImplIprFileTest.java +++ b/platform/configuration-store-impl/testSrc/com/intellij/configurationStore/ProjectStoreImplIprFileTest.java @@ -34,8 +34,8 @@ public class ProjectStoreImplIprFileTest extends ProjectStoreBaseTestCase { ((ProjectEx)myProject).setOptimiseTestLoadSpeed(false); - final TestIprComponent testIprComponent = new TestIprComponent(); - ComponentsPackage.getStateStore(myProject).initComponent(testIprComponent, false); - assertNotNull(testIprComponent.myState); + final TestComponent testComponent = new TestComponent(); + ComponentsPackage.getStateStore(myProject).initComponent(testComponent, false); + assertNotNull(testComponent.myState); } } From 8563043ac203b6bb2c764133dd643bf4897aca38 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 10 Aug 2015 08:18:01 +0200 Subject: [PATCH 25/99] smart pointer cleanup --- .../SmartPsiElementPointersTest.java | 31 ---------- .../impl/smartPointers/AnchorElementInfo.java | 5 +- .../impl/smartPointers/ClsElementInfo.java | 24 +------- .../impl/smartPointers/FileElementInfo.java | 21 +------ .../impl/smartPointers/HardElementInfo.java | 21 +------ .../InjectedSelfElementInfo.java | 13 +---- .../impl/smartPointers/SelfElementInfo.java | 10 +--- .../SmartPointerElementInfo.java | 30 +++++----- .../impl/smartPointers/SmartPointerEx.java | 6 +- .../SmartPointerManagerImpl.java | 56 +------------------ .../SmartPsiElementPointerImpl.java | 10 +--- .../tree/MarkersHolderFileViewProvider.java | 25 --------- .../impl/SmartPointerEditorTracker.java | 28 +--------- .../psi/impl/file/impl/PsiVFSListener.java | 3 +- .../injected/InjectedFileViewProvider.java | 18 +----- 15 files changed, 35 insertions(+), 266 deletions(-) delete mode 100644 platform/core-impl/src/com/intellij/psi/impl/source/tree/MarkersHolderFileViewProvider.java diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java b/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java index e653f3f26147..9eaae9dbfa58 100644 --- a/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java @@ -28,8 +28,6 @@ import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.editor.event.DocumentListener; import com.intellij.openapi.editor.event.EditorEventMulticaster; import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.fileEditor.FileEditor; -import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileTypes.PlainTextFileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.util.Segment; @@ -672,35 +670,6 @@ public class SmartPsiElementPointersTest extends CodeInsightTestCase { assertNotNull(node); } - public void testSmartPointersForOpenFilesAreFastened() { - PsiJavaFile file = (PsiJavaFile)myJavaFacade.findClass("AClass", GlobalSearchScope.allScope(getProject())).getContainingFile(); - - SmartPointerManagerImpl manager = (SmartPointerManagerImpl)SmartPointerManager.getInstance(myProject); - VirtualFile virtualFile = file.getVirtualFile(); - - assertFalse(manager.areBeltsFastened(virtualFile)); - FileEditor[] editors = FileEditorManager.getInstance(myProject).openFile(virtualFile, true); - assertTrue(editors.length != 0); - - assertTrue(manager.areBeltsFastened(virtualFile)); - - FileEditorManager.getInstance(myProject).closeFile(virtualFile); - assertFalse(manager.areBeltsFastened(virtualFile)); - - SmartPsiElementPointer pointer = manager.createSmartPsiElementPointer(file.getClasses()[0]); - - assertFalse(manager.areBeltsFastened(virtualFile)); - editors = FileEditorManager.getInstance(myProject).openFile(virtualFile, true); - assertTrue(editors.length != 0); - - assertTrue(manager.areBeltsFastened(virtualFile)); - - FileEditorManager.getInstance(myProject).closeFile(virtualFile); - assertFalse(manager.areBeltsFastened(virtualFile)); - - assertEquals(file.getClasses()[0], pointer.getElement()); // retain pointer from gc - } - public void testLargeFileWithManyChanges() { configureByText(PlainTextFileType.INSTANCE, StringUtil.repeat("foo foo \n", 50000)); final TextRange range = TextRange.from(10, 10); diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java index 0a7bdd6f12a5..2c6d23fd1727 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java @@ -18,7 +18,6 @@ package com.intellij.psi.impl.smartPointers; import com.intellij.lang.LanguageUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.util.*; import com.intellij.psi.PsiAnchor; import com.intellij.psi.PsiElement; @@ -110,11 +109,11 @@ class AnchorElementInfo extends SelfElementInfo { } @Override - public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) { + public void fastenBelt() { if (getStubId() != -1) { switchToTree(); } - super.fastenBelt(offset, cachedRangeMarker); + super.fastenBelt(); } private void switchToTree() { diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/ClsElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/ClsElementInfo.java index adb5206dc6e6..4d947cb83f3e 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/ClsElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/ClsElementInfo.java @@ -15,8 +15,6 @@ */ package com.intellij.psi.impl.smartPointers; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Segment; @@ -29,28 +27,13 @@ import org.jetbrains.annotations.NotNull; /** * User: cdr */ -public class ClsElementInfo implements SmartPointerElementInfo { +public class ClsElementInfo extends SmartPointerElementInfo { private final PsiAnchor.StubIndexReference myStubIndexReference; public ClsElementInfo(@NotNull PsiAnchor.StubIndexReference stubReference) { myStubIndexReference = stubReference; } - @Override - public Document getDocumentToSynchronize() { - return null; - } - - // before change - @Override - public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) { - } - - // after change - @Override - public void unfastenBelt(int offset) { - } - @Override public PsiElement restoreElement() { return myStubIndexReference.retrieve(); @@ -85,11 +68,6 @@ public class ClsElementInfo implements SmartPointerElementInfo { return myStubIndexReference.getProject(); } - @Override - public void cleanup() { - - } - @Override public PsiFile restoreFile() { return myStubIndexReference.getFile(); diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java index 5f99cb3c4df8..e7da9a06dc73 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java @@ -16,8 +16,6 @@ package com.intellij.psi.impl.smartPointers; import com.intellij.lang.Language; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Segment; @@ -30,7 +28,7 @@ import org.jetbrains.annotations.NotNull; /** * User: cdr */ -class FileElementInfo implements SmartPointerElementInfo { +class FileElementInfo extends SmartPointerElementInfo { protected final VirtualFile myVirtualFile; protected final Project myProject; protected final Language myLanguage; @@ -48,19 +46,6 @@ class FileElementInfo implements SmartPointerElementInfo { myLanguage = lang; } - @Override - public Document getDocumentToSynchronize() { - return null; - } - - @Override - public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) { - } - - @Override - public void unfastenBelt(int offset) { - } - @Override public PsiElement restoreElement() { return SelfElementInfo.restoreFileFromVirtual(myVirtualFile, myProject, myLanguage); @@ -105,8 +90,4 @@ class FileElementInfo implements SmartPointerElementInfo { return myProject; } - @Override - public void cleanup() { - - } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/HardElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/HardElementInfo.java index 8bbf00ed563d..395375e750d4 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/HardElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/HardElementInfo.java @@ -15,8 +15,6 @@ */ package com.intellij.psi.impl.smartPointers; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Segment; @@ -29,7 +27,7 @@ import org.jetbrains.annotations.NotNull; /** * User: cdr */ -class HardElementInfo implements SmartPointerElementInfo { +class HardElementInfo extends SmartPointerElementInfo { @NotNull private final PsiElement myElement; @NotNull @@ -40,19 +38,6 @@ class HardElementInfo implements SmartPointerElementInfo { myProject = project; } - @Override - public Document getDocumentToSynchronize() { - return null; - } - - @Override - public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) { - } - - @Override - public void unfastenBelt(int offset) { - } - @Override public PsiElement restoreElement() { return myElement; @@ -89,8 +74,4 @@ class HardElementInfo implements SmartPointerElementInfo { return myProject; } - @Override - public void cleanup() { - - } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java index e16ec5ab5ff7..8c2091c71062 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java @@ -20,7 +20,6 @@ import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.lang.Language; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.ProperTextRange; @@ -39,7 +38,7 @@ import java.util.List; /** * User: cdr */ -class InjectedSelfElementInfo implements SmartPointerElementInfo { +class InjectedSelfElementInfo extends SmartPointerElementInfo { private final SmartPsiFileRange myInjectedFileRangeInHostFile; private final Class anchorClass; private final Language anchorLanguage; @@ -193,16 +192,6 @@ class InjectedSelfElementInfo implements SmartPointerElementInfo { return ((SmartPsiElementPointerImpl)myHostContext).getElementInfo().getDocumentToSynchronize(); } - @Override - public void fastenBelt(int offset, RangeMarker[] cachedRangeMarkers) { - - } - - @Override - public void unfastenBelt(int offset) { - - } - @Override public int elementHashCode() { return ((SmartPsiElementPointerImpl)myHostContext).getElementInfo().elementHashCode(); diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java index 66dcee8daec7..1bb7c8c76f4e 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java @@ -18,7 +18,6 @@ package com.intellij.psi.impl.smartPointers; import com.intellij.lang.Language; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.editor.impl.FrozenDocument; import com.intellij.openapi.editor.impl.ManualRangeMarker; @@ -38,7 +37,7 @@ import java.util.Set; /** * User: cdr */ -public class SelfElementInfo implements SmartPointerElementInfo { +public class SelfElementInfo extends SmartPointerElementInfo { private final VirtualFile myVirtualFile; private final Class myType; private final Project myProject; @@ -81,7 +80,7 @@ public class SelfElementInfo implements SmartPointerElementInfo { // before change @Override - public void fastenBelt(int offset, @Nullable RangeMarker[] cachedRangeMarkers) { + public void fastenBelt() { if (myRangeMarker != null) return; // already tracks changes if (myPsiRange == null) return; // invalid @@ -96,11 +95,6 @@ public class SelfElementInfo implements SmartPointerElementInfo { setRange(myPsiRange, document); } - // after change - @Override - public void unfastenBelt(int offset) { - } - @Override public PsiElement restoreElement() { Segment segment = getPsiRange(); diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java index e0bf6b2eb10c..c975a59a959c 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java @@ -17,7 +17,6 @@ package com.intellij.psi.impl.smartPointers; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Segment; import com.intellij.openapi.vfs.VirtualFile; @@ -26,27 +25,30 @@ import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -interface SmartPointerElementInfo { +abstract class SmartPointerElementInfo { @Nullable - Document getDocumentToSynchronize(); + public Document getDocumentToSynchronize() { + return null; + } - void fastenBelt(int offset, @Nullable RangeMarker[] cachedRangeMarkers); - - void unfastenBelt(int offset); + public void fastenBelt() { + } @Nullable - PsiElement restoreElement(); + public abstract PsiElement restoreElement(); - PsiFile restoreFile(); + public abstract PsiFile restoreFile(); - int elementHashCode(); // must be immutable - boolean pointsToTheSameElementAs(@NotNull SmartPointerElementInfo other); + public abstract int elementHashCode(); // must be immutable + public abstract boolean pointsToTheSameElementAs(@NotNull SmartPointerElementInfo other); - VirtualFile getVirtualFile(); + public abstract VirtualFile getVirtualFile(); @Nullable - Segment getRange(); - @NotNull Project getProject(); + public abstract Segment getRange(); + @NotNull + public abstract Project getProject(); - void cleanup(); + public void cleanup() { + } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerEx.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerEx.java index df0ca95ae7d0..160f6f064356 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerEx.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerEx.java @@ -15,15 +15,13 @@ */ package com.intellij.psi.impl.smartPointers; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.psi.PsiElement; import com.intellij.psi.SmartPsiElementPointer; import org.jetbrains.annotations.Nullable; interface SmartPointerEx extends SmartPsiElementPointer { - void fastenBelt(int offset, @Nullable RangeMarker[] cachedRangeMarkers); - - void unfastenBelt(int offset); + void fastenBelt(); + @Nullable PsiElement getCachedElement(); } diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java index be4e9bf53e89..c5501035c154 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java @@ -16,12 +16,9 @@ package com.intellij.psi.impl.smartPointers; -import com.intellij.injected.editor.DocumentWindow; -import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.editor.impl.FrozenDocument; import com.intellij.openapi.editor.impl.ManualRangeMarker; @@ -34,7 +31,6 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.PsiDocumentManagerBase; -import com.intellij.psi.impl.PsiManagerEx; import com.intellij.psi.util.PsiUtilCore; import com.intellij.reference.SoftReference; import com.intellij.util.ArrayUtil; @@ -65,12 +61,10 @@ public class SmartPointerManagerImpl extends SmartPointerManager { private final Project myProject; private final Key POINTERS_KEY; - private final Key POINTERS_ARE_FASTENED_KEY; public SmartPointerManagerImpl(Project project) { myProject = project; POINTERS_KEY = Key.create("SMART_POINTERS for "+project); - POINTERS_ARE_FASTENED_KEY = Key.create("SMART_POINTERS_ARE_FASTENED for "+project); } private static void processQueue() { @@ -89,50 +83,22 @@ public class SmartPointerManagerImpl extends SmartPointerManager { } } - public void fastenBelts(@NotNull VirtualFile file, int offset, @Nullable RangeMarker[] cachedRangeMarkers) { + public void fastenBelts(@NotNull VirtualFile file) { ApplicationManager.getApplication().assertIsDispatchThread(); processQueue(); synchronized (lock) { - if (getAndFasten(file)) return; FilePointersList pointers = getPointers(file); if (pointers != null && !pointers.isEmpty()) { for (PointerReference ref : pointers.references) { SmartPointerEx pointer = SoftReference.dereference(ref); if (pointer != null) { - pointer.fastenBelt(offset, cachedRangeMarkers); + pointer.fastenBelt(); } } } } } - public void unfastenBelts(@NotNull VirtualFile file, int offset) { - ApplicationManager.getApplication().assertIsDispatchThread(); - processQueue(); - synchronized (lock) { - if (!getAndUnfasten(file)) return; - FilePointersList pointers = getPointers(file); - if (pointers != null && !pointers.isEmpty()) { - for (PointerReference ref : pointers.references) { - SmartPointerEx pointer = SoftReference.dereference(ref); - if (pointer != null) { - pointer.unfastenBelt(offset); - } - } - } - - PsiFile psiFile = ((PsiManagerEx)PsiManager.getInstance(myProject)).getFileManager().getCachedPsiFile(file); - if (psiFile != null) { - PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(myProject); - for (DocumentWindow injectedDoc : InjectedLanguageManager.getInstance(myProject).getCachedInjectedDocuments(psiFile)) { - PsiFile injectedFile = psiDocumentManager.getPsiFile(injectedDoc); - if (injectedFile == null) continue; - unfastenBelts(injectedFile.getViewProvider().getVirtualFile(), 0); - } - } - } - } - private static final Key> CACHED_SMART_POINTER_KEY = Key.create("CACHED_SMART_POINTER_KEY"); @Override @NotNull @@ -158,11 +124,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager { element.putUserData(CACHED_SMART_POINTER_KEY, new SoftReference(pointer)); } else { - containingFile = containingFile == null ? element.getContainingFile() : containingFile; synchronized (lock) { - if (containingFile != null && areBeltsFastened(containingFile.getViewProvider().getVirtualFile())) { - pointer.fastenBelt(0, null); - } if (pointer instanceof SmartPsiElementPointerImpl) { ((SmartPsiElementPointerImpl)pointer).incrementAndGetReferenceCount(1); } @@ -273,20 +235,6 @@ public class SmartPointerManagerImpl extends SmartPointerManager { } } - private boolean getAndFasten(@NotNull VirtualFile file) { - boolean fastened = areBeltsFastened(file); - file.putUserData(POINTERS_ARE_FASTENED_KEY, Boolean.TRUE); - return fastened; - } - private boolean getAndUnfasten(@NotNull VirtualFile file) { - boolean fastened = areBeltsFastened(file); - file.putUserData(POINTERS_ARE_FASTENED_KEY, null); - return fastened; - } - boolean areBeltsFastened(@NotNull VirtualFile file) { - return file.getUserData(POINTERS_ARE_FASTENED_KEY) == Boolean.TRUE; - } - @Override public boolean pointToTheSameElement(@NotNull SmartPsiElementPointer pointer1, @NotNull SmartPsiElementPointer pointer2) { return SmartPsiElementPointerImpl.pointsToTheSameElementAs(pointer1, pointer2); diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java index 2ea0695a08f0..b516188dce6a 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java @@ -20,7 +20,6 @@ import com.intellij.lang.LanguageUtil; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; @@ -178,13 +177,8 @@ class SmartPsiElementPointerImpl implements SmartPointerEx } @Override - public void unfastenBelt(int offset) { - myElementInfo.unfastenBelt(offset); - } - - @Override - public void fastenBelt(int offset, @Nullable RangeMarker[] cachedRangeMarkers) { - myElementInfo.fastenBelt(offset, cachedRangeMarkers); + public void fastenBelt() { + myElementInfo.fastenBelt(); } @NotNull diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/MarkersHolderFileViewProvider.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/MarkersHolderFileViewProvider.java deleted file mode 100644 index 03f7e62fca3a..000000000000 --- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/MarkersHolderFileViewProvider.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2000-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.psi.impl.source.tree; - -import com.intellij.openapi.editor.RangeMarker; -import org.jetbrains.annotations.NotNull; - -public interface MarkersHolderFileViewProvider { - - @NotNull - RangeMarker[] getCachedMarkers(); -} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SmartPointerEditorTracker.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SmartPointerEditorTracker.java index fcaaf35293df..8066ee86d669 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SmartPointerEditorTracker.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SmartPointerEditorTracker.java @@ -60,20 +60,12 @@ public class SmartPointerEditorTracker extends AbstractProjectComponent implemen boolean isRelevant = virtualFile != null && isRelevant(virtualFile); if (!isBulk && isRelevant && shouldNotifySmartPointers(virtualFile)) { - mySmartPointerManager.fastenBelts(virtualFile, event.getOffset(), null); + mySmartPointerManager.fastenBelts(virtualFile); } } @Override public void documentChanged(DocumentEvent event) { - final Document document = event.getDocument(); - VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document); - boolean isBulk = document instanceof DocumentEx && ((DocumentEx)document).isInBulkUpdate(); - - boolean isRelevant = virtualFile != null && isRelevant(virtualFile); - if (!isBulk && isRelevant && shouldNotifySmartPointers(virtualFile)) { - mySmartPointerManager.unfastenBelts(virtualFile, event.getOffset()); - } } @Override @@ -86,22 +78,12 @@ public class SmartPointerEditorTracker extends AbstractProjectComponent implemen final VirtualFile virtualFile = psiFile.getVirtualFile(); // materialize all range markers and do not let them to be collected to improve responsiveness if (virtualFile != null) { - mySmartPointerManager.fastenBelts(virtualFile, 0, null); + mySmartPointerManager.fastenBelts(virtualFile); } } @Override public void editorReleased(@NotNull EditorFactoryEvent event) { - final Editor editor = event.getEditor(); - if (editor.getProject() != null && editor.getProject() != myProject || myProject.isDisposed()) return; - final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument()); - if (psiFile == null) return; - final VirtualFile virtualFile = psiFile.getVirtualFile(); - // allow range markers in smart pointers to be collected - // beware there maybe other editors still open for that file - if (virtualFile != null && virtualFile.isValid() && shouldNotifySmartPointers(virtualFile)) { - mySmartPointerManager.unfastenBelts(virtualFile, 0); - } } private boolean shouldNotifySmartPointers(@NotNull VirtualFile virtualFile) { @@ -116,16 +98,12 @@ public class SmartPointerEditorTracker extends AbstractProjectComponent implemen public void updateStarted(@NotNull Document document) { final VirtualFile virtualFile = getVirtualFile(document); if (virtualFile != null && isRelevant(virtualFile) && shouldNotifySmartPointers(virtualFile)) { - mySmartPointerManager.fastenBelts(virtualFile, 0, null); + mySmartPointerManager.fastenBelts(virtualFile); } } @Override public void updateFinished(@NotNull Document document) { - final VirtualFile virtualFile = getVirtualFile(document); - if (virtualFile != null && isRelevant(virtualFile) && shouldNotifySmartPointers(virtualFile)) { - mySmartPointerManager.unfastenBelts(virtualFile, 0); - } } private static VirtualFile getVirtualFile(@NotNull Document document) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java index 91fc23c52f69..5a0fc06a21cb 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java @@ -42,7 +42,6 @@ import com.intellij.psi.*; import com.intellij.psi.impl.PsiManagerImpl; import com.intellij.psi.impl.PsiTreeChangeEventImpl; import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl; -import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.util.FileContentUtilCore; import com.intellij.util.messages.MessageBusConnection; import org.jetbrains.annotations.NotNull; @@ -365,7 +364,7 @@ public class PsiVFSListener extends VirtualFileAdapter { } } - ((SmartPointerManagerImpl)SmartPointerManager.getInstance(myManager.getProject())).fastenBelts(vFile, 0, null); + ((SmartPointerManagerImpl)SmartPointerManager.getInstance(myManager.getProject())).fastenBelts(vFile); ApplicationManager.getApplication().runWriteAction( new ExternalChangeAction() { @Override diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java index ff7fa6c865ed..1dec8e119186 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java @@ -22,7 +22,6 @@ import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.lang.Language; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Ref; @@ -32,8 +31,6 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.FreeThreadedFileViewProvider; -import com.intellij.psi.impl.source.tree.MarkersHolderFileViewProvider; -import com.intellij.util.SmartList; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -42,8 +39,7 @@ import java.util.List; /** * @author cdr */ -public class InjectedFileViewProvider extends SingleRootFileViewProvider implements FreeThreadedFileViewProvider, - MarkersHolderFileViewProvider { +public class InjectedFileViewProvider extends SingleRootFileViewProvider implements FreeThreadedFileViewProvider { private Project myProject; private final Object myLock = new Object(); private final DocumentWindowImpl myDocumentWindow; @@ -205,16 +201,4 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider impleme myPatchingLeaves = patchingLeaves; } - @Override - @NotNull - public RangeMarker[] getCachedMarkers() { - List markers = new SmartList(); - for (PsiLanguageInjectionHost.Shred shred : myDocumentWindow.getShreds()) { - RangeMarker marker = (RangeMarker)shred.getHostRangeMarker(); - if (marker != null) { - markers.add(marker); - } - } - return markers.toArray(new RangeMarker[markers.size()]); - } } From 61f57459d52c1fed8513fbc656c7ba375b0262f2 Mon Sep 17 00:00:00 2001 From: Alexey Utkin Date: Mon, 10 Aug 2015 11:57:51 +0300 Subject: [PATCH 26/99] CPP-4184 Generate multiple '}' on enter for enclosed namespaces #3 --- .../EnterAfterUnmatchedBraceHandler.java | 180 ++++++++++++------ 1 file changed, 122 insertions(+), 58 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java index ae6e57b5fe9f..dd2899548bc3 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -49,27 +49,106 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.editorActions.enter.EnterAfterUnmatchedBraceHandler"); @Override - public Result preprocessEnter(@NotNull final PsiFile file, @NotNull final Editor editor, @NotNull final Ref caretOffsetRef, @NotNull final Ref caretAdvance, - @NotNull final DataContext dataContext, final EditorActionHandler originalHandler) { - Document document = editor.getDocument(); - CharSequence text = document.getCharsSequence(); - Project project = file.getProject(); - int caretOffset = caretOffsetRef.get().intValue(); - int unmatchedLBracesNumber = getUnmatchedLBracesNumberBefore(editor, caretOffset, file.getFileType()); - if (!CodeInsightSettings.getInstance().INSERT_BRACE_ON_ENTER || unmatchedLBracesNumber <= 0) { - return Result.Continue; + public Result preprocessEnter(@NotNull final PsiFile file, + @NotNull final Editor editor, + @NotNull final Ref caretOffsetRef, + @NotNull final Ref caretAdvance, + @NotNull final DataContext dataContext, + final EditorActionHandler originalHandler) { + + int caretOffset = caretOffsetRef.get(); + int maxRBraceCount = getMaxRBraceCount(file, editor, caretOffset); + if (maxRBraceCount > 0 && insertRBraces(file, editor, caretOffset, + getRBraceOffset(file, editor, caretOffset), + adjustRBraceCountForPosition(editor, caretOffset, maxRBraceCount))) { + return Result.DefaultForceIndent; } - - int offset = CharArrayUtil.shiftForward(text, caretOffset, " \t"); - if (offset < document.getTextLength()) { - char c = text.charAt(offset); - if (c != ')' && c != ']' && c != ';' && c != ',' && c != '%' && c != '<' && c != '?') { - offset = calculateOffsetToInsertClosingBrace(file, text, offset); - //offset = CharArrayUtil.shiftForwardUntil(text, caretOffset, "\n"); + return Result.Continue; + } + + /** + * Calculates the maximum number of '}' that can be inserted by handler. + * Can return 0 or less in custom implementation to skip '}' insertion in the preprocessEnter call + * and switch to default implementation. + * + * @param file target PSI file + * @param editor target editor + * @param caretOffset target caret offset + * @return maximum number of '}' that can be inserted by handler, 0 or less to switch to default implementation + */ + protected int getMaxRBraceCount(@NotNull final PsiFile file, @NotNull final Editor editor, int caretOffset) { + if (!CodeInsightSettings.getInstance().INSERT_BRACE_ON_ENTER) { + return 0; + } + return Math.max(0, getUnmatchedLBracesNumberBefore(editor, caretOffset, file.getFileType())); + } + + /** + * Calculates the precise number of '}' that have be inserted by handler. + * + * @param editor target editor + * @param caretOffset target caret offset + * @param maxRBraceCount the maximum number of '}' for insert at position, it always positive + * @return number of '}' that has to be inserted by handler, it has to positive + */ + protected int adjustRBraceCountForPosition(@NotNull final Editor editor, int caretOffset, int maxRBraceCount) { + assert maxRBraceCount > 0; + + CharSequence text = editor.getDocument().getCharsSequence(); + int bracesToInsert = 0; + outer: + for (int i = caretOffset - 1; i >= 0 && bracesToInsert < maxRBraceCount; --i) { + switch (text.charAt(i)) { + case ' ': + case '\n': + case '\t': + continue; + case '{': + bracesToInsert++; + break; + default: + break outer; } } - offset = Math.min(offset, document.getTextLength()); + return Math.max(bracesToInsert, 1); + } + /** + * Calculates the position for insertion of one or more '}'. + * + * @param file target PSI file + * @param editor target editor + * @param caretOffset target caret offset + * @return the position between caretOffset and the end of file + */ + protected int getRBraceOffset(@NotNull final PsiFile file, @NotNull final Editor editor, int caretOffset) { + CharSequence text = editor.getDocument().getCharsSequence(); + int offset = CharArrayUtil.shiftForward(text, caretOffset, " \t"); + final int fileLength = text.length(); + if (offset < fileLength && ")];,%rBracesCount of '}' at the rBracesInsertOffset position and formats the code block. + * + * @param file target PSI file + * @param editor target editor + * @param caretOffset target caret offset + * @param rBracesInsertOffset target position to insert + * @param rBracesCount count of '}' to insert + * @return true for success + */ + protected boolean insertRBraces(@NotNull PsiFile file, + @NotNull Editor editor, + int caretOffset, + int rBracesInsertOffset, + int rBracesCount) { + final Document document = editor.getDocument(); + document.insertString(rBracesInsertOffset, "\n" + StringUtil.repeatSymbol('}', rBracesCount)); // We need to adjust indents of the text that will be moved, hence, need to insert preliminary line feed. // Example: // if (test1()) { @@ -85,27 +164,14 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter // That is formatted incorrectly because line feed between 'else' and 'if' is not inserted yet (whole 'if' block is indent anchor // to 'if' code block('{}')). So, we insert temporary line feed between 'if' and 'else', correct indent and remove that temporary // line feed. - int bracesToInsert = 0; - outer: - for (int i = caretOffset - 1; unmatchedLBracesNumber > 0 && i >= 0 && bracesToInsert < unmatchedLBracesNumber; i--) { - char c = text.charAt(i); - switch (c) { - case ' ': - case '\n': - case '\t': - continue; - case '{': bracesToInsert++; break; - default: break outer; - } - } - bracesToInsert = Math.max(bracesToInsert, 1); - document.insertString(offset, "\n" + StringUtil.repeatSymbol('}', bracesToInsert)); document.insertString(caretOffset, "\n"); - PsiDocumentManager.getInstance(project).commitDocument(document); + + Project project = file.getProject(); long stamp = document.getModificationStamp(); boolean closingBraceIndentAdjusted; try { - CodeStyleManager.getInstance(project).adjustLineIndent(file, new TextRange(caretOffset, offset + 2)); + PsiDocumentManager.getInstance(project).commitDocument(document); + CodeStyleManager.getInstance(project).adjustLineIndent(file, new TextRange(caretOffset, rBracesInsertOffset + 2)); } catch (IncorrectOperationException e) { LOG.error(e); @@ -118,10 +184,11 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter // There is a possible case that formatter was unable to adjust line indent for the closing brace (that is the case for plain text // document for example). Hence, we're trying to do the manually. if (!closingBraceIndentAdjusted) { - int line = document.getLineNumber(offset); + int line = document.getLineNumber(rBracesInsertOffset); StringBuilder buffer = new StringBuilder(); int start = document.getLineStartOffset(line); int end = document.getLineEndOffset(line); + final CharSequence text = document.getCharsSequence(); for (int i = start; i < end; i++) { char c = text.charAt(i); if (c != ' ' && c != '\t') { @@ -132,18 +199,17 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter } } if (buffer.length() > 0) { - document.insertString(offset + 1, buffer); + document.insertString(rBracesInsertOffset + 1, buffer); } } - - return Result.DefaultForceIndent; + return true; } /** * Current handler inserts closing curly brace (right brace) if necessary. There is a possible case that it should be located * more than one line forward. *

- * Example + * Example *

    *     if (test1()) {
    *     } else { if (test2()) {
@@ -165,11 +231,11 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter
    * 

* In essence it inspects PSI structure and finds PSE elements with the max length that starts at caret offset. End offset * of that element is used as an insertion point. - * - * @param file target PSI file - * @param text text from the given file - * @param offset target offset where line feed will be inserted - * @return offset to use for inserting closing brace + * + * @param file target PSI file + * @param text text from the given file + * @param offset target offset where line feed will be inserted + * @return offset to use for inserting closing brace */ protected int calculateOffsetToInsertClosingBrace(PsiFile file, CharSequence text, final int offset) { PsiElement element = PsiUtilCore.getElementAtOffset(file, offset); @@ -187,24 +253,22 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter if (element.getTextOffset() != offset) { return CharArrayUtil.shiftForwardUntil(text, offset, "\n"); } - else { - return element.getTextRange().getEndOffset(); - } + return element.getTextRange().getEndOffset(); } - + public static boolean isAfterUnmatchedLBrace(Editor editor, int offset, FileType fileType) { return getUnmatchedLBracesNumberBefore(editor, offset, fileType) > 0; } /** * Calculates number of unmatched left braces before the given offset. - * - * @param editor target editor - * @param offset target offset - * @param fileType target file type - * @return number of unmatched braces before the given offset; - * negative value if it's not possible to perform the calculation or if there are no unmatched left braces before - * the given offset + * + * @param editor target editor + * @param offset target offset + * @param fileType target file type + * @return number of unmatched braces before the given offset; + * negative value if it's not possible to perform the calculation or if there are no unmatched left braces before + * the given offset */ protected static int getUnmatchedLBracesNumberBefore(Editor editor, int offset, FileType fileType) { if (offset == 0) { @@ -237,7 +301,7 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter } boolean beforeOffset = iterator.getStart() < offset; - + if (braceMatcher.isLBraceToken(iterator, chars, fileType)) { if (beforeOffset) { lBracesBeforeOffset++; @@ -255,7 +319,7 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter } } } - + return lBracesBeforeOffset - rBracesBeforeOffset - (rBracesAfterOffset - lBracesAfterOffset); } } From 127d7e39ada9dd21f780c704d748f95391e592da Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Mon, 10 Aug 2015 11:51:10 +0300 Subject: [PATCH 27/99] Color scheme migration to version 142 (inheritance is enforced for missing attributes) --- .../colors/impl/AbstractColorsScheme.java | 32 +++++++++++++ .../colors/impl/EditorColorsManagerImpl.java | 10 ++++ .../impl/EditorColorsSchemeImplTest.java | 46 +++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java b/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java index d3ca96632a7f..2d232020deac 100644 --- a/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java +++ b/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java @@ -70,6 +70,10 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme { // version influences XML format and triggers migration private int myVersion = CURR_VERSION; + /** + * The version from the original file. + */ + private int myOriginalVersion = CURR_VERSION; protected Map myColorsMap = ContainerUtilRt.newHashMap(); protected Map myAttributesMap = ContainerUtilRt.newHashMap(); @@ -294,6 +298,7 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme { } myVersion = readVersion; + myOriginalVersion = readVersion; String isDefaultScheme = node.getAttributeValue(DEFAULT_SCHEME_ATTR); boolean isDefault = isDefaultScheme != null && Boolean.parseBoolean(isDefaultScheme); if (!isDefault) { @@ -357,6 +362,33 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme { } } + /** + * The method is called for the scheme when it is fully loaded including additional text attributes from providers. + */ + public void upgradeSchemeFromPreviousVersion() { + setUndefinedAttributesAsInheritedForVersion142(); + } + + + /** + * Defines empty attributes with fallback (inheritance) enabled for all the attributes explicitly defined in the parent scheme since + * previously undefined attributes were treated as inherited, not taken from the parent scheme. + */ + private void setUndefinedAttributesAsInheritedForVersion142() { + if (myOriginalVersion >= 142 || myParentScheme == null) return; + if (myParentScheme instanceof AbstractColorsScheme) { + for (TextAttributesKey key : ((AbstractColorsScheme)myParentScheme).myAttributesMap.keySet()) { + TextAttributes parentAttributes = ((AbstractColorsScheme)myParentScheme).getDirectlyDefinedAttributes(key); + if (key.getFallbackAttributeKey() != null && + parentAttributes != null && + !parentAttributes.isFallbackEnabled() && + !myAttributesMap.containsKey(key)) { + myAttributesMap.put(key, new TextAttributes()); + } + } + } + } + @Deprecated @SuppressWarnings("unused") public static final Map DEFAULT_ERROR_STRIPE_COLOR = new THashMap(); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java index 3aa26b6f66e7..e68fddb7745e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java @@ -144,6 +144,8 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers loadAdditionalTextAttributes(); + upgradeSchemesFromPreviousVersion(); + String wizardEditorScheme = WelcomeWizardUtil.getWizardEditorScheme(); EditorColorsScheme scheme = null; if (wizardEditorScheme != null) { @@ -153,6 +155,14 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers setGlobalSchemeInner(scheme == null ? getDefaultScheme() : scheme); } + private void upgradeSchemesFromPreviousVersion() { + for (EditorColorsScheme scheme : mySchemeManager.getAllSchemes()) { + if (scheme instanceof AbstractColorsScheme && !(scheme instanceof ReadOnlyColorsScheme)) { + ((AbstractColorsScheme)scheme).upgradeSchemeFromPreviousVersion(); + } + } + } + public static void schemeChangedOrSwitched() { EditorFactory.getInstance().refreshAllEditors(); // refreshAllEditors is not enough - for example, change "Errors and warnings -> Typo" from green (default) to red diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImplTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImplTest.java index 86941a1f5757..0a2a04ab1503 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImplTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImplTest.java @@ -22,11 +22,18 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.WriteExternalException; import com.intellij.testFramework.LightPlatformCodeInsightTestCase; import org.jdom.Element; +import org.jdom.input.DOMBuilder; import org.jdom.output.Format; import org.jdom.output.XMLOutputter; import org.jetbrains.annotations.NotNull; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; +import java.io.StringReader; import java.io.StringWriter; import java.util.Arrays; import java.util.Collections; @@ -223,6 +230,45 @@ public class EditorColorsSchemeImplTest extends LightPlatformCodeInsightTestCase assertSame(fallbackAttrs, result.second); } + + /** + * Check that the attributes missing in a custom scheme with a version prior to 142 are explicitly added with fallback enabled, + * not taken from parent scheme. + * + * @throws Exception + */ + public void testUpgradeFromVer141() throws Exception { + TextAttributesKey constKey = DefaultLanguageHighlighterColors.CONSTANT; + TextAttributesKey fallbackKey = constKey.getFallbackAttributeKey(); + assertNotNull(fallbackKey); + + EditorColorsScheme scheme = loadScheme( + "\n" + + "\n" + + "\n" + ); + + TextAttributes constAttrs = scheme.getAttributes(constKey); + TextAttributes fallbackAttrs = scheme.getAttributes(fallbackKey); + assertSame(fallbackAttrs, constAttrs); + } + + + private static EditorColorsScheme loadScheme(@NotNull String docText) throws ParserConfigurationException, IOException, SAXException { + DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + InputSource inputSource = new InputSource(new StringReader(docText)); + org.w3c.dom.Document doc = docBuilder.parse(inputSource); + Element root = new DOMBuilder().build(doc.getDocumentElement()); + + EditorColorsScheme defaultScheme = EditorColorsManager.getInstance().getScheme(EditorColorsScheme.DEFAULT_SCHEME_NAME); + EditorColorsScheme targetScheme = new EditorColorsSchemeImpl(defaultScheme); + + targetScheme.readExternal(root); + ((AbstractColorsScheme)targetScheme).upgradeSchemeFromPreviousVersion(); + + return targetScheme; + } + @NotNull public Pair doTestWriteRead(TextAttributesKey key, TextAttributes attributes) throws WriteExternalException { From 7f24e34e54f6e2ab3daaaa47ea8785708cd534d2 Mon Sep 17 00:00:00 2001 From: Sergey Savenko Date: Mon, 10 Aug 2015 13:07:33 +0300 Subject: [PATCH 28/99] IdeStartupScripts: do not attempt to execute backup files --- .../ide/extensionResources/ExtensionsRootType.java | 11 ++++++++--- .../com/intellij/ide/script/IdeStartupScripts.java | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/extensionResources/ExtensionsRootType.java b/platform/lang-impl/src/com/intellij/ide/extensionResources/ExtensionsRootType.java index ffa1d04199f4..7f8fa57f153e 100644 --- a/platform/lang-impl/src/com/intellij/ide/extensionResources/ExtensionsRootType.java +++ b/platform/lang-impl/src/com/intellij/ide/extensionResources/ExtensionsRootType.java @@ -56,11 +56,11 @@ import java.util.Set; *

Bundled resources are updated automatically upon plugin version change. For bundled plugins, application version is used.

*/ public class ExtensionsRootType extends RootType { - public static final String EXTENSIONS_PATH = "extensions"; - public static final String BACKUP_FILE_EXTENSION = "old"; - static final Logger LOG = Logger.getInstance(ExtensionsRootType.class); + private static final String HASH_ALGORITHM = "MD5"; + private static final String EXTENSIONS_PATH = "extensions"; + private static final String BACKUP_FILE_EXTENSION = "old"; ExtensionsRootType() { super(EXTENSIONS_PATH, "Extensions"); @@ -129,6 +129,11 @@ public class ExtensionsRootType extends RootType { return super.substituteName(project, file); } + public boolean isBackupFile(@NotNull VirtualFile file) { + String extension = file.getExtension(); + return !file.isDirectory() && extension != null && extension.startsWith(BACKUP_FILE_EXTENSION); + } + @Nullable String getPath(@Nullable VirtualFile resource) { VirtualFile pluginResourcesDir = getPluginResourcesDirectoryFor(resource); diff --git a/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java b/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java index 086a9a23f48c..3d6c8aeaba9f 100644 --- a/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java +++ b/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java @@ -170,9 +170,10 @@ class IdeStartupScripts extends ApplicationComponent.Adapter { } scripts = ContainerUtil.filter(scripts, new Condition() { + private final ExtensionsRootType myExtensionsRootType = ExtensionsRootType.getInstance(); @Override public boolean value(VirtualFile file) { - return !file.isDirectory() && !README_FILE_NAME.equals(file.getName()); + return !file.isDirectory() && !myExtensionsRootType.isBackupFile(file) && !README_FILE_NAME.equals(file.getName()); } }); From d759f0fd1e9d80f319e409b75e647279560ae4cd Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 10 Aug 2015 13:11:26 +0300 Subject: [PATCH 29/99] review --- .../codeInspection/dataFlow/DfaMemoryStateImpl.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java index 26dbb4456d8f..e9f9d49eb3e5 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java @@ -49,7 +49,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { private final DfaValueFactory myFactory; private final List myEqClasses; - // dfa value id -> indices in myEqClasses list of the classes which contain the id (or negated or wrapped) + // dfa value id -> indices in myEqClasses list of the classes which contain the id (or wrapped) private final TIntObjectHashMap myIdToEqClassesIndices; private final Stack myStack; private final TLongHashSet myDistinctClasses; @@ -321,7 +321,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState { } private void removeFromMap(int id, int index) { - if (id < 0) return; id = unwrap(myFactory.getValue(id)).getID(); int[] classes = myIdToEqClassesIndices.get(id); if (classes != null) { @@ -487,11 +486,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState { } EqClass newClass = new EqClass(c1); - for (int i = 0; i < newClass.size(); i++) { - int c = newClass.get(i); - removeFromMap(c, c1Index); - addToMap(c, c1Index); - } myEqClasses.set(c1Index, newClass); for (int i = 0; i < c2.size(); i++) { From 2e2d02473df352f37a66a6cbde4666fae77337d6 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 10 Aug 2015 11:54:35 +0200 Subject: [PATCH 30/99] when parsing signatures, create GenericBoundUsage only for classes mentioned in signature bounds; mark dependencies caused by GenericBoundUsage only in chunk being compiled and all chunks that depend on it recursively --- .../incremental/generics/changeExtends.log | 4 +- .../generics/changeExtends/Super2.java.new | 3 + .../generics/changeExtends/src/Client4.java | 2 + .../generics/changeExtends/src/Super2.java | 3 + .../dependencyView/ClassfileAnalyzer.java | 118 +++++++++++------- .../java/dependencyView/Mappings.java | 82 ++++++++++-- 6 files changed, 158 insertions(+), 54 deletions(-) create mode 100644 java/java-tests/testData/compileServer/incremental/generics/changeExtends/Super2.java.new create mode 100644 java/java-tests/testData/compileServer/incremental/generics/changeExtends/src/Client4.java create mode 100644 java/java-tests/testData/compileServer/incremental/generics/changeExtends/src/Super2.java diff --git a/java/java-tests/testData/compileServer/incremental/generics/changeExtends.log b/java/java-tests/testData/compileServer/incremental/generics/changeExtends.log index 0cba040f482a..34c270510a8b 100644 --- a/java/java-tests/testData/compileServer/incremental/generics/changeExtends.log +++ b/java/java-tests/testData/compileServer/incremental/generics/changeExtends.log @@ -1,8 +1,10 @@ Cleaning output files: out/production/ChangeExtends/Super.class +out/production/ChangeExtends/Super2.class End of files Compiling files: src/Super.java +src/Super2.java End of files Cleaning output files: out/production/ChangeExtends/Client.class @@ -13,4 +15,4 @@ Compiling files: src/Client.java src/Client2.java src/Client3.java -End of files +End of files \ No newline at end of file diff --git a/java/java-tests/testData/compileServer/incremental/generics/changeExtends/Super2.java.new b/java/java-tests/testData/compileServer/incremental/generics/changeExtends/Super2.java.new new file mode 100644 index 000000000000..55dd08a7fffb --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/generics/changeExtends/Super2.java.new @@ -0,0 +1,3 @@ +class Super2 { + char s = 's'; +} \ No newline at end of file diff --git a/java/java-tests/testData/compileServer/incremental/generics/changeExtends/src/Client4.java b/java/java-tests/testData/compileServer/incremental/generics/changeExtends/src/Client4.java new file mode 100644 index 000000000000..9c68d9aab48c --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/generics/changeExtends/src/Client4.java @@ -0,0 +1,2 @@ +class Client4 extends Hyper{ +} \ No newline at end of file diff --git a/java/java-tests/testData/compileServer/incremental/generics/changeExtends/src/Super2.java b/java/java-tests/testData/compileServer/incremental/generics/changeExtends/src/Super2.java new file mode 100644 index 000000000000..0045f0cb5ca6 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/generics/changeExtends/src/Super2.java @@ -0,0 +1,3 @@ +class Super2 extends Hyper { + char s = 's'; +} \ No newline at end of file diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java index 2b11ac6bd546..c0d00b8b058c 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java @@ -217,61 +217,21 @@ class ClassfileAnalyzer { } } - private final SignatureVisitor mySignatureCrawler = new SignatureVisitor(Opcodes.ASM5) { - public void visitFormalTypeParameter(String name) { - } - + private final SignatureVisitor mySignatureCrawler = new BaseSignatureVisitor() { public SignatureVisitor visitClassBound() { - return this; + return mySignatureWithGenericBoundUsageCrawler; } public SignatureVisitor visitInterfaceBound() { - return this; - } - - public SignatureVisitor visitSuperclass() { - return this; - } - - public SignatureVisitor visitInterface() { - return this; - } - - public SignatureVisitor visitParameterType() { - return this; - } - - public SignatureVisitor visitReturnType() { - return this; - } - - public SignatureVisitor visitExceptionType() { - return this; - } - - public void visitBaseType(char descriptor) { - } - - public void visitTypeVariable(String name) { - } - - public SignatureVisitor visitArrayType() { - return this; - } - - public void visitInnerClassType(String name) { - } - - public void visitTypeArgument() { + return mySignatureWithGenericBoundUsageCrawler; } public SignatureVisitor visitTypeArgument(char wildcard) { - return this; - } - - public void visitEnd() { + return mySignatureWithGenericBoundUsageCrawler; } + }; + private final SignatureVisitor mySignatureWithGenericBoundUsageCrawler = new BaseSignatureVisitor() { public void visitClassType(String name) { final int className = myContext.get(name); myUsages.add(UsageRepr.createClassUsage(myContext, className)); @@ -653,6 +613,72 @@ class ClassfileAnalyzer { myLocalClassFlag.set(true); } } + + private class BaseSignatureVisitor extends SignatureVisitor { + + public BaseSignatureVisitor() { + super(Opcodes.ASM5); + } + + public void visitFormalTypeParameter(String name) { + } + + public SignatureVisitor visitClassBound() { + return this; + } + + public SignatureVisitor visitInterfaceBound() { + return this; + } + + public SignatureVisitor visitSuperclass() { + return this; + } + + public SignatureVisitor visitInterface() { + return this; + } + + public SignatureVisitor visitParameterType() { + return this; + } + + public SignatureVisitor visitReturnType() { + return this; + } + + public SignatureVisitor visitExceptionType() { + return this; + } + + public void visitBaseType(char descriptor) { + } + + public void visitTypeVariable(String name) { + } + + public SignatureVisitor visitArrayType() { + return this; + } + + public void visitInnerClassType(String name) { + } + + public void visitTypeArgument() { + } + + public SignatureVisitor visitTypeArgument(char wildcard) { + return this; + } + + public void visitEnd() { + } + + public void visitClassType(String name) { + final int className = myContext.get(name); + myUsages.add(UsageRepr.createClassUsage(myContext, className)); + } + } } public Pair> analyze(final int fileName, final ClassReader cr) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java index dd87660bcd6b..583406b372d2 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java @@ -716,6 +716,28 @@ public class Mappings { public abstract boolean checkResidence(final int residence); } + public class FileFilterConstraint extends UsageConstraint { + @NotNull + private final DependentFilesFilter myFilter; + + public FileFilterConstraint(@NotNull DependentFilesFilter filter) { + myFilter = filter; + } + + public boolean checkResidence(int residence) { + final Collection fNames = myClassToSourceFile.get(residence); + if (fNames == null || fNames.isEmpty()) { + return true; + } + for (File fName : fNames) { + if (myFilter.accept(fName)) { + return true; + } + } + return false; + } + } + public class PackageConstraint extends UsageConstraint { public final String packageName; @@ -1132,6 +1154,11 @@ public class Mappings { debug("Class is annotation, skipping method analysis"); return; } + + assert myFuture != null; + assert myPresent != null; + assert myAffectedFiles != null; + Ref oldItRef = null; for (final MethodRepr m : added) { debug("Method: ", m.name); @@ -1256,6 +1283,10 @@ public class Mappings { if (removed.isEmpty()) { return; } + assert myFuture != null; + assert myAffectedFiles != null; + assert myCompiledFiles != null; + debug("Processing removed methods:"); for (final MethodRepr m : removed) { debug("Method ", m.name); @@ -1362,6 +1393,10 @@ public class Mappings { return; } debug("Processing changed methods:"); + + assert myFuture != null; + assert myAffectedFiles != null; + for (final Pair mr : changed) { final MethodRepr m = mr.first; final MethodRepr.Diff d = (MethodRepr.Diff)mr.second; @@ -1473,6 +1508,11 @@ public class Mappings { } debug("Processing added fields"); + assert myFuture != null; + assert myPresent != null; + assert myCompiledFiles != null; + assert myAffectedFiles != null; + for (final FieldRepr f : added) { debug("Field: ", f.name); @@ -1535,23 +1575,23 @@ public class Mappings { // nothing } else { - Util.UsageConstraint constaint; + Util.UsageConstraint constraint; if ((ff.isProtected() && f.isPublic()) || (f.isProtected() && ff.isPublic()) || (ff.isPackageLocal() && f.isProtected())) { - constaint = myFuture.new NegationConstraint(myFuture.new InheritanceConstraint(cc.name)); + constraint = myFuture.new NegationConstraint(myFuture.new InheritanceConstraint(cc.name)); } else if (ff.isPublic() && ff.isPackageLocal()) { - constaint = myFuture.new NegationConstraint(myFuture.new PackageConstraint(cc.getPackageName())); + constraint = myFuture.new NegationConstraint(myFuture.new PackageConstraint(cc.getPackageName())); } else { - constaint = + constraint = myFuture.new IntersectionConstraint(myFuture.new NegationConstraint(myFuture.new InheritanceConstraint(cc.name)), myFuture.new NegationConstraint( myFuture.new PackageConstraint(cc.getPackageName()))); } for (final UsageRepr.Usage usage : localUsages) { - state.myUsageConstraints.put(usage, constaint); + state.myUsageConstraints.put(usage, constraint); } } @@ -1569,6 +1609,8 @@ public class Mappings { if (removed.isEmpty()) { return true; } + assert myFuture != null; + debug("Processing removed fields:"); for (final FieldRepr f : removed) { @@ -1577,6 +1619,7 @@ public class Mappings { if (!f.isPrivate() && (f.access & DESPERATE_MASK) == DESPERATE_MASK && f.hasValue()) { debug("Field had value and was (non-private) final static => a switch to non-incremental mode requested"); if (myConstantSearch != null) { + assert myDelayedWorks != null; myDelayedWorks.addConstantWork(it.name, f, true, false); } else { @@ -1601,6 +1644,7 @@ public class Mappings { return true; } debug("Processing changed fields:"); + assert myFuture != null; for (final Pair f : changed) { final Difference d = f.second; @@ -1619,6 +1663,7 @@ public class Mappings { if (harmful || valueChanged || becameLessAccessible) { debug("Inline field changed it's access or value => a switch to non-incremental mode requested"); if (myConstantSearch != null) { + assert myDelayedWorks != null; myDelayedWorks.addConstantWork(it.name, field, false, accessChanged); } else { @@ -1687,6 +1732,10 @@ public class Mappings { final Collection> changedClasses = state.myClassDiff.changed(); if (!changedClasses.isEmpty()) { debug("Processing changed classes:"); + assert myFuture != null; + assert myPresent != null; + + final Util.FileFilterConstraint fileFilterConstraint = myFilter != null? myPresent.new FileFilterConstraint(myFilter) : null; for (final Pair changed : changedClasses) { final ClassRepr changedClass = changed.first; @@ -1753,7 +1802,11 @@ public class Mappings { @Override public boolean execute(int className) { debug("Affecting usages in generic type parameter bounds of class: ", className); - state.myAffectedUsages.add(UsageRepr.createClassAsGenericBoundUsage(myContext, className)); + final UsageRepr.Usage usage = UsageRepr.createClassAsGenericBoundUsage(myContext, className); + state.myAffectedUsages.add(usage); + if (fileFilterConstraint != null) { + state.myUsageConstraints.put(usage, fileFilterConstraint); + } final TIntHashSet depClasses = myClassToClassDependency.get(className); if (depClasses != null) { @@ -1869,6 +1922,9 @@ public class Mappings { if (removed.isEmpty()) { return; } + assert myPresent != null; + assert myDelta.myChangedFiles != null; + myDelta.myChangedFiles.add(fileName); debug("Processing removed classes:"); @@ -1896,6 +1952,9 @@ public class Mappings { if (!myEasyMode && myFilter != null) { // checking if this newly added class duplicates already existing one + assert myCompiledFiles != null; + assert myAffectedFiles != null; + for (ClassRepr c : addedClasses) { if (!c.isLocal() && !c.isAnonymous() && isEmpty(c.getOuterClassName())) { final Set candidates = new THashSet(FileUtil.FILE_HASHING_STRATEGY); @@ -1976,6 +2035,8 @@ public class Mappings { } private void affectCorrespondingSourceFiles(TIntHashSet toAffect) { + assert myAffectedFiles != null; + toAffect.forEach(new TIntProcedure() { @Override public boolean execute(int depClass) { @@ -1995,6 +2056,8 @@ public class Mappings { private void calculateAffectedFiles(final DiffState state) { debug("Checking dependent classes:"); + assert myAffectedFiles != null; + assert myCompiledFiles != null; state.myDependants.forEach(new TIntProcedure() { @Override @@ -2106,6 +2169,8 @@ public class Mappings { if (myEasyMode) { return false; } + assert myAffectedFiles != null; + assert myDelayedWorks != null; final Collection removed = myDelta.myRemovedFiles; if (removed != null) { @@ -2117,6 +2182,7 @@ public class Mappings { } finally { if (myFilesToCompile != null) { + assert myDelta.myChangedFiles != null; // if some class is associated with several sources, // some of them may not have been compiled in this round, so such files should be considered unchanged myDelta.myChangedFiles.retainAll(myFilesToCompile); @@ -2463,7 +2529,9 @@ public class Mappings { } for (final String s : staticImports) { int i = s.length() - 1; - for (; s.charAt(i) != '.'; i--) ; + while (s.charAt(i) != '.') { + i--; + } final String anImport = s.substring(0, i); if (!anImport.endsWith("*")) { allImports.add(anImport); // filter out wildcard imports From 87a0a5f17ab7b1f034bad6e27ad3cd5b26843945 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 10 Aug 2015 15:04:02 +0300 Subject: [PATCH 31/99] vcs: do not suggest to revert changes from current changelist if modifiedWithoutEditing files were detected --- .../openapi/vcs/changes/actions/RollbackAction.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/RollbackAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/RollbackAction.java index ba057fede2ab..ca07a1675a4f 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/RollbackAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/RollbackAction.java @@ -134,9 +134,13 @@ public class RollbackAction extends AnAction implements DumbAware { }); } - if (!changes.isEmpty() || !hasChanges) { + if (!changes.isEmpty()) { RollbackChangesDialog.rollbackChanges(project, changes); } + else if (!hasChanges) { + List changelistChanges = getCurrentChangelistChanges(project); + RollbackChangesDialog.rollbackChanges(project, changelistChanges); + } } @NotNull @@ -158,13 +162,16 @@ public class RollbackAction extends AnAction implements DumbAware { if (changes != null && changes.length > 0) { return ContainerUtil.newArrayList(changes); } + return Collections.emptyList(); + } + @NotNull + private static List getCurrentChangelistChanges(final Project project) { final ChangeListManager clManager = ChangeListManager.getInstance(project); ChangeList list = clManager.getDefaultChangeList(); if (list != null) { return ContainerUtil.newArrayList(list.getChanges()); } - return Collections.emptyList(); } From e9501a133a834e80236282d6ab8889f22859c067 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Mon, 10 Aug 2015 15:52:52 +0300 Subject: [PATCH 32/99] TreeTraversal: extract the notion of tree traversal type (DFS, BFS, etc.) & cleanup FilteredTraversal API --- .../src/com/intellij/psi/SyntaxTraverser.java | 2 +- .../actionSystem/ex/ComboBoxAction.java | 2 +- .../ide/actions/ToggleToolbarAction.java | 2 +- .../actionSystem/impl/ToolbarUpdater.java | 2 +- .../openapi/wm/impl/ToolWindowHeader.java | 2 +- .../com/intellij/util/IJSwingUtilities.java | 2 +- .../util/containers/TreeTraverserTest.java | 19 +- .../util/containers/FilteredTraverser.java | 2 +- .../containers/FilteredTraverserBase.java | 52 ++-- .../intellij/util/containers/JBIterator.java | 2 +- ...{TreeTraverser.java => TreeTraversal.java} | 251 ++++++++++-------- 11 files changed, 186 insertions(+), 152 deletions(-) rename platform/util/src/com/intellij/util/containers/{TreeTraverser.java => TreeTraversal.java} (55%) diff --git a/platform/core-api/src/com/intellij/psi/SyntaxTraverser.java b/platform/core-api/src/com/intellij/psi/SyntaxTraverser.java index 8f8d30ce712d..9aa092e1c392 100644 --- a/platform/core-api/src/com/intellij/psi/SyntaxTraverser.java +++ b/platform/core-api/src/com/intellij/psi/SyntaxTraverser.java @@ -18,7 +18,7 @@ import java.util.LinkedList; /** * @author gregsh */ -public class SyntaxTraverser extends FilteredTraverserBase> implements Iterable, UserDataHolder { +public class SyntaxTraverser extends FilteredTraverserBase> implements UserDataHolder { @NotNull public static ApiEx psiApi() { diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java index 7ebe3c5951e2..344e67dddb4c 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java @@ -65,7 +65,7 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent JRootPane rootPane = UIUtil.getParentOfType(JRootPane.class, contextComponent); if (rootPane != null) { button = (ComboBoxButton) - JBSwingUtilities.uiTraverser().bfsTraversal(rootPane).filter(new Condition() { + JBSwingUtilities.uiTraverser().withRoot(rootPane).bfsTraversal().filter(new Condition() { @Override public boolean value(Component component) { return component instanceof ComboBoxButton && ((ComboBoxButton)component).getMyAction() == ComboBoxAction.this; diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ToggleToolbarAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ToggleToolbarAction.java index 33168df48d50..1baf2a13af62 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ToggleToolbarAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ToggleToolbarAction.java @@ -107,7 +107,7 @@ public class ToggleToolbarAction extends ToggleAction implements DumbAware { @NotNull private static Iterable iterateToolbars(JComponent root) { - return JBSwingUtilities.uiTraverser().preOrderDfsTraversal(root).filter(ActionToolbar.class); + return JBSwingUtilities.uiTraverser().withRoot(root).preOrderDfsTraversal().filter(ActionToolbar.class); } private static class OptionsGroup extends ActionGroup implements DumbAware { diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ToolbarUpdater.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ToolbarUpdater.java index 877d502e2815..77aeb2332163 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ToolbarUpdater.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ToolbarUpdater.java @@ -122,7 +122,7 @@ public abstract class ToolbarUpdater implements Activatable { protected abstract void updateActionsImpl(boolean transparentOnly, boolean forced); protected void updateActionTooltips() { - for (ActionButton actionButton : JBSwingUtilities.uiTraverser().preOrderDfsTraversal(myComponent).filter(ActionButton.class)) { + for (ActionButton actionButton : JBSwingUtilities.uiTraverser().withRoot(myComponent).preOrderDfsTraversal().filter(ActionButton.class)) { actionButton.updateToolTipText(); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java index ca3547ceea2f..6b64443d3acf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java @@ -212,7 +212,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS @Override protected void updateActionTooltips() { - for (ActionButton actionButton : JBSwingUtilities.uiTraverser().preOrderDfsTraversal(myButtonPanel).filter(ActionButton.class)) { + for (ActionButton actionButton : JBSwingUtilities.uiTraverser().withRoot(myButtonPanel).preOrderDfsTraversal().filter(ActionButton.class)) { actionButton.updateTooltip(); } } diff --git a/platform/platform-impl/src/com/intellij/util/IJSwingUtilities.java b/platform/platform-impl/src/com/intellij/util/IJSwingUtilities.java index c6b0c044ad8a..7f1750de8701 100644 --- a/platform/platform-impl/src/com/intellij/util/IJSwingUtilities.java +++ b/platform/platform-impl/src/com/intellij/util/IJSwingUtilities.java @@ -231,7 +231,7 @@ public class IJSwingUtilities extends JBSwingUtilities { */ public static void updateComponentTreeUI(@Nullable Component c) { if (c == null) return; - for (Component component : uiTraverser().postOrderDfsTraversal(c)) { + for (Component component : uiTraverser().withRoot(c).postOrderDfsTraversal()) { if (component instanceof JComponent) ((JComponent)component).updateUI(); } c.invalidate(); diff --git a/platform/platform-tests/testSrc/com/intellij/util/containers/TreeTraverserTest.java b/platform/platform-tests/testSrc/com/intellij/util/containers/TreeTraverserTest.java index 4af63d7dc399..c8896ad222e2 100644 --- a/platform/platform-tests/testSrc/com/intellij/util/containers/TreeTraverserTest.java +++ b/platform/platform-tests/testSrc/com/intellij/util/containers/TreeTraverserTest.java @@ -137,26 +137,23 @@ public class TreeTraverserTest extends TestCase { } } - // TreeTraverser ---------------------------------------------- + // TreeTraversal ---------------------------------------------- @NotNull - private static TreeTraverser traverser() { - return new TreeTraverser(Functions.fromMap(numbers())); + private static Function> traverser(TreeTraversal t) { + return t.traversal(Functions.fromMap(numbers())); } public void testSimplePreOrderDfs() { - TreeTraverser t = traverser(); - assertEquals(Arrays.asList(1, 2, 5, 6, 7, 3, 8, 9, 10, 4, 11, 12, 13), t.preOrderDfsTraversal(1).toList()); + assertEquals(Arrays.asList(1, 2, 5, 6, 7, 3, 8, 9, 10, 4, 11, 12, 13), traverser(TreeTraversal.PRE_ORDER_DFS).fun(1).toList()); } public void testSimplePostOrderDfs() { - TreeTraverser t = traverser(); - assertEquals(Arrays.asList(5, 6, 7, 2, 8, 9, 10, 3, 11, 12, 13, 4, 1), t.postOrderDfsTraversal(1).toList()); + assertEquals(Arrays.asList(5, 6, 7, 2, 8, 9, 10, 3, 11, 12, 13, 4, 1), traverser(TreeTraversal.POST_ORDER_DFS).fun(1).toList()); } public void testSimpleBfs() { - TreeTraverser t = traverser(); - assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), t.bfsTraversal(1).toList()); + assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), traverser(TreeTraversal.PLAIN_BFS).fun(1).toList()); } // FilteredTraverser ---------------------------------------------- @@ -219,8 +216,8 @@ public class TreeTraverserTest extends TestCase { return JBIterable.generate(1, k, FIBONACCI).skip(2).take(3); } }); - TreeTraverser.TracingIt it = t.withRoot(1).preOrderDfsTraversal().skip(20).typedIterator(); - TreeTraverser.TracingIt cursor = JBIterator.cursor(it).first(); + TreeTraversal.TracingIt it = t.withRoot(1).preOrderDfsTraversal().skip(20).typedIterator(); + TreeTraversal.TracingIt cursor = JBIterator.cursor(it).first(); assertNotNull(cursor); assertSame(cursor, it); assertEquals(Arrays.asList(20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1), cursor.backtrace().toList()); diff --git a/platform/util/src/com/intellij/util/containers/FilteredTraverser.java b/platform/util/src/com/intellij/util/containers/FilteredTraverser.java index 2d0106a243b9..21d16ca51756 100644 --- a/platform/util/src/com/intellij/util/containers/FilteredTraverser.java +++ b/platform/util/src/com/intellij/util/containers/FilteredTraverser.java @@ -31,6 +31,6 @@ public class FilteredTraverser extends FilteredTraverserBase newInstance(Meta meta) { - return new FilteredTraverser(meta, treeStructure); + return new FilteredTraverser(meta, tree); } } \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/containers/FilteredTraverserBase.java b/platform/util/src/com/intellij/util/containers/FilteredTraverserBase.java index 940fa0aa164f..fa2e6770027e 100644 --- a/platform/util/src/com/intellij/util/containers/FilteredTraverserBase.java +++ b/platform/util/src/com/intellij/util/containers/FilteredTraverserBase.java @@ -25,12 +25,13 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; -public abstract class FilteredTraverserBase> extends TreeTraverser implements Iterable { +public abstract class FilteredTraverserBase> implements Iterable { protected final Meta meta; + protected final Function> tree; - protected FilteredTraverserBase(@Nullable Meta meta, Function> provider) { - super(provider); + protected FilteredTraverserBase(@Nullable Meta meta, Function> tree) { + this.tree = tree; this.meta = meta == null ? Meta.empty() : meta; } @@ -46,50 +47,56 @@ public abstract class FilteredTraverserBase iterator() { - return rawIterable().iterator(); + return traverse().iterator(); } @NotNull protected abstract Self newInstance(Meta meta); @NotNull - public JBIterable rawIterable() { + public JBIterable traverse(TreeTraversal traversal) { + Function> adjusted = new Function>() { + @Override + public Iterable fun(T t) { + return children(t); + } + }; + return traversal.traversal(getRoots(), adjusted).filter(meta.resultFilter); + } + + @NotNull + public JBIterable traverse() { return meta.skipExpanded ? leavesOnlyDfsTraversal() : preOrderDfsTraversal(); } @NotNull public final JBIterable preOrderDfsTraversal() { - return adjust(preOrderDfsTraversal(getRoots())); + return traverse(TreeTraversal.PRE_ORDER_DFS); } @NotNull public final JBIterable postOrderDfsTraversal() { - return adjust(postOrderDfsTraversal(getRoots())); + return traverse(TreeTraversal.POST_ORDER_DFS); } @NotNull public final JBIterable leavesOnlyDfsTraversal() { - return adjust(leavesOnlyDfsTraversal(getRoots())); + return traverse(TreeTraversal.LEAVES_ONLY_DFS); } @NotNull public final JBIterable bfsTraversal() { - return adjust(bfsTraversal(getRoots())); + return traverse(TreeTraversal.PLAIN_BFS); } @NotNull public final JBIterable tracingBfsTraversal() { - return adjust(tracingBfsTraversal(getRoots())); + return traverse(TreeTraversal.TRACING_BFS); } @NotNull public final JBIterable leavesOnlyBfsTraversal() { - return adjust(leavesOnlyBfsTraversal(getRoots())); - } - - @NotNull - private JBIterable adjust(JBIterable traversal) { - return traversal.filter(meta.resultFilter); + return traverse(TreeTraversal.LEAVES_ONLY_BFS); } @NotNull @@ -139,7 +146,7 @@ public abstract class FilteredTraverserBase JBIterable filter(@NotNull Class type) { - return rawIterable().filter(type); + return traverse().filter(type); } @NotNull @@ -148,13 +155,12 @@ public abstract class FilteredTraverserBase children(@NotNull T node) { if (isAlwaysLeaf(node)) return JBIterable.empty(); - Iterable children = super.children(node); - if (meta.childFilter == Conditions.TRUE) return JBIterable.from(children).filter(Conditions.not(meta.excludeFilter)); + JBIterable children = JBIterable.from(tree.fun(node)); + if (meta.childFilter == Conditions.TRUE) return children.filter(Conditions.not(meta.excludeFilter)); // traverse subtree to select accepted children - return newInstance(meta.forChildren(children)).rawIterable(); + return newInstance(meta.forChildren(children)).traverse(); } protected boolean isAlwaysLeaf(@NotNull T node) { @@ -163,12 +169,12 @@ public abstract class FilteredTraverserBase toList() { - return rawIterable().toList(); + return traverse().toList(); } @Override public String toString() { - return rawIterable().toString(); + return traverse().toString(); } diff --git a/platform/util/src/com/intellij/util/containers/JBIterator.java b/platform/util/src/com/intellij/util/containers/JBIterator.java index c197d479ca61..1eee5d9898ae 100644 --- a/platform/util/src/com/intellij/util/containers/JBIterator.java +++ b/platform/util/src/com/intellij/util/containers/JBIterator.java @@ -38,7 +38,7 @@ import java.util.NoSuchElementException; * * @see JBIterable#transform(Function) * @see JBIterable#filter(Condition) - * @see TreeTraverser.TracingIt + * @see TreeTraversal.TracingIt * * @author gregsh * diff --git a/platform/util/src/com/intellij/util/containers/TreeTraverser.java b/platform/util/src/com/intellij/util/containers/TreeTraversal.java similarity index 55% rename from platform/util/src/com/intellij/util/containers/TreeTraverser.java rename to platform/util/src/com/intellij/util/containers/TreeTraversal.java index fc13a0c1232a..fc0e98006519 100644 --- a/platform/util/src/com/intellij/util/containers/TreeTraverser.java +++ b/platform/util/src/com/intellij/util/containers/TreeTraversal.java @@ -27,8 +27,10 @@ import java.util.Iterator; import java.util.Map; /** - * A pruned version of com.google.common.collect.TreeTraverser. - * + * A redesigned version of com.google.common.collect.TreeTraversal. + *

+ * The original JavaDoc: + *

* Views elements of a type {@code T} as nodes in a tree, and provides methods to traverse the trees * induced by this traverser. * @@ -43,31 +45,70 @@ import java.util.Map; * / | \ f * a b c }

* - *

can be iterated over in preorder (hdabcegf), postorder (abcdefgh), or breadth-first order + *

can be iterated over in pre-order (hdabcegf), post-order (abcdefgh), or breadth-first order * (hdegabcf). * *

Null nodes are strictly forbidden. * * @author Louis Wasserman + *

+ * + * @author gregsh */ -public class TreeTraverser { +public abstract class TreeTraversal { - protected final Function> treeStructure; + private final String debugName; - public TreeTraverser(Function> provider) { - treeStructure = provider; + protected TreeTraversal(@NotNull String debugName) { + this.debugName = debugName; + } + + @NotNull + public JBIterable traversal(@NotNull final Iterable roots, @NotNull final Function> tree) { + return new JBIterable() { + @NotNull + @Override + public Iterator iterator() { + return createIterator(roots, tree); + } + }; + } + + @NotNull + public JBIterable traversal(@Nullable final T root, @NotNull final Function> tree) { + return traversal(ContainerUtil.createMaybeSingletonList(root), tree); + } + + @NotNull + public Function> traversal(@NotNull final Function> tree) { + return new Function>() { + @Override + public JBIterable fun(T t) { + return traversal(t, tree); + } + }; } /** - * Returns the children of the specified node. Must not contain null. + * Creates a new iterator for this type of traversal. + * @param roots tree roots + * @param tree tree structure the children for parent function. + * May return null (useful for map representation). */ @NotNull - public Iterable children(@NotNull T root) { - Iterable result = treeStructure.fun(root); - return result != null ? result : JBIterable.empty(); + public abstract It createIterator(@NotNull Iterable roots, @NotNull Function> tree); + + @Override + public String toString() { + return debugName; } - public static abstract class TracingIt extends JBIterator { + public static abstract class It extends JBIterator { + + } + + public static abstract class TracingIt extends It { + @Nullable public abstract T parent(); @@ -75,113 +116,86 @@ public class TreeTraverser { public abstract JBIterable backtrace(); } + @NotNull + private static Iterable children(@NotNull T root, @NotNull Function> tree) { + return JBIterable.from(tree.fun(root)); + } + /** - * Returns an unmodifiable iterable over the nodes in a tree structure, using pre-order + * Returns an iterator over the nodes in a tree structure, using pre-order * traversal. That is, each node's subtrees are traversed after the node itself is returned. * *

No guarantees are made about the behavior of the traversal when nodes change while * iteration is in progress or when the iterators generated by {@link #children} are advanced. */ @NotNull - public final JBIterable preOrderDfsTraversal(@NotNull final Iterable roots) { - return new JBIterable() { - @Override - public TracingIt iterator() { - return new PreOrderIt((Iterable)roots); - } - }; - } + public static final TreeTraversal PRE_ORDER_DFS = new TreeTraversal("PRE_ORDER_DFS") { + @NotNull + @Override + public It createIterator(@NotNull Iterable roots, @NotNull Function> tree) { + return new PreOrderIt(roots, tree); + } + }; /** - * @see #preOrderDfsTraversal(Iterable) - */ - @NotNull - public final JBIterable preOrderDfsTraversal(@Nullable T root) { - return preOrderDfsTraversal(ContainerUtil.createMaybeSingletonList(root)); - } - - - /** - * Returns an unmodifiable iterable over the nodes in a tree structure, using post-order + * Returns an iterator over the nodes in a tree structure, using post-order * traversal. That is, each node's subtrees are traversed before the node itself is returned. *

*

No guarantees are made about the behavior of the traversal when nodes change while * iteration is in progress or when the iterators generated by {@link #children} are advanced. */ @NotNull - public final JBIterable postOrderDfsTraversal(@NotNull final Iterable roots) { - return new JBIterable() { - @Override - public Iterator iterator() { - return new PostOrderIt(roots); - } - }; - } + public static final TreeTraversal POST_ORDER_DFS = new TreeTraversal("POST_ORDER_DFS") { + @NotNull + @Override + public It createIterator(@NotNull Iterable roots, @NotNull Function> tree) { + return new PostOrderIt(roots, tree); + } + }; - /** - * @see #postOrderDfsTraversal(Iterable) - */ - @NotNull - public final JBIterable postOrderDfsTraversal(@Nullable T root) { - return postOrderDfsTraversal(ContainerUtil.createMaybeSingletonList(root)); - } @NotNull - public final JBIterable leavesOnlyDfsTraversal(@NotNull final Iterable roots) { - return new JBIterable() { - @Override - public Iterator iterator() { - return new LeavesDfsIt(roots); - } - }; - } + public static final TreeTraversal LEAVES_ONLY_DFS = new TreeTraversal("LEAVES_ONLY_DFS") { + @NotNull + @Override + public It createIterator(@NotNull Iterable roots, @NotNull Function> tree) { + return new LeavesDfsIt(roots, tree); + } + }; /** - * Returns an unmodifiable iterable over the nodes in a tree structure, using breadth-first + * Returns an iterator over the nodes in a tree structure, using breadth-first * traversal. That is, all the nodes of depth 0 are returned, then depth 1, then 2, and so on. *

*

No guarantees are made about the behavior of the traversal when nodes change while * iteration is in progress or when the iterators generated by {@link #children} are advanced. */ @NotNull - public final JBIterable bfsTraversal(@NotNull final Iterable roots) { - return new JBIterable() { - @Override - public Iterator iterator() { - return new BfsIterator(roots); - } - }; - } + public static final TreeTraversal PLAIN_BFS = new TreeTraversal("PLAIN_BFS") { + @NotNull + @Override + public It createIterator(@NotNull Iterable roots, @NotNull Function> tree) { + return new BfsIterator(roots, tree); + } + }; @NotNull - public final JBIterable bfsTraversal(@Nullable T root) { - return bfsTraversal(ContainerUtil.createMaybeSingletonList(root)); - } + public static final TreeTraversal TRACING_BFS = new TreeTraversal("TRACING_BFS") { + @NotNull + @Override + public It createIterator(@NotNull Iterable roots, @NotNull Function> tree) { + return new TracingBfsIt(roots, tree); + } + }; @NotNull - public final JBIterable tracingBfsTraversal(@NotNull final Iterable roots) { - return new JBIterable() { - @Override - public TracingIt iterator() { - return new TracingBfsIt(roots); - } - }; - } - - @NotNull - public final JBIterable tracingBfsTraversal(@Nullable T root) { - return tracingBfsTraversal(ContainerUtil.createMaybeSingletonList(root)); - } - - @NotNull - public final JBIterable leavesOnlyBfsTraversal(@NotNull final Iterable roots) { - return new JBIterable() { - @Override - public Iterator iterator() { - return new LeavesBfsIt(roots); - } - }; - } + public static final TreeTraversal LEAVES_ONLY_BFS = new TreeTraversal("LEAVES_ONLY_BFS") { + @NotNull + @Override + public It createIterator(@NotNull Iterable roots, @NotNull Function> tree) { + return new LeavesBfsIt(roots, tree); + } + }; // ----------------------------------------------------------------------------- @@ -211,12 +225,14 @@ public class TreeTraverser { } } - private final class PreOrderIt extends DfsIt { + private final static class PreOrderIt extends DfsIt { + final Function> tree; int doneCount; - PreOrderIt(@NotNull Iterable roots) { - Iterator iterator = roots.iterator(); + PreOrderIt(@NotNull Iterable roots, Function> tree) { + this.tree = tree; + Iterator iterator = roots.iterator(); if (iterator.hasNext()) { stack.addLast(Pair.>create(null, iterator)); } @@ -232,18 +248,21 @@ public class TreeTraverser { } T result = top.second.next(); if (!top.second.hasNext()) doneCount++; - Iterator childItr = children(result).iterator(); + Iterator childItr = children(result, tree).iterator(); stack.addLast(Pair.>create(result, childItr)); if (!childItr.hasNext()) doneCount++; return result; } } - private final class PostOrderIt extends DfsIt { + private static final class PostOrderIt extends DfsIt { - PostOrderIt(@NotNull Iterable roots) { + final Function> tree; + + PostOrderIt(@NotNull Iterable roots, Function> tree) { + this.tree = tree; for (T root : roots) { - stack.addLast(Pair.>create(root, children(root).iterator())); + stack.addLast(Pair.>create(root, children(root, tree).iterator())); } } @@ -253,7 +272,7 @@ public class TreeTraverser { Pair> top = stack.getLast(); if (top.second.hasNext()) { T child = top.second.next(); - stack.addLast(Pair.>create(child, children(child).iterator())); + stack.addLast(Pair.>create(child, children(child, tree).iterator())); } else { stack.removeLast(); @@ -264,11 +283,14 @@ public class TreeTraverser { } } - private final class LeavesDfsIt extends DfsIt { + private final static class LeavesDfsIt extends DfsIt { - LeavesDfsIt(@NotNull Iterable roots) { + final Function> tree; + + LeavesDfsIt(@NotNull Iterable roots, Function> tree) { + this.tree = tree; for (T root : roots) { - Iterator childrenIt = children(root).iterator(); + Iterator childrenIt = children(root, tree).iterator(); stack.addLast(Pair.>create(root, childrenIt.hasNext() ? childrenIt : null)); } } @@ -279,7 +301,7 @@ public class TreeTraverser { Pair> top = stack.getLast(); if (top.second != null && top.second.hasNext()) { T child = top.second.next(); - Iterator childrenIt = children(child).iterator(); + Iterator childrenIt = children(child, tree).iterator(); if (childrenIt.hasNext()) { stack.addLast(Pair.>create(child, childrenIt)); } @@ -296,10 +318,13 @@ public class TreeTraverser { } } - private final class BfsIterator extends JBIterator { + private static final class BfsIterator extends It { + + final Function> tree; final ArrayDeque queue = new ArrayDeque(); - BfsIterator(@NotNull Iterable roots) { + BfsIterator(@NotNull Iterable roots, Function> tree) { + this.tree = tree; JBIterable.from(roots).addAllTo(queue); } @@ -307,15 +332,18 @@ public class TreeTraverser { public T nextImpl() { if (queue.isEmpty()) return stop(); T result = queue.remove(); - for (T t : children(result)) queue.add(t); + for (T t : children(result, tree)) queue.add(t); return result; } } - private final class LeavesBfsIt extends JBIterator { + private static final class LeavesBfsIt extends It { + + final Function> tree; final ArrayDeque queue = new ArrayDeque(); - LeavesBfsIt(@NotNull Iterable roots) { + LeavesBfsIt(@NotNull Iterable roots, Function> tree) { + this.tree = tree; JBIterable.from(roots).addAllTo(queue); } @@ -323,7 +351,7 @@ public class TreeTraverser { public T nextImpl() { while (!queue.isEmpty()) { T result = queue.remove(); - Iterator childrenIt = children(result).iterator(); + Iterator childrenIt = children(result, tree).iterator(); if (!childrenIt.hasNext()) return result; while (childrenIt.hasNext()) queue.add(childrenIt.next()); } @@ -331,12 +359,15 @@ public class TreeTraverser { } } - private final class TracingBfsIt extends TracingIt { + private final static class TracingBfsIt extends TracingIt { + + final Function> tree; final ArrayDeque queue = new ArrayDeque(); final Map paths = ContainerUtil.newTroveMap(ContainerUtil.identityStrategy()); T cur; - TracingBfsIt(@NotNull Iterable roots) { + TracingBfsIt(@NotNull Iterable roots, Function> tree) { + this.tree = tree; JBIterable.from(roots).addAllTo(queue); } @@ -344,7 +375,7 @@ public class TreeTraverser { public T nextImpl() { if (queue.isEmpty()) return stop(); T result = queue.remove(); - for (T t : children(result)) { + for (T t : children(result, tree)) { if (paths.containsKey(t)) continue; queue.add(t); paths.put(t, result); From 04825889a9203ea19a586f00889c9b0a64fa02ea Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Mon, 10 Aug 2015 15:58:06 +0300 Subject: [PATCH 33/99] JBIterable: stateful filters/transforms/generators JBIterator: ability to introspect operations --- .../util/containers/TreeTraverserTest.java | 37 ++++++++++ .../intellij/util/containers/JBIterable.java | 47 ++++++++++--- .../intellij/util/containers/JBIterator.java | 67 ++++++++++++------- 3 files changed, 117 insertions(+), 34 deletions(-) diff --git a/platform/platform-tests/testSrc/com/intellij/util/containers/TreeTraverserTest.java b/platform/platform-tests/testSrc/com/intellij/util/containers/TreeTraverserTest.java index c8896ad222e2..0911b7c74fbb 100644 --- a/platform/platform-tests/testSrc/com/intellij/util/containers/TreeTraverserTest.java +++ b/platform/platform-tests/testSrc/com/intellij/util/containers/TreeTraverserTest.java @@ -68,6 +68,16 @@ public class TreeTraverserTest extends TestCase { } }; + private static final Function FIBONACCI2 = new JBIterable.StatefulTransform() { + int k0; + @Override + public Integer fun(Integer k) { + int t = k0; + k0 = k; + return t + k; + } + }; + @NotNull private static Condition LESS_THAN(final int max) { return new Condition() { @@ -90,6 +100,13 @@ public class TreeTraverserTest extends TestCase { // JBIterable ---------------------------------------------- + public void testAppend() { + JBIterable it = JBIterable.of(1, 2, 3).append(JBIterable.of(4, 5, 6)).append(7); + assertEquals(7, it.size()); + assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7), it.toList()); + assertTrue(it.contains(5)); + } + public void testGenerateRepeat() { JBIterable it = JBIterable.generate(1, INCREMENT).take(3).repeat(3); assertEquals(9, it.size()); @@ -137,6 +154,26 @@ public class TreeTraverserTest extends TestCase { } } + public void testStatefulFilter() { + JBIterable it = JBIterable.generate(1, INCREMENT).take(5).filter(new JBIterable.StatefulFilter() { + int prev; + @Override + public boolean value(Integer integer) { + boolean b = integer > prev; + if (b) prev = integer; + return b; + } + }); + assertEquals(Arrays.asList(1, 2, 3, 4, 5), it.toList()); + assertEquals(Arrays.asList(1, 2, 3, 4, 5), it.toList()); + } + + public void testStatefulGenerator() { + JBIterable it = JBIterable.generate(1, FIBONACCI2).take(8); + assertEquals(Arrays.asList(1, 1, 2, 3, 5, 8, 13, 21), it.toList()); + assertEquals(Arrays.asList(1, 1, 2, 3, 5, 8, 13, 21), it.toList()); + } + // TreeTraversal ---------------------------------------------- @NotNull diff --git a/platform/util/src/com/intellij/util/containers/JBIterable.java b/platform/util/src/com/intellij/util/containers/JBIterable.java index c2d34b994d58..f9d9c816d5ab 100644 --- a/platform/util/src/com/intellij/util/containers/JBIterable.java +++ b/platform/util/src/com/intellij/util/containers/JBIterable.java @@ -108,6 +108,7 @@ public abstract class JBIterable implements Iterable { return new JBIterable() { @Override public Iterator iterator() { + final Function fun = Stateful.copy(generator); return new JBIterator() { E cur = first; @@ -115,7 +116,7 @@ public abstract class JBIterable implements Iterable { public E nextImpl() { E result = cur; if (result == null) return stop(); - cur = generator.fun(cur); + cur = fun.fun(cur); return result; } }; @@ -228,14 +229,14 @@ public abstract class JBIterable implements Iterable { * {@code Iterator} supports it. */ public final JBIterable append(@Nullable Iterable other) { - return other == null ? this : this == EMPTY ? from(other) : from(ContainerUtil.concat(myIterable, other)); + return other == null ? this : this == EMPTY ? from(other) : of(myIterable, other).flatten(Functions., Iterable>identity()); } public final JBIterable append(@Nullable Iterable other, @NotNull Function> fun) { return other == null ? this : this == EMPTY ? from(other).flatten(fun) : append(from(other).flatten(fun)); } - public final JBIterable repeat(final int count) { + public final JBIterable repeat(int count) { Function, JBIterable> fun = Functions.identity(); return generate(this, fun).take(count).flatten(fun); } @@ -259,7 +260,7 @@ public abstract class JBIterable implements Iterable { return intercept(new Function, Iterator>() { @Override public Iterator fun(Iterator iterator) { - return JBIterator.from(iterator).filter(condition); + return JBIterator.from(iterator).filter(Stateful.copy(condition)); } }); } @@ -288,7 +289,7 @@ public abstract class JBIterable implements Iterable { return intercept(new Function, Iterator>() { @Override public Iterator fun(Iterator iterator) { - return JBIterator.from(iterator).takeWhile(condition); + return JBIterator.from(iterator).takeWhile(Stateful.copy(condition)); } }); } @@ -308,7 +309,7 @@ public abstract class JBIterable implements Iterable { return intercept(new Function, Iterator>() { @Override public Iterator fun(Iterator iterator) { - return JBIterator.from(iterator).skipWhile(condition); + return JBIterator.from(iterator).skipWhile(Stateful.copy(condition)); } }); } @@ -326,7 +327,7 @@ public abstract class JBIterable implements Iterable { return intercept(new Function, Iterator>() { @Override public Iterator fun(Iterator iterator) { - return JBIterator.from(iterator).transform(function); + return JBIterator.from(iterator).transform(Stateful.copy(function)); } }); } @@ -344,13 +345,14 @@ public abstract class JBIterable implements Iterable { return intercept(new Function, Iterator>() { @Override public Iterator fun(final Iterator iterator) { + final Function> fun = Stateful.copy(function); return new JBIterator() { Iterator cur; @Override public T nextImpl() { while ((cur == null || !cur.hasNext()) && iterator.hasNext()) { - cur = function.fun(iterator.next()).iterator(); + cur = fun.fun(iterator.next()).iterator(); } if (cur == null || !cur.hasNext()) return stop(); return cur.next(); @@ -456,4 +458,33 @@ public abstract class JBIterable implements Iterable { } return collection; } + + @SuppressWarnings("unchecked") + public abstract static class Stateful implements Cloneable { + + @NotNull + static T copy(@NotNull T o) { + if (!(o instanceof Stateful)) { + return o; + } + return (T)((Stateful)o).clone(); + } + + public Self clone() { + try { + return (Self)super.clone(); + } + catch (CloneNotSupportedException e) { + throw new AssertionError(e); + } + } + } + + public abstract static class StatefulFilter extends Stateful implements Condition { + + } + + public abstract static class StatefulTransform extends Stateful implements Function { + + } } diff --git a/platform/util/src/com/intellij/util/containers/JBIterator.java b/platform/util/src/com/intellij/util/containers/JBIterator.java index 1eee5d9898ae..ababafdf6474 100644 --- a/platform/util/src/com/intellij/util/containers/JBIterator.java +++ b/platform/util/src/com/intellij/util/containers/JBIterator.java @@ -68,7 +68,7 @@ public abstract class JBIterator implements Iterator { } private Object cur = INIT; - private final Op firstOp = new Op(); + private final Op firstOp = new Op(null); private Op lastOp = firstOp; protected abstract E nextImpl(); @@ -125,31 +125,21 @@ public abstract class JBIterator implements Iterator { } @NotNull - public final JBIterator transform(@NotNull final Function function) { - return addOp(new Op() { + public final JBIterator transform(@NotNull Function function) { + return addOp(new Op>(function) { @Override public Object apply(Object o) { - return function.fun((E)o); - } - - @Override - public String toString() { - return toShortString(function); + return impl.fun((E)o); } }); } @NotNull - public final JBIterator filter(@NotNull final Condition condition) { - return addOp(new Op() { + public final JBIterator filter(@NotNull Condition condition) { + return addOp(new Op>(condition) { @Override public Object apply(Object o) { - return condition.value((E)o) ? o : SKIP; - } - - @Override - public String toString() { - return toShortString(condition); + return impl.value((E)o) ? o : SKIP; } }); } @@ -160,16 +150,16 @@ public abstract class JBIterator implements Iterator { } @NotNull - public final JBIterator takeWhile(@NotNull final Condition condition) { - return addOp(new Op() { + public final JBIterator takeWhile(@NotNull Condition condition) { + return addOp(new Op>(condition) { @Override public Object apply(Object o) { - return condition.value((E)o) ? o : stop(); + return impl.value((E)o) ? o : stop(); } @Override public String toString() { - return "while:" + toShortString(condition); + return "takeWhile:" + super.toString(); } }); } @@ -181,7 +171,7 @@ public abstract class JBIterator implements Iterator { @NotNull public final JBIterator skipWhile(@NotNull final Condition condition) { - return addOp(new Op() { + return addOp(new Op>(condition) { boolean active = true; @@ -194,7 +184,7 @@ public abstract class JBIterator implements Iterator { @Override public String toString() { - return "skip:" + toShortString(condition); + return "skipWhile:" + super.toString(); } }); } @@ -218,13 +208,28 @@ public abstract class JBIterator implements Iterator { @Override public String toString() { - JBIterable ops = JBIterable.generate(firstOp.nextOp, new Function() { + JBIterable ops = operationsImpl(); + return "{cur=" + cur + "; ops[" + ops.size() + "]=" + ops + "}"; + } + + @NotNull + public JBIterable operations() { + return operationsImpl().transform(new Function() { + @Override + public Object fun(Op op) { + return op.impl; + } + }); + } + + @NotNull + private JBIterable operationsImpl() { + return JBIterable.generate(firstOp.nextOp, new Function() { @Override public Op fun(Op op) { return op.nextOp; } }); - return "{cur=" + cur + "; ops[" + ops.size() + "]=" + ops + "}"; } private static String toShortString(@NotNull Object o) { @@ -239,12 +244,22 @@ public abstract class JBIterator implements Iterator { } }; - private static class Op { + private static class Op { + final T impl; Op nextOp; + public Op(T impl) { + this.impl = impl; + } + Object apply(Object o) { throw new UnsupportedOperationException(); } + + @Override + public String toString() { + return impl == null ? "" : toShortString(impl); + } } private static class CountDown implements Condition { From eacdb9fa668ced6d0f4c0d95ccb7c8889a9e28a4 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 10 Aug 2015 14:57:15 +0200 Subject: [PATCH 34/99] @TestOnly UpdateRequestsQueue.waitUntilRefreshed (IDEA-CR-4267) --- .../com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java index 9b064f67b38c..bdc806669ae0 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java @@ -28,6 +28,7 @@ import com.intellij.util.Consumer; import com.intellij.util.concurrency.Semaphore; import com.intellij.util.io.storage.HeavyProcessLatch; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import javax.swing.*; import java.util.ArrayList; @@ -150,6 +151,7 @@ public class UpdateRequestsQueue { LOG.debug("Stop finished for project: " + myProject.getName()); } + @TestOnly public void waitUntilRefreshed() { while (true) { final Semaphore semaphore = new Semaphore(); From 7812538433ed429d9c8516c336370e57e005a793 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 10 Aug 2015 16:04:11 +0200 Subject: [PATCH 35/99] Idea sets default scaling on Linux to 1.25f, which is wrong. --- platform/util/src/com/intellij/util/ui/JBUI.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/util/src/com/intellij/util/ui/JBUI.java b/platform/util/src/com/intellij/util/ui/JBUI.java index 1684f553268f..91dd0dd296d2 100644 --- a/platform/util/src/com/intellij/util/ui/JBUI.java +++ b/platform/util/src/com/intellij/util/ui/JBUI.java @@ -85,6 +85,10 @@ public class JBUI { else if (scale < 2f) scale = 1.75f; else scale = 2.0f; + if (SystemInfo.isLinux && scale == 1.25f) { + //Default UI font size for Unity and Gnome is 15. Scaling factor 1.25f works badly on Linux + scale = 1f; + } SCALE_FACTOR = scale; IconLoader.setScale(scale); } From 8c61dbb2e7e595d54c6c404d3ac8662f28f0a6fb Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 10 Aug 2015 17:22:06 +0300 Subject: [PATCH 36/99] EA-71679 - NPE: XDebuggerEvaluateActionHandler.showDialog --- .../handlers/XDebuggerEvaluateActionHandler.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java index 92e353b9346c..9afff78ef6e5 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java @@ -79,12 +79,14 @@ public class XDebuggerEvaluateActionHandler extends XDebuggerActionHandler { value.calculateEvaluationExpression().done(new Consumer() { @Override public void consume(final XExpression expression) { - AppUIUtil.invokeOnEdt(new Runnable() { - @Override - public void run() { - showDialog(session, file, editorsProvider, stackFrame, evaluator, expression); - } - }); + if (expression != null) { + AppUIUtil.invokeOnEdt(new Runnable() { + @Override + public void run() { + showDialog(session, file, editorsProvider, stackFrame, evaluator, expression); + } + }); + } } }); return; @@ -100,7 +102,7 @@ public class XDebuggerEvaluateActionHandler extends XDebuggerActionHandler { XDebuggerEditorsProvider editorsProvider, XStackFrame stackFrame, XDebuggerEvaluator evaluator, - XExpression expression) { + @NotNull XExpression expression) { if (expression.getLanguage() == null) { Language language = null; if (stackFrame != null) { From 614a2c07b9232c644dda5e9741f7fbf0cf10cc15 Mon Sep 17 00:00:00 2001 From: Sergey Savenko Date: Mon, 10 Aug 2015 17:29:44 +0300 Subject: [PATCH 37/99] Remove tabbed pane wrapper is null assertion Adding a new tabbed component in com.intellij.openapi.fileEditor.impl.EditorComposite.addEditor can cause actions update, which requires a currently selected editor. The removed assertion failed in this case. --- .../openapi/fileEditor/impl/EditorWithProviderComposite.java | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java index 63677ed684c1..a11827777575 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java @@ -62,7 +62,6 @@ public class EditorWithProviderComposite extends EditorComposite { public Pair getSelectedEditorWithProvider() { LOG.assertTrue(myEditors.length > 0, myEditors.length); if (myEditors.length == 1) { - LOG.assertTrue(myTabbedPaneWrapper == null); return Pair.create(myEditors[0], myProviders[0]); } else { // we have to get myEditor from tabbed pane From e8b2c686f4e8678e78a5c245996e5524e6f4a4e5 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Sun, 9 Aug 2015 21:03:11 +0300 Subject: [PATCH 38/99] fixed button size in new project study panel --- .../com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java index 7fff347c61a6..6aac2ca5c52a 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java @@ -16,14 +16,15 @@ import com.intellij.util.Consumer; import com.jetbrains.edu.courseFormat.Course; import com.jetbrains.edu.learning.StudyUtils; import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator; -import com.jetbrains.edu.stepic.StudySettings; import com.jetbrains.edu.stepic.CourseInfo; import com.jetbrains.edu.stepic.EduStepicConnector; +import com.jetbrains.edu.stepic.StudySettings; import icons.InteractiveLearningIcons; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; @@ -51,6 +52,8 @@ public class StudyNewProjectPanel{ public StudyNewProjectPanel(StudyProjectGenerator generator) { myGenerator = generator; myAvailableCourses = myGenerator.getCourses(false); + myBrowseButton.setPreferredSize(new Dimension(28, 28)); + myRefreshButton.setPreferredSize(new Dimension(28, 28)); if (myAvailableCourses.isEmpty()) { setError(CONNECTION_ERROR); } From f47356801a51480129edd926b7d77361edb1ae12 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 10 Aug 2015 16:43:29 +0300 Subject: [PATCH 39/99] update toolwindow buttons and task text --- .../jetbrains/edu/learning/StudyUtils.java | 10 ++---- .../learning/actions/StudyCheckAction.java | 7 +++- .../actions/StudyRefreshTaskFileAction.java | 6 ++-- .../actions/StudyTaskNavigationAction.java | 5 +++ .../edu/learning/ui/StudyToolWindow.java | 33 +++++++++++++------ 5 files changed, 40 insertions(+), 21 deletions(-) diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyUtils.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyUtils.java index 73ba099fbc2e..1d129c8c8a3d 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyUtils.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyUtils.java @@ -106,15 +106,11 @@ public class StudyUtils { public static void updateAction(@NotNull final AnActionEvent e) { final Presentation presentation = e.getPresentation(); presentation.setEnabled(false); - presentation.setVisible(false); final Project project = e.getProject(); if (project != null) { - final FileEditor[] editors = FileEditorManager.getInstance(project).getAllEditors(); - for (FileEditor editor : editors) { - if (editor instanceof StudyEditor) { - presentation.setEnabled(true); - presentation.setVisible(true); - } + final StudyEditor studyEditor = getSelectedStudyEditor(project); + if (studyEditor != null) { + presentation.setEnabled(true); } } } diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java index 88ea6492ec32..596446f3daaa 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java @@ -7,6 +7,7 @@ import com.intellij.ide.projectView.ProjectView; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.KeyboardShortcut; +import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; @@ -396,6 +397,10 @@ public class StudyCheckAction extends DumbAwareAction { @Override public void update(AnActionEvent e) { - e.getPresentation().setEnabled(!checkInProgress); + final Presentation presentation = e.getPresentation(); + StudyUtils.updateAction(e); + if (presentation.isEnabled()) { + presentation.setEnabled(!checkInProgress); + } } } diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java index f36e544c1e4f..bca245a7e9ca 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java @@ -175,13 +175,13 @@ public class StudyRefreshTaskFileAction extends DumbAwareAction { @Override public void update(AnActionEvent event) { - EduUtils.enableAction(event, false); + StudyUtils.updateAction(event); final Project project = event.getProject(); if (project != null) { StudyEditor studyEditor = StudyUtils.getSelectedStudyEditor(project); StudyState studyState = new StudyState(studyEditor); - if (studyState.isValid()) { - EduUtils.enableAction(event, true); + if (!studyState.isValid()) { + event.getPresentation().setEnabled(false); } } } diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyTaskNavigationAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyTaskNavigationAction.java index fca1daadea3e..25111e7b52c5 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyTaskNavigationAction.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyTaskNavigationAction.java @@ -115,4 +115,9 @@ abstract public class StudyTaskNavigationAction extends DumbAwareAction { protected abstract String getNavigationFinishedMessage(); protected abstract Task getTargetTask(@NotNull final Task sourceTask); + + @Override + public void update(AnActionEvent e) { + StudyUtils.updateAction(e); + } } diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java index 9703f587c109..a55a6f321869 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java @@ -43,13 +43,23 @@ import javax.swing.border.EmptyBorder; public class StudyToolWindow extends SimpleToolWindowPanel implements DataProvider, Disposable { + private static final String EMPTY_TASK_TEXT = "Please, open any task to see task description"; + public StudyToolWindow(final Project project) { super(true, true); JPanel toolbarPanel = createToolbarPanel(); setToolbar(toolbarPanel); final StudyEditor studyEditor = StudyUtils.getSelectedStudyEditor(project); - if (studyEditor == null) return; + if (studyEditor == null) { + final JTextPane taskTextPane = new JTextPane(); + taskTextPane.setEditable(false); + taskTextPane.setText(EMPTY_TASK_TEXT); + taskTextPane.setBackground(EditorColorsManager.getInstance().getGlobalScheme().getDefaultBackground()); + taskTextPane.setBorder(new EmptyBorder(15, 20, 0, 100)); + setContent(taskTextPane); + return; + } Task task = studyEditor.getTaskFile().getTask(); if (task != null) { @@ -92,22 +102,24 @@ public class StudyToolWindow extends SimpleToolWindowPanel implements DataProvid private Project myProject; private JTextPane myTaskTextPane; - StudyFileEditorManagerListener(@NotNull final Project project, JTextPane taskTextPane){ + StudyFileEditorManagerListener(@NotNull final Project project, JTextPane taskTextPane) { myProject = project; myTaskTextPane = taskTextPane; } - @Override - public void fileOpened (@NotNull FileEditorManager source, @NotNull VirtualFile file){ + + @Override + public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) { Task task = getTask(file); setTaskText(task); } - @Override - public void fileClosed (@NotNull FileEditorManager source, @NotNull VirtualFile file){ + @Override + public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) { + myTaskTextPane.setText(EMPTY_TASK_TEXT); } - @Override - public void selectionChanged (@NotNull FileEditorManagerEvent event){ + @Override + public void selectionChanged(@NotNull FileEditorManagerEvent event) { VirtualFile file = event.getNewFile(); if (file != null) { Task task = getTask(file); @@ -115,8 +127,8 @@ public class StudyToolWindow extends SimpleToolWindowPanel implements DataProvid } } - @Nullable - private Task getTask (@NotNull VirtualFile file){ + @Nullable + private Task getTask(@NotNull VirtualFile file) { TaskFile taskFile = StudyUtils.getTaskFile(myProject, file); if (taskFile != null) { return taskFile.getTask(); @@ -128,6 +140,7 @@ public class StudyToolWindow extends SimpleToolWindowPanel implements DataProvid private void setTaskText(@Nullable final Task task) { if (task == null) { + myTaskTextPane.setText(EMPTY_TASK_TEXT); return; } String text = task.getText(); From 3a9160f5be5352128ae4f7157b2497fa37116327 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 10 Aug 2015 17:22:51 +0300 Subject: [PATCH 40/99] fixed EDU-276 Pycharm education - how to change font size of task description area in lessons --- .../edu/learning/ui/StudyToolWindow.java | 36 +++++++++++++------ .../learning/ui/StudyToolWindowFactory.java | 1 - 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java index a55a6f321869..841162e1dadf 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java @@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.FileEditorManagerEvent; import com.intellij.openapi.fileEditor.FileEditorManagerListener; @@ -40,6 +41,9 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.EmptyBorder; +import javax.swing.text.html.HTMLDocument; +import javax.swing.text.html.HTMLEditorKit; +import java.awt.*; public class StudyToolWindow extends SimpleToolWindowPanel implements DataProvider, Disposable { @@ -51,28 +55,21 @@ public class StudyToolWindow extends SimpleToolWindowPanel implements DataProvid setToolbar(toolbarPanel); final StudyEditor studyEditor = StudyUtils.getSelectedStudyEditor(project); + final JTextPane taskTextPane = createTaskTextPane(); + if (studyEditor == null) { - final JTextPane taskTextPane = new JTextPane(); - taskTextPane.setEditable(false); taskTextPane.setText(EMPTY_TASK_TEXT); - taskTextPane.setBackground(EditorColorsManager.getInstance().getGlobalScheme().getDefaultBackground()); - taskTextPane.setBorder(new EmptyBorder(15, 20, 0, 100)); setContent(taskTextPane); return; } - Task task = studyEditor.getTaskFile().getTask(); + final Task task = studyEditor.getTaskFile().getTask(); if (task != null) { final String taskText = task.getText(); - - final JTextPane taskTextPane = new JTextPane(); JBScrollPane scrollPane = new JBScrollPane(taskTextPane); - taskTextPane.setContentType("text/html"); - taskTextPane.setEditable(false); taskTextPane.setText(taskText); taskTextPane.addHyperlinkListener(BrowserHyperlinkListener.INSTANCE); - taskTextPane.setBackground(EditorColorsManager.getInstance().getGlobalScheme().getDefaultBackground()); - taskTextPane.setBorder(new EmptyBorder(15, 20, 0, 100)); + setContent(scrollPane); final FileEditorManagerListener listener = new StudyFileEditorManagerListener(project, taskTextPane); @@ -80,6 +77,23 @@ public class StudyToolWindow extends SimpleToolWindowPanel implements DataProvid } } + @NotNull + private JTextPane createTaskTextPane() { + final JTextPane taskTextPane = new JTextPane(); + taskTextPane.setContentType(new HTMLEditorKit().getContentType()); + final EditorColorsScheme editorColorsScheme = EditorColorsManager.getInstance().getGlobalScheme(); + int fontSize = editorColorsScheme.getEditorFontSize(); + final String fontName = editorColorsScheme.getEditorFontName(); + final Font font = new Font(fontName, Font.PLAIN, fontSize); + String bodyRule = "body { font-family: " + font.getFamily() + "; " + + "font-size: " + font.getSize() + "pt; }"; + ((HTMLDocument)taskTextPane.getDocument()).getStyleSheet().addRule(bodyRule); + taskTextPane.setEditable(false); + taskTextPane.setBackground(EditorColorsManager.getInstance().getGlobalScheme().getDefaultBackground()); + taskTextPane.setBorder(new EmptyBorder(15, 20, 0, 100)); + return taskTextPane; + } + public void dispose() { } diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindowFactory.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindowFactory.java index 4522064be221..d847b4606468 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindowFactory.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindowFactory.java @@ -25,7 +25,6 @@ public class StudyToolWindowFactory implements ToolWindowFactory, DumbAware { final Content content = contentManager.getFactory().createContent(studyToolWindow, null, false); contentManager.addContent(content); Disposer.register(project, studyToolWindow); - } } From f5658cd0feb2c9996e247b881a7992544aaa2be9 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 10 Aug 2015 18:18:47 +0300 Subject: [PATCH 41/99] do not show empty author label --- .../com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java index 6aac2ca5c52a..a32674311844 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java @@ -62,7 +62,8 @@ public class StudyNewProjectPanel{ myCoursesComboBox.addItem(courseInfo); } final CourseInfo selectedCourse = StudyUtils.getFirst(myAvailableCourses); - myAuthorLabel.setText("Author: " + Course.getAuthorsString(selectedCourse.getAuthors())); + final String authorsString = Course.getAuthorsString(selectedCourse.getAuthors()); + myAuthorLabel.setText(!StringUtil.isEmptyOrSpaces(authorsString) ? "Author: " + authorsString : ""); myDescriptionLabel.setText(selectedCourse.getDescription()); //setting the first course in list as selected myGenerator.setSelectedCourse(selectedCourse); @@ -212,7 +213,8 @@ public class StudyNewProjectPanel{ myDescriptionLabel.setText(""); return; } - myAuthorLabel.setText("Author: " + Course.getAuthorsString(selectedCourse.getAuthors())); + final String authorsString = Course.getAuthorsString(selectedCourse.getAuthors()); + myAuthorLabel.setText(!StringUtil.isEmptyOrSpaces(authorsString) ?"Author: " + authorsString : ""); myCoursesComboBox.removeItem(CourseInfo.INVALID_COURSE); myDescriptionLabel.setText(selectedCourse.getDescription()); myGenerator.setSelectedCourse(selectedCourse); From 4636648258e29a89c37c93cbd91c1d9d0b0e2518 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 10 Aug 2015 19:04:00 +0300 Subject: [PATCH 42/99] vcs: codereview --- .../history/integration/ui/FileHistoryDialogTest.java | 4 ++-- .../history/integration/ui/LocalHistoryUITestCase.java | 2 +- .../integration/ui/SelectionHistoryDialogTest.java | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/platform/platform-tests/testSrc/com/intellij/history/integration/ui/FileHistoryDialogTest.java b/platform/platform-tests/testSrc/com/intellij/history/integration/ui/FileHistoryDialogTest.java index 8a138b961877..19680575a3b6 100644 --- a/platform/platform-tests/testSrc/com/intellij/history/integration/ui/FileHistoryDialogTest.java +++ b/platform/platform-tests/testSrc/com/intellij/history/integration/ui/FileHistoryDialogTest.java @@ -110,8 +110,8 @@ public class FileHistoryDialogTest extends LocalHistoryUITestCase { DiffContent left = getLeftDiffContent(m); DiffContent right = getRightDiffContent(m); - assertEquals(leftContent, left); - assertEquals(rightContent, right); + assertContent(leftContent, left); + assertContent(rightContent, right); } private DiffContent getLeftDiffContent(FileHistoryDialogModel m) { diff --git a/platform/platform-tests/testSrc/com/intellij/history/integration/ui/LocalHistoryUITestCase.java b/platform/platform-tests/testSrc/com/intellij/history/integration/ui/LocalHistoryUITestCase.java index 36dcb951c1b0..3de6a99e6dbd 100644 --- a/platform/platform-tests/testSrc/com/intellij/history/integration/ui/LocalHistoryUITestCase.java +++ b/platform/platform-tests/testSrc/com/intellij/history/integration/ui/LocalHistoryUITestCase.java @@ -23,7 +23,7 @@ import com.intellij.testFramework.SkipInHeadlessEnvironment; @SkipInHeadlessEnvironment public abstract class LocalHistoryUITestCase extends IntegrationTestCase { - protected void assertEquals(String expected, DiffContent actual) { + protected void assertContent(String expected, DiffContent actual) { actual.onAssigned(true); try { assertEquals(expected, ((DocumentContent)actual).getDocument().getText()); diff --git a/platform/platform-tests/testSrc/com/intellij/history/integration/ui/SelectionHistoryDialogTest.java b/platform/platform-tests/testSrc/com/intellij/history/integration/ui/SelectionHistoryDialogTest.java index 008a9bb166a9..b97af0ef8787 100644 --- a/platform/platform-tests/testSrc/com/intellij/history/integration/ui/SelectionHistoryDialogTest.java +++ b/platform/platform-tests/testSrc/com/intellij/history/integration/ui/SelectionHistoryDialogTest.java @@ -90,8 +90,8 @@ public class SelectionHistoryDialogTest extends LocalHistoryUITestCase { DiffContent left = dm.getLeftDiffContent(new NullRevisionsProgress()); DiffContent right = dm.getRightDiffContent(new NullRevisionsProgress()); - assertEquals("b", left); - assertEquals("bc", right); + assertContent("b", left); + assertContent("bc", right); } public void testDiffContentsAndTitleForCurrentRevision() throws IOException { @@ -101,7 +101,7 @@ public class SelectionHistoryDialogTest extends LocalHistoryUITestCase { DiffContent right = dm.getRightDiffContent(new NullRevisionsProgress()); - assertEquals("bcd", right); + assertContent("bcd", right); assertTrue(right instanceof DocumentFragmentContent); } @@ -114,8 +114,8 @@ public class SelectionHistoryDialogTest extends LocalHistoryUITestCase { initModelOnSecondLineAndSelectRevisions(3, 3); - assertEquals("b", dm.getLeftDiffContent(new NullRevisionsProgress())); - assertEquals("bcd", dm.getRightDiffContent(new NullRevisionsProgress())); + assertContent("b", dm.getLeftDiffContent(new NullRevisionsProgress())); + assertContent("bcd", dm.getRightDiffContent(new NullRevisionsProgress())); } public void testRevert() throws IOException { From 87ef5021e664fcbb44150812065bf9a0ea225e56 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 10 Aug 2015 19:07:13 +0300 Subject: [PATCH 43/99] do not use fake last lesson --- .../jetbrains/edu/learning/navigation/StudyNavigator.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/navigation/StudyNavigator.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/navigation/StudyNavigator.java index 1476fd0ba372..4121c84445f1 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/navigation/StudyNavigator.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/navigation/StudyNavigator.java @@ -3,6 +3,7 @@ package com.jetbrains.edu.learning.navigation; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.LogicalPosition; import com.intellij.openapi.project.Project; +import com.jetbrains.edu.EduNames; import com.jetbrains.edu.courseFormat.AnswerPlaceholder; import com.jetbrains.edu.courseFormat.Lesson; import com.jetbrains.edu.courseFormat.Task; @@ -52,7 +53,10 @@ public class StudyNavigator { if (nextLessonIndex >= lessons.size()) { return null; } - return lessons.get(nextLessonIndex); + final Lesson nextLesson = lessons.get(nextLessonIndex); + if (EduNames.PYCHARM_ADDITIONAL.equals(nextLesson.getName())) + return null; + return nextLesson; } public static Lesson previousLesson(@NotNull final Lesson lesson) { From c480f36be62a2830be063c0d82ded82e2ec52623 Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Mon, 10 Aug 2015 18:54:03 +0300 Subject: [PATCH 44/99] Cleanup --- .../psi/codeStyle/LanguageCodeStyleSettingsProvider.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java b/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java index 95f2f3bec0eb..0942308dec2b 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java @@ -17,20 +17,16 @@ package com.intellij.psi.codeStyle; import com.intellij.application.options.IndentOptionsEditor; import com.intellij.lang.Language; -import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiFile; -import com.intellij.util.ArrayUtil; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; -import java.util.List; import java.util.Set; /** @@ -189,6 +185,7 @@ public abstract class LanguageCodeStyleSettingsProvider { return null; } + @SuppressWarnings("unused") public static DisplayPriority getDisplayPriority(Language language) { LanguageCodeStyleSettingsProvider langProvider = forLanguage(language); if (langProvider == null) return DisplayPriority.LANGUAGE_SETTINGS; From 0c776d4202c002222049818dff66cd447c295e10 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 10 Aug 2015 18:32:01 +0200 Subject: [PATCH 45/99] IDEA-142768 Failed to report IDE errors with internal error reporting system --- .../src/com/intellij/errorreport/itn/ITNProxy.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java b/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java index eefe2b90ee21..8a93072e2bbe 100644 --- a/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java +++ b/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java @@ -63,8 +63,10 @@ import java.util.Set; * @since Aug 4, 2003 */ public class ITNProxy { - private static final String NEW_THREAD_VIEW_URL = "https://ea.jetbrains.com/browser/ea_reports/"; - private static final String NEW_THREAD_POST_URL = "https://ea-report.jetbrains.com/trackerRpc/idea/createScr"; + private static final String NEW_THREAD_VIEW_URL_SECURE = "https://ea.jetbrains.com/browser/ea_reports/"; + private static final String NEW_THREAD_VIEW_URL = "http://ea.jetbrains.com/browser/ea_reports/"; + private static final String NEW_THREAD_POST_URL_SECURE = "https://ea-report.jetbrains.com/trackerRpc/idea/createScr"; + private static final String NEW_THREAD_POST_URL = "http://ea-report.jetbrains.com/trackerRpc/idea/createScr"; private static final String ENCODING = "UTF8"; public static void sendError(Project project, @@ -99,7 +101,7 @@ public class ITNProxy { } public static String getBrowseUrl(int threadId) { - return NEW_THREAD_VIEW_URL + threadId; + return (UpdateSettings.getInstance().canUseSecureConnection() ? NEW_THREAD_VIEW_URL_SECURE : NEW_THREAD_VIEW_URL) + threadId; } private static SSLContext ourSslContext; @@ -110,7 +112,8 @@ public class ITNProxy { } Map params = createParameters(login, password, error); - HttpURLConnection connection = post(new URL(NEW_THREAD_POST_URL), join(params)); + String newThreadPostUrl = UpdateSettings.getInstance().canUseSecureConnection() ? NEW_THREAD_POST_URL_SECURE : NEW_THREAD_POST_URL; + HttpURLConnection connection = post(new URL(newThreadPostUrl), join(params)); int responseCode = connection.getResponseCode(); if (responseCode != HttpURLConnection.HTTP_OK) { throw new InternalEAPException(DiagnosticBundle.message("error.http.result.code", responseCode)); From 631a2e682e8e4ca200d9dda0eeba3fd516e79e97 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 10 Aug 2015 18:41:31 +0200 Subject: [PATCH 46/99] check sni availability before posting to our https service --- .../src/com/intellij/errorreport/itn/ITNProxy.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java b/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java index 8a93072e2bbe..d86caed913a5 100644 --- a/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java +++ b/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java @@ -63,8 +63,7 @@ import java.util.Set; * @since Aug 4, 2003 */ public class ITNProxy { - private static final String NEW_THREAD_VIEW_URL_SECURE = "https://ea.jetbrains.com/browser/ea_reports/"; - private static final String NEW_THREAD_VIEW_URL = "http://ea.jetbrains.com/browser/ea_reports/"; + private static final String NEW_THREAD_VIEW_URL = "https://ea.jetbrains.com/browser/ea_reports/"; private static final String NEW_THREAD_POST_URL_SECURE = "https://ea-report.jetbrains.com/trackerRpc/idea/createScr"; private static final String NEW_THREAD_POST_URL = "http://ea-report.jetbrains.com/trackerRpc/idea/createScr"; private static final String ENCODING = "UTF8"; @@ -101,7 +100,7 @@ public class ITNProxy { } public static String getBrowseUrl(int threadId) { - return (UpdateSettings.getInstance().canUseSecureConnection() ? NEW_THREAD_VIEW_URL_SECURE : NEW_THREAD_VIEW_URL) + threadId; + return NEW_THREAD_VIEW_URL + threadId; } private static SSLContext ourSslContext; @@ -112,7 +111,7 @@ public class ITNProxy { } Map params = createParameters(login, password, error); - String newThreadPostUrl = UpdateSettings.getInstance().canUseSecureConnection() ? NEW_THREAD_POST_URL_SECURE : NEW_THREAD_POST_URL; + String newThreadPostUrl = NetUtils.isSniEnabled() ? NEW_THREAD_POST_URL_SECURE : NEW_THREAD_POST_URL; HttpURLConnection connection = post(new URL(newThreadPostUrl), join(params)); int responseCode = connection.getResponseCode(); if (responseCode != HttpURLConnection.HTTP_OK) { From fe8c5e10a3c5885a1ca6428a8946734e82189b73 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 10 Aug 2015 17:42:01 +0200 Subject: [PATCH 47/99] IDEA-143496 Creating file with "Create Directory" dialog fails --- .../ide/actions/CreateDirectoryOrPackageHandler.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageHandler.java b/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageHandler.java index ec89d0930e1b..ff616e497f5c 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageHandler.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageHandler.java @@ -207,15 +207,13 @@ public class CreateDirectoryOrPackageHandler implements InputValidatorEx { final Runnable run = new Runnable() { @Override public void run() { - LocalHistoryAction action = LocalHistoryAction.NULL; + String dirPath = myDirectory.getVirtualFile().getPresentableUrl(); + String actionName = IdeBundle.message("progress.creating.directory", dirPath, File.separator, subDirName); + LocalHistoryAction action = LocalHistory.getInstance().startAction(actionName); try { - String actionName; - String dirPath = myDirectory.getVirtualFile().getPresentableUrl(); - actionName = IdeBundle.message("progress.creating.directory", dirPath, File.separator, subDirName); - action = LocalHistory.getInstance().startAction(actionName); - if (createFile) { - myCreatedElement = myDirectory.createFile(subDirName); + CreateFileAction.MkDirs mkdirs = new CreateFileAction.MkDirs(subDirName, myDirectory); + myCreatedElement = mkdirs.directory.createFile(mkdirs.newName); } else { createDirectories(subDirName); } From 2ee2baaff800e041e4e23aa1505f4c66f8ac17c7 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 10 Aug 2015 18:15:47 +0200 Subject: [PATCH 48/99] bring back right arrows for Import Class sub-popups --- .../daemon/impl/actions/AddImportAction.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/actions/AddImportAction.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/actions/AddImportAction.java index f01b5b7d08bd..b9bb43c0abcc 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/actions/AddImportAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/actions/AddImportAction.java @@ -42,12 +42,14 @@ import com.intellij.psi.PsiReference; import com.intellij.psi.statistics.JavaStatisticsManager; import com.intellij.psi.statistics.StatisticsManager; import com.intellij.ui.popup.list.ListPopupImpl; +import com.intellij.ui.popup.list.PopupListElementRenderer; import com.intellij.util.IncorrectOperationException; import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import java.awt.*; import java.util.ArrayList; import java.util.List; @@ -161,7 +163,18 @@ public class AddImportAction implements QuestionAction { ListPopupImpl popup = new ListPopupImpl(step) { @Override protected ListCellRenderer getListElementRenderer() { - return new DefaultPsiElementCellRenderer(); + final PopupListElementRenderer baseRenderer = (PopupListElementRenderer)super.getListElementRenderer(); + final DefaultPsiElementCellRenderer psiRenderer = new DefaultPsiElementCellRenderer(); + return new ListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + JPanel panel = new JPanel(new BorderLayout()); + baseRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + panel.add(baseRenderer.getNextStepLabel(), BorderLayout.EAST); + panel.add(psiRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus)); + return panel; + } + }; } }; popup.showInBestPositionFor(myEditor); From 2d7619d1061d17d275df5a458fc933b526719fa1 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 10 Aug 2015 18:45:24 +0200 Subject: [PATCH 49/99] IDEA-143735 FileChooser.chooseFiles doesn't call callback anymore then dialog is shown from another dialog --- .../src/com/intellij/ui/mac/MacFileChooserDialogImpl.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/mac/MacFileChooserDialogImpl.java b/platform/platform-impl/src/com/intellij/ui/mac/MacFileChooserDialogImpl.java index 623fe0e2ba1e..ba54fd98bab4 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/MacFileChooserDialogImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/MacFileChooserDialogImpl.java @@ -17,6 +17,7 @@ package com.intellij.ui.mac; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationNamesInfo; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; @@ -62,6 +63,7 @@ public class MacFileChooserDialogImpl implements PathChooserDialog { private final FileChooserDescriptor myChooserDescriptor; private final Project myProject; + private ModalityState myModalityState; private Consumer> myCallback; private static final Callback SHOULD_ENABLE_CALLBACK = new Callback() { @@ -160,14 +162,14 @@ public class MacFileChooserDialogImpl implements PathChooserDialog { } }); } - }); + }, impl.myModalityState); } else if (impl.myCallback instanceof FileChooser.FileChooserConsumer) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { ((FileChooser.FileChooserConsumer)impl.myCallback).cancelled(); } - }); + }, impl.myModalityState); } } finally { @@ -324,6 +326,7 @@ public class MacFileChooserDialogImpl implements PathChooserDialog { ExtensionsInitializer.initialize(); myCallback = callback; + myModalityState = ModalityState.current(); final VirtualFile lastOpenedFile = FileChooserUtil.getLastOpenedFile(myProject); final VirtualFile selectFile = FileChooserUtil.getFileToSelect(myChooserDescriptor, myProject, toSelect, lastOpenedFile); From 9bceeebf3cca4c7bbbe21fc6f043c6a1f09751ee Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 10 Aug 2015 18:48:41 +0200 Subject: [PATCH 50/99] AbstractVcsTestCase.refreshVfs: process only the current project --- .../com/intellij/testFramework/vcs/AbstractVcsTestCase.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/vcs-impl/testSrc/com/intellij/testFramework/vcs/AbstractVcsTestCase.java b/platform/vcs-impl/testSrc/com/intellij/testFramework/vcs/AbstractVcsTestCase.java index c4468ae8cb14..d459e971b910 100644 --- a/platform/vcs-impl/testSrc/com/intellij/testFramework/vcs/AbstractVcsTestCase.java +++ b/platform/vcs-impl/testSrc/com/intellij/testFramework/vcs/AbstractVcsTestCase.java @@ -77,11 +77,11 @@ public abstract class AbstractVcsTestCase { ChangeListManagerImpl.getInstanceImpl(myProject).waitUntilRefreshed(); } - protected static void refreshVfs() { + protected void refreshVfs() { UsefulTestCase.edt(new Runnable() { @Override public void run() { - LocalFileSystem.getInstance().refresh(false); + myWorkingCopyDir.refresh(false, true); } }); } From 94ccfed45015391024b44aaa51a21a451689c051 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 10 Aug 2015 19:49:25 +0300 Subject: [PATCH 51/99] log error in creating user file --- python/educational/src/com/jetbrains/edu/EduUtils.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/educational/src/com/jetbrains/edu/EduUtils.java b/python/educational/src/com/jetbrains/edu/EduUtils.java index 7808ad2d21f9..c4b305d11d47 100644 --- a/python/educational/src/com/jetbrains/edu/EduUtils.java +++ b/python/educational/src/com/jetbrains/edu/EduUtils.java @@ -200,6 +200,10 @@ public class EduUtils { taskFile.sortAnswerPlaceholders(); for (int i = taskFile.getAnswerPlaceholders().size() - 1; i >= 0; i--) { final AnswerPlaceholder answerPlaceholder = taskFile.getAnswerPlaceholders().get(i); + if (answerPlaceholder.getRealStartOffset(document) > document.getTextLength() || answerPlaceholder.getRealStartOffset(document) + answerPlaceholder.getPossibleAnswerLength() > document.getTextLength()) { + LOG.error("Wrong startOffset: " + answerPlaceholder.getRealStartOffset(document) + "; document: " + file.getPath()); + return; + } replaceAnswerPlaceholder(project, document, answerPlaceholder); } CommandProcessor.getInstance().executeCommand(project, new Runnable() { From a86ea20208cdc0933ed8b0e1d69a5d837d6f6e39 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 10 Aug 2015 19:50:29 +0300 Subject: [PATCH 52/99] fixed tooltip for refresh courses action --- .../src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.form | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.form b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.form index 8d60f3ad7ce4..c13bc229b973 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.form +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.form @@ -93,7 +93,7 @@ - + From 7fe8772304eba3ba6ed52c90feeae6a33c6f3307 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 10 Aug 2015 20:04:56 +0300 Subject: [PATCH 53/99] fixed EDU-193 New Task Window dialog is not resizable --- .../edu/coursecreator/ui/CCCreateAnswerPlaceholderPanel.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateAnswerPlaceholderPanel.java b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateAnswerPlaceholderPanel.java index 1b0b2804290d..cc55b58ec101 100644 --- a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateAnswerPlaceholderPanel.java +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateAnswerPlaceholderPanel.java @@ -16,6 +16,8 @@ public class CCCreateAnswerPlaceholderPanel extends JPanel { super(new BorderLayout()); add(myPanel, BorderLayout.CENTER); enableHint(false); + myHintText.setLineWrap(true); + myHintText.setWrapStyleWord(true); myCreateHintCheckBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { From de098014f17efed384778aa46ac9fbd6f5d5723c Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 10 Aug 2015 20:13:50 +0300 Subject: [PATCH 54/99] fixed EDU-388 Throwable at com.intellij.openapi.project.DumbServiceImpl.scheduleCacheUpdate(DumbServiceImpl.java:159) --- .../StudyProjectGenerator.java | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java index 7bd9054b647b..18b01f4c7c01 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java @@ -8,6 +8,8 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.DumbModePermission; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.io.FileUtil; @@ -66,17 +68,21 @@ public class StudyProjectGenerator { new Runnable() { @Override public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { + DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() { @Override public void run() { - course.initCourse(false); - final File courseDirectory = new File(ourCoursesDir, course.getName()); - StudyGenerator.createCourse(course, baseDir, courseDirectory, project); - course.setCourseDirectory(new File(ourCoursesDir, mySelectedCourseInfo.getName()).getAbsolutePath()); - VirtualFileManager.getInstance().refreshWithoutFileWatcher(true); - StudyProjectComponent.getInstance(project).registerStudyToolwindow(course); - openFirstTask(course, project); - + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + course.initCourse(false); + final File courseDirectory = new File(ourCoursesDir, course.getName()); + StudyGenerator.createCourse(course, baseDir, courseDirectory, project); + course.setCourseDirectory(new File(ourCoursesDir, mySelectedCourseInfo.getName()).getAbsolutePath()); + VirtualFileManager.getInstance().refreshWithoutFileWatcher(true); + StudyProjectComponent.getInstance(project).registerStudyToolwindow(course); + openFirstTask(course, project); + } + }); } }); } From edf430a9891e280a56462287eae5aa2ac1692838 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 10 Aug 2015 19:44:59 +0200 Subject: [PATCH 55/99] don't run pushers on changes in .idea (EA-71691 - Throwable: DumbServiceImpl.a) --- .../roots/impl/PushedFilePropertiesUpdaterImpl.java | 7 ++----- .../openapi/options/newEditor/SettingsDialog.java | 9 +-------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java index 4f27cb072c8d..804bf10d41ea 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java @@ -29,10 +29,7 @@ import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.util.ProgressWrapper; -import com.intellij.openapi.project.DumbModeTask; -import com.intellij.openapi.project.DumbService; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.*; import com.intellij.openapi.roots.*; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Computable; @@ -114,7 +111,7 @@ public class PushedFilePropertiesUpdaterImpl extends PushedFilePropertiesUpdater // avoid dumb mode for just one file doPushRecursively(file, pushers, ProjectRootManager.getInstance(myProject).getFileIndex()); } - else { + else if (!ProjectCoreUtil.isProjectOrWorkspaceFile(file)) { ContainerUtil.addIfNotNull(delayedTasks, createRecursivePushTask(file, pushers)); } } else if (event instanceof VFileMoveEvent) { diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsDialog.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsDialog.java index 17264b5cfc42..915cd2d85031 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsDialog.java @@ -21,8 +21,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurableGroup; -import com.intellij.openapi.project.DumbModePermission; -import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import org.jetbrains.annotations.NonNls; @@ -143,12 +141,7 @@ public class SettingsDialog extends DialogWrapper implements DataProvider { @Override public void doOKAction() { if (myEditor.apply()) { - DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().saveAll(); - } - }); + ApplicationManager.getApplication().saveAll(); super.doOKAction(); } } From 8ab0b5c4d1d1163858feda257443a497dbbb7d1f Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 10 Aug 2015 19:48:28 +0200 Subject: [PATCH 56/99] don't fold our testFramework calls in console because it contains useful information quite often (IDEA-143693) --- plugins/devkit/resources/META-INF/plugin.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/devkit/resources/META-INF/plugin.xml b/plugins/devkit/resources/META-INF/plugin.xml index 4692132964e0..131ebeddc940 100644 --- a/plugins/devkit/resources/META-INF/plugin.xml +++ b/plugins/devkit/resources/META-INF/plugin.xml @@ -136,7 +136,6 @@ - From 494edf8e177eb6db5a67e786290a7755f2a30621 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Mon, 10 Aug 2015 21:04:59 +0200 Subject: [PATCH 57/99] Fix terminal for Windows 10 (IDEA-143300). --- .idea/libraries/pty4j.xml | 4 ++-- lib/libpty/win/win10_x86/libwinpty.dll | Bin 0 -> 192512 bytes lib/libpty/win/win10_x86/winpty-agent.exe | Bin 0 -> 185856 bytes lib/libpty/win/win10_x86_64/libwinpty.dll | Bin 0 -> 196096 bytes lib/libpty/win/win10_x86_64/winpty-agent.exe | Bin 0 -> 185344 bytes lib/pty4j-0.4.17.jar | Bin 51090 -> 0 bytes lib/pty4j-0.4.18.jar | Bin 0 -> 48832 bytes ...4j-0.4.17-src.jar => pty4j-0.4.18-src.jar} | Bin 31922 -> 31592 bytes 8 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 lib/libpty/win/win10_x86/libwinpty.dll create mode 100644 lib/libpty/win/win10_x86/winpty-agent.exe create mode 100644 lib/libpty/win/win10_x86_64/libwinpty.dll create mode 100644 lib/libpty/win/win10_x86_64/winpty-agent.exe delete mode 100644 lib/pty4j-0.4.17.jar create mode 100644 lib/pty4j-0.4.18.jar rename lib/src/{pty4j-0.4.17-src.jar => pty4j-0.4.18-src.jar} (58%) diff --git a/.idea/libraries/pty4j.xml b/.idea/libraries/pty4j.xml index 55f81956ee96..faec40e44f2e 100644 --- a/.idea/libraries/pty4j.xml +++ b/.idea/libraries/pty4j.xml @@ -1,11 +1,11 @@ - + - + diff --git a/lib/libpty/win/win10_x86/libwinpty.dll b/lib/libpty/win/win10_x86/libwinpty.dll new file mode 100644 index 0000000000000000000000000000000000000000..6c78cab2c98a85f6b07041160e48cca8676f8544 GIT binary patch literal 192512 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 literal 0 HcmV?d00001 diff --git a/lib/libpty/win/win10_x86/winpty-agent.exe b/lib/libpty/win/win10_x86/winpty-agent.exe new file mode 100644 index 0000000000000000000000000000000000000000..ece0a21d8a5e5c5b520db34fc306425749c09bf6 GIT binary patch literal 185856 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

7sed`H@t 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≫kgrX zUV2zQ#9m?B(SCitowNJFz8~f+Dh{l@8RL-h(8pduudK|i&0b&gl^LueUs*K_ zz1(=%u+nUw)ruh4S7>QI9t|NW>{5#?l9CNn<9~z&+v&GsRWlDbnQXR#r7)Orki|K1 zWpZ&2gNAs}du4mLbpUo3IZd4CjFiNYWWmzB5X>2qyF$a0Y9D1K91RTDAb{gt0BL@?D(?M=8 zlQNp=E}6OL3rm~4%{eT==&2XNQ1$LpE?3z-ss^xR2i$uD#h+CP4zRaXMTcI@oOw~v zide8sPfO#YmuLE$J_x$o-B5D<`3+?y!EgF(KXmENJNjFPy4ojaoX5-etVP4tj%bQs zWgT+bj%M2%QH|-|>AEJ9LH4;f0+0iMjI094OaZv(>^=y9&ow#gV0P23kja8W8_G-2 z85_MSL(A|uk4}a@u#eM4z??3=Ji-te=D<=kA7Sh}(^-o8($Ag+S<2Z!$)Z9HkmU?D zU^DknMGau12-pK4n}D#md85_--#&BqtupDY z=LC3*6r~!cl(uqTsbrM)2wAy!r z+xxrX7s^pfE^R*hp3ys%%S}-RnR-={JBuHkdt=lMxyU*53)%Wnf+u&rzf2^s>=~(> zlF8$mWcU`-Xy%G;X4&6{pu?Q!nM{r{(Lh&~9ZPKUqiD^0g_-hfKcN$y>ZqCW%<5?{ zH^!uLjLuwiMTm*s0vax}bLKW_x4WaRBP*lCB~g0sKr=0DHA{;GX}vw2tl>jvD$DG4 zP_~|E@6Y`0K)KRPKT0$YbF^Qw5ZFL;VTSX#z$+no1%5x^GU3Uq2URzF?dcd%xMR{G znKN@;m`&Sc*{}I34tQ(27$H{Gc4v-cG;^EiYF4XiyHiD8)iXDlhor_=>mpC5iFB#C6@H(7%)YfEHL+$KcVY!(VwK3m+HC2GmG8t6uwi1k{zWEMe2&~N z;>lT+uVz(A&#V&0l(9(Ra8fVvx!ajoC7=>!(+=m-i+g6#88VAn87K`X#0GVWH?yb6 z<-B1g&J3A2izd)L;b-dgtV!zn{$>yT?8oC$4bv;;Ftf+9W9mMbzGAjH?^jC04zglS zkcJgHXMq;&O|dp=Bbe0jaX;{twpxkpYFWsvku?-O6}41Hd2nF7i+8HEfu2l3iQk`K z8rIJhUqbtR7?@&oA8ZRB{(MnI#pcD|XoP;Jo-lY0IMh7(SaJ=ea?!09Z49iPq73IP zwz1vrzZSZK}v=y9^cp zsJ7%lEs@%3(1(ot6`A8Yq2nbst;lWM68gkcKR6*i;9Ng^GHIC}A9(gP&WE6HRxk+enx3) zo%d_m?Wf+s#y)8p?qLVgooI818R$X{w5l8d^TpN-RZAB=N6RWjY7OU75+~IB6;%(Vj zjJi+Bg@2kR-W%u24U5^pC}ONou zbOoXdGM&#ES7f_0y)B*c4Nd9_A~iviHWjy3mhs@M&sQn&B!%{RkRj7b$-U6uVsVFF z5i)cJA3?;Up8^#d=Y5E-YfV!M%-k#5ck`St?v}Q4*K);co!Xr;Iqpy*KE9@X_2*X% z-;AaQQJMg*-UJ8kMuLhN8v~Vg)3!Pg!Hi~Q`~+uBDl?~zxg{4;Mah!;dcM%m z)N_EAH%AtQd;L+=RD~1ALWNEi--bbix2E!l@jC8up4=gI@-{_!QVS@;0DQqPK?WV>%+|5a&K|%wRsbkw38tk#r;1)=p&#|(qu%*9 zW>E>L3&1%4x?Osyp4%y_J!9dhfc;5e&OtcYFUn`l1&0uCxYQE`ci%~- zk$y;NBeDAtOx@LXysGVsY%Bcsh|BDOj!3lD*35Z(scL2}wG@#rp2OzMGL`9O~4iGsiUP&OQI;~c(ZX$;`4-`n^d z0*Qj%i(D@HY$}}lYzosjwtE{ZND+{xMlxE#t9-+e9CkI*kqOOqsp<@Mtni|twXUG( z3?5qDTs`_mO+;=+tkeq6B1tMYBaUg#EzaQ%X;E-2YDEIYo2uOHBC+7T_Yv|}NLhc% z#^7AWl!40bZTy3z!CP>urAahw8VY@%odmc?05~9H$3Rh4*va4`qjW_r)~_z5yJ0IH zqev`lDzfV(3L5T^v#2BeQ6*XM9jBjJql=^mN8Lyd+5DyI+>Q#^`De!V zGa=c)q6JwrCDB1U-m{v01FM;p?^zwbEO{Aov5s;o0FBmdZ?=^v3Yz>D5v>EIU%&G z*R8f@7&+Rx@F#{~mS#tCAe-cStf%;jTV>m+MFK0J7`X>xs}^=pv|$T`3@$YZK!;tZ zD=s5kO(hvzfK)bt;sb%1SUZ&GwtM7-lUl9MquRP^-n%#{Bw`~-fN2IX=NFPK8c&o0 z{E9Zg{n|pK!kaT?Ohbd}A}7i@LPY*$zmdH;0zHD@vLnZ&dC&ZV=6&xwYUX}L^R8LY z(>!EAzOs4WCarJtE|%t1lAwm^W`R&sNY>+A#LQA-^tImY8OSpU!aLFu)Q9sYx@0A| z?C2x({XCFB&+3(xJGYp1ha+ot3LT6Qir5z}*8{~HOLy-&EXK^ufarzX5>fVXNKVPy4fIgu`GO3hYJNBU7;Zq?#@?ck8x-ag5 zzeHum*+@<%V^B`OA?cYVsZFyAZ=^7GI|p*m|Mi4oGu7c-&)j=azsX^tO>F>`!5pjM z;#0hhrvc$CRhgVh>zypT;UX;m5?>5zk|&j@Y>jduno}ZY{Rc-kvxkaO0i5*L(|_iC z@vFu9d@)cJDF>d|LsITEh1Upm-?le6fwF3d8VIJM)Y^FBqop-P^GL@C&60ecTiD5NpSuZMSw1e|yoI~D3!N2pY$~(m`7cnWg zlA5#Li`Ox3B6!zx)@zvM@q8f|DWKm6)Wa@kJWihaT$#xBuq$!f(n^Wr3u%JrA!a`1 zA-L@^nup^<2*40AxrhkR4CfJm#5y|?-3aw1&y9B8?}~*5F%aI85h%~|vA)^K)fr2* zzmPS`MM)0z>~zuva?#_!G(;Y?c`@A*%sd_TLZzclLT)56&HMO*A&!d%C!bLBm(h6C zeBGxW*7Rn5pWG^GZ6(TKCm~XFS8`?D=62IrXijtnqUJR(Cv9j>`GNx#^fpSYBiFT;ScBw`l40zE9W9 zl9e1{AxEqttK`!)7nZ@oO9PU{f`+g=g!-YbXmI?wDy(SAi}s|ic+m#PxiDG5_#?b% z|3T4$m>5ND*xWc}GRVK(p(0YhCe=ELQ1Apv#5DEEaYx?PPsQgrcl6ZnF!&-_ziJx_ z{q8C_Y(uBk6k`Nhzp=ZMZ|q;IqS~?enCjv-Zm(H|XgnkBdiDOELs~Gq3Lc@irNk`K zhSi9vu5$;GEl&Fy6+EDxqL03E+xE!Nrm$yV&m}LF8P2B{9*0+cZQV zlKtZ;B8O9;G9kTDr%z9%->K67PSNW7Svq}6Dt)F(e<7Lflk`aTbYcaw6j4@HvNmgy zKqE9ziTZRN0U(D9Yb*q282%0bCpresR4V9V`{@}8p2X|v->#L~z6*d-m=)V2y=LdV zLv#Qu5Hkbi7rlu;cwM4kqbeN-8Bz^Vb*P}W(hV#N47Z~m7-<2#KXOKSvWl3 z3I^}Z%W^eZBn&SL4~**W{ie^Jn^j}SAfP~-L)8v!X{8D0`Pb;2nFnYeaviZ3$bZQ# z$!B>^Y=<-F{quY)pGsbuZ>6#~-^y=<$gkGm@%dKZ8!<6D*$v8_Y@=x=xfQQ&} zm2weim~sqpZn%j28b>$KQ)<@3UV%Or4jpprb#6SSI92+-CCPDOhH$C~yKSuyvXlYj z*m@3r>@gzEBA3*ZZdSXhFi?>2@tbW$294f*~Gl2W9I9axx_rLV{X(j^~7w|F;}V> zTlGmr-cveqoQ_maR~30{bmSR2a;5ZMMc%_YGG8LqI!fn#k)bY}lF|{V)V^1Wsz}80 zYYzDA&zSRvp{K~*Csc?B{w?HleD+%ykyv*+^3^k-1z1l(u5~FUPtjhw?l#fhBAnHs z97VZ^tpI2Pe`4lm7@JkK-K|oESz#e(fOuDg%zq)JcpER2dozF^t84^SiITYO&J_T% zp5o5|YdxN1<7*vVsz#1rq9WYh9 zG{6{Zog5;P0C5A5+vU6tZOmGCk|gp`ZWqOrP{ezwBA!+Ng#gqQaLPA04QYE09^W2E7qg{t_MIxuHzD;fq2)3J6$(&d@A|mWb##M z$-`60*Cvy%PD?%(NhDOouF*wI0Vpl`b&@4Pfm~~?ldDKta;r(U)_p6P`INNeU#60U zM5^-mW?J%HspM;t$=^y#o=LJE+*A!_)At_$qFX*m0jQx(R&g!>AEp3KR{&~glK}O- zCWuP`qz~`i4O9h~cq)@ucweyA$p9v+p}0qY`Ev?pEik!V);bx*s_5Nn(dl9A8Rz>1 zW)rq*nZ?1+WEO9C8qQX;*{N6Vj@YN4OLz*Tq4?kxIZ3bG=@YGy>*cqBT2HP&ds*{6wqmF=)wROPmdRjlu-)rVcIrT;m* zSfW+B%H4@gEHRChW)};6(fNUhl^@3f;$~;pD8Zd~ACP{sJynrGsX&0x6&xr`S|Fbw zceG@1D#58e!5IW+SRGlTS=w5R%IXl+0pxnOBMuuDmR`v3-Yyk{yG>NTfe!AK!ku%+ zNJUhlQ-r@d^0a(c9r=yGS4aLTP`o8^U#iqhC1P~>PW&m;-&l%JdquFWXP+1V7JUx; z0c;an)z)^ohnP(|X047viZXAVj`@v_nM%xl9dnc1z z8MKt}U$%mGZx&eD3cQW$sif=xPYH-Q6AzMR!w4Yg0a+hs6i*y5uyMcVh-_fIzyJUk z*gq41>ge~?dnjk>{8U;JcfY|~iKT2B=XM36mrT`}M6dcZweUA62+37J%t%6fl7jd- z5G;E*54StN`-1$G%DL@M(-~^%#|FqDw9k?sq?UY@`$bvu@oQwgBh~Wd_1?|pt^5>u zcVUa>fjxUH0gO(vII=I$UKU#R_qCTrmOV#%XZRyyM=Ld7{>V21c2hSE=vi3Nz6(o5 zID1CRG>WQ4)`7n|@|1j69r?9_kNo9J3u_JwYkvB|lJl54gB@Ud?^#<_9%q5d{PKL~ zHti{NW@%56bG`PAajw>$5~oUeave)YR61qa6L7w!J+;o6+B4M|u01oHq1rRs$<>}R zCsTXoI!6@ly1d>wpgih$<-D!^a;kE=w11`epVfX@WKOI0uNME~+W(07AJP6b;(t*4 z*NT6o_P2_^QTsc^U$6Z;#eb{zOP@M3w7*;Y*J{7uGAE$@(&5f{?LRF367820t}|Nu zJ>oCa{(SKd)c!*8yR^SZ{GVdNHDKFg#P4W-iTGd9ej!^qJGEbqUCuMwFALCFtNrr+ z;rzSy&ldk`?Vl_D`?SAa{LR|mApS+#-z@&Q+P_l#v$TJP_@`?BYVlWV|0CkB)c!T% zAFKVc+c{&jzg7IFYJaEr^R<7K__MTsr}z(pl4yIE_}|z5Zt-_(za#$Vwf}(lJGK9? z_@C5%rDJZ5_Ip6E&abpTU;L}Izfk=5Xn&FT8?;|plMHIVU~p%)_RAxSGfn#|#b2xa z0rC5^zgGNZ+CNqN=W729@fT_TZ1E4({<-4!Xn(!d`^_44(t ze57s>&Vn1IW{RF(jPL_rJYs#u~W@Ts2Sc}VTUNqvBGlTx*n0sGHV*B%i8rR(6FT#4H5 zob`Y-@}|SwMlPUifAj}C16WX{DS_yv9yvH7Fv70GP3nL?yf!W2i|Cd4{^%75T`8e4 zHYtw&YHPY#ry`=u-UY~oJy~!ok#`azVK$bNIVBV&bN8|D730 zdg^{i{p9@hp5m0~4Q0NdQ_fc9Ri>v)nJqdM@|39&Z>PGwlKOy7EhbKVUaPu5U}>#$ zr%pXL_3hO3Z>Q^2xMNMuGtyHh>eTa7sk75lPuHnmOQk~F=&6-kr%q0#&P`AK8zg;t zf|q_%Zhd-chfeh;QgfQ#(EyjE0AwFY2WZj&m!<$@b4dr7r2(WPrPG$nhNET> zJt`kLlQlq9Du>m5au}%rP>8OZuw3@0^dd4ez~w0b*|5?9x}m($3A_NC9Ap(g5RA0J7Vr1GH#>2`KjUs80IG78B#_l<0-0Widvy*Y6i@)5z5urYAaT|@cfLMVFBiOmQ$w^~icN&lanA@kEH+g-d4M-1~saf9#piKiPfyfXS027U)yN zXFST0a|(AaU(*NRWerfA%3*CEfOQ%mg~6A%_5oO>0a8eOd1oJhg&H7*$Ct0_1Mp1^ z&@*>;_5rv^1EjF|@~%DrLjh2o)J+2IRhT`!CqIGiPkawfclzY8TLbjq^aFhW{-gnV zaQfjs04p_sqVcJ^xHuuC*Wq>z(1X)GeE_b|06jQ8zYoB98lVTK7xn=dr~!I#dQl&M zIIo2CLk~_L(+6NH0IK#SBmmj#v>^Na?{p45IK8Y-4$T^%2d7u|0k~NM^x*VBAAn0V zz_`?$tnCAEh6d=t=~MdvWNCmNoIaxuz*|Ap4?Q@2b{~L^8lVTK&+P;7OAXM2)9d>H zGytG_vVjDJmFP}|;q|0&ZqPaO;PmD`Ib5s(&P?^g%02+YH9!weU)2ZT^ZBZo!&5n| z?gOw-11MCkD*H$ufb{^#*J&twO&^e-0FrAYEO?xO6oJZlQSPL)q9}S>DU9AeZwq|O z8CJ0<$u8bnCki- z!NC)GTpwIlksmy%3iZnb@?rE2eJFZ10L+iS5P;Ep*Wpdi%FAORm7shPb3dW3A~Tei zWZM!0((jPsZOJL7G#Jqh*g2S=DaX`YTe6^?!6AJLYRio8rdpVONwbMy4{)|!N4MFR zd)Tzl+3dYP z+ln4G#X!DbAQf_MH%P0n|Lpn_iU zP(rZZ!O8jkLs>lr$o1Q;u)2(+5tK1c__n*bD?qc8WnTIsez>bbfpBMt11Qk@=A_i&UX9qQxDOM9m94n zdo%k$BC%{^CWi;-Vv19?KJy}T@?~FxNrJABaS^`V5@#7~TLSQU_@Z*cl{jX|< z=ao_o)HS>42pB1s5iFlGG+0?Zb21{WCf8{^d@yB;!v9KyJK5#pr&p)-_PU z<8+1d#s=Mj(5bza~hlYak@!RA^AC0AOF>$pe2=6fX zq%G5kgDl9Y3%_?`UHB-1A&K_*o4`3^C4&ROoBPx#^i9d|q%YOxjeSy^U|CE^(tW=f zDc`*H&Au)8gZjqX^dO(muWe4|p`B6WJHN!Wi0wOjP9Teo}o< z0wZ8ae7wNBKp2RtX=sI1EXA&%40AgFrr^Q#t?@zf4ZYMaQLy%MDQlYOtLddTQjydu z8ITQ`WC@X zw*Ow$_DmA4T#4Q#m|(w}%6 z>j+k9yUijLa^n|p#Guc?+lbmTSG2h>6ISFS8Q!}uCWyROqTt6>g7CbJ=Mf?NpP7-< z0+@em+(dyQO(6N%J79J_)2Y5%Ol7LQN3A45twUc@Q=sWA;C#_QWi=fBvZ<-G^(w7# zx610N1{`Z$CI8pUMk?=JWUzmo1`?@_^*8WOmhPGGunPl6ezf*{37@FL!ISm(`cvj+ zhqFd~9-L>b%aL!R_q(Wwz0DuB`Z*7>hSbE0PjP0^L$ST|pKPhpRN;y<_QJ_R3DvBZ z(UExPyU6;h#g%68b%!(NMP1eZ1zdczkc00T-7Tdu?R|7Cm_jB|8ZTQ9vQWCboJ&AS zX?RyhULcWmkZnEceQRw3`#av2m+LAz)k5~Kl_n9IFE4Y`j!7b-d0Bz@nd&$z4D^-i z*x<9<5(WD%fl`g};$XHCW%0JOd0V!j1%#O|vY&#BJqk^sicE1VZwU=`=Ao;`NJNIO z<=ov7zeHJ-8s|KIpDgEXFjw8eo26i&C99ZHoz4b^L<#I+3<%N9%f|@1%W=9rz=vm! zafN3Vx@3ffVourW9gniXlQdM*^6kCUfo_Dw>i$+nd#LjsylAE#pIsxoVevDmM`f^I z_{Kt4{DAZ40%i7Un{yFwpginSor)6~47kb#y`_~?D8;CwA8fcr(l6gxq4F2>6^|~K(=Qf&-{bw`siW7bZ)UU6rp?g6%_U@?z?iTC_%<+RM!TEGl#ci*zOunV zkN4@ph$Y3dl^A|=KBA*2njn*roAH(IRi$-R?p~Kxac)dGPPY(BpbR2z|6x zRvgw@>}n2|sfwufHl-q9UIx1sYqVzqN?X{XQ>q|4Kcl*ui@9DNl+fiQYe@ui3-ZW| zJy0#I8FJ4qQ+)3HV`|TWE@HTdZ27+&cr=X`b zG$fvVa1%#N&QGw}bU z9V2?TW5(eBs&<_DmF@6w8@&#J&|UUrSy(^YwAR%iyM*YesT12Xb-qzuc4nP_R2#}` z&;j%Wv!{VO`A();p@r;q?t0gFU{NK4;kC7irA)3 ztw7!JvVhn5A#E_bJZ$>cdDMAg$~9QdhUK@7IVP_+;OkjO%pCKdC8xqj&AXU;;I9UY zPpqc{&LP=!Z2ut+m4S%=UF6!>d20G|vmFf7yLA!&erMlskp9y(1FEC`+=$n^p@u`l zp2(Hx?bwdhOsD&L!D68i7#wDc0O!`6C6nh*pD}roIzX;Rb#CAD>sqj(U=Nv3`Dz0) z3V~~NYb!dvjUuQ-J-Qutj?{B{H>%jnWdEeVA>NiL`AISPn?y`LeuKBACV#!&u(r-W zV?B_(DeE(CKLL+V5C}5KC&~NQp`N(VfZ?|kNZOY#QZ-{V0}i{4znVekGxoDA+@glX zhh0j~D>JvnSA zwN57YKKP0jjn0P}!Is2ayS*asO?biQ-;C5XY_Z};lc(%2ZHa7UZ_Lg*rgsxxAUwV> z5u6a7FbtlpjL=!^wI?RF1apz;7`EFz|q4-xmRB8NbDpc_Pp zu=zcgCbt=9Fy3&H%WNp1VYs;Uu0kIg8jhCJFL3^LiGp=%QlH1a>8xHUbFRJyQT+=l zhMywsI2+8XMfFdTrt}uyI*6oxhN$$&@*r~dzf6`#agB6ZE+ef(&e+>Hs03!h*`2o? zo<6wE!f(gJG1K%yQb&n0@7lg;H?#IZ`M%h$;C4R5TO!Izi_Ulp@aq;j7rTy-|*&yjY+(DJiD?H&uh+UT=#M zX;W(RL`O#%iu#b>1*hg9yDFCrS3Fzg;cx~bZ-F#xx|eS0(htzmgxnoMQ9dnqSLpn^ zujfSaWR*IRJV_>yX@hUoMb1IPQLViZs?)G7=sV-EQH_4jfzAT?N*zi%(F}M@c`G(8 z{8K=rRyHzg2BUYcCORoIdim=}PGwq$xV3hQ^zJ6H+u0R9I$%LRkl(lBqA8>V5DqVG zLeZ5&cmUm0%IV3SXk%1eduTqAxyn>-tUVD$;aNgovu3X+`V9c)-%{PU4aP)_`k6D z6U%$MhYvQ^dH3^o`_4LVXcvFm>b!B>m$0!MDx~uH@y#f!&JT`)BVe}3ro=J&(aJy-vcZVXl`S=x_7e7;bOU=cqMmo>Ue)@ z;CPBx=!tz&Z4XswT1$&_9br+`Vzji#hdC)# zEnEh*suo$$|ADF&aGQER0k`SB@_6^8Lg(X3jqvy>CfwbxZmNXY}bbWF@;2wy;U95CPJz3fV!HY_DPxB-iX3?;Nd&*m$!s38Q<2WX z2`rFTHm+R@P$;M3NND)M${88KlblbftU8y#Qs%rXLr}3PcpCZa6Te6s_WOGBV)yn% zsuf)9NcXCAq@6pGyI{1yO>t~qN^ea&o1v%^8OZ(hw-XKja&obU(`1_E63)FVI1-OX zID)J4oh3((C6>)BJoK5m-XO4y{Bi^{q+`XV)55&!!* z2cq*c{L$d(x0fX{S`&%T**+UuVEMErhlenCdsRjIqK{*bX31yM9T?f3$RvxHSX|`D z>-g>GEulh0{M~l;o#-owEN(@immQDzI}@!BSfidtKcL-Zje4edqt*6Vwy$_+)yz$H zb(7 zCi8AJc^}TUUo7sdnYk0=0{1(6-i!{+2mfMEdA{3cf9NZ2pA@OS->I6pv;Hj6i8xZA zs3#&48NQ0vdD&<>(2x-l0>v-hvDar$c}3T2Pj}VKZKwO9j)lb*G|^X8ytr7NPDOux zb@4`QZvIQ@?y9!#Os94nR6M(;ONz)u(Q4kz&zV$h#o0IDRvcbD)bt{qtUK~5URNrP zcz<+0-CB$`dE4KO!c_XxvD;*H9;iY4oxP2YJbO}vxlmo)e#a{`3{9G^u*GI1dw-{?%uz|$+1LyyPQFR#AKQOAID`;T8kCA1-w$9JAw==Sr zM5_OwMs_s2Ns$b!fTfMAfF*~OA(cwWkZ#pOIw?7%Cm(l67ngyy<)bI%)Q+Ef=GlsU7_iY~$Cd0W+?uBwV7i=be?WG2g9smYQRnf4Tm=hz*u`t0m_ z>Se#?=T?6^p<4)f*M}UgPX4hk|)6uw6n zF1=JmQ_>3WnW;U62W&80@frJJ*t1qVYccz#KQpZL3P5Sat(I|`UnmE$M||=3~c$|4`07^ z=>PZldiB^o_<9?U{erJMaQ_EifAuc>-xps$ccI|x+`lK0;(s4}z3@|ouV>->cf{A- z==bQs*SiV*e~hocMUltF*ON&2=kRsIJO3QMF6^aa@z&8tAos3jf8cN(dMk;nVL=Hk zh1?ve`LP%WgYx@Z&dxunj!t>KE;9W`K3kG(WHBStmm`kJY0~}#Q%b1IJ;`~iG^Zgd7Ub&n27N-{gjV1C3Z~-7FMX>azC2!OX35_*(&~s%*X8v zei9$iaI}2sX;%2NljjdQXQ$u2*J?hY#=Q#&U4wBu7rz>v^ui-w1V=XQ!{oj`5y_L)LLlHVvb!*bAie{V0DO?{@|!_Ba3y zM@uk3Dt)D{fR?=__H&)1j-Y?Yx}O!T%8dWMPj24EJ7|gO0kn<=1@gDEp zw-9;Uj~b2^2hVOedR}mdd=u7XNu}pXm&x_1!~Y{!1MRCN3l$;LDF&?~(ePf03|Yg` z0p8_%fzh;Vpl@3lf;^mO<$O! zBfd|B>SB2_R2EQUOEnCI9~}7<6b`T{zw?j zdQ#ty{fo|CXU>J{C)E+Hz0b|0VkQpeEc-KiTkLhFot4-|ia?c}68xA0^9Jq-uUoKYoW|=~`E+}+8&eHF_lN$bw?kPz z_iZCUD7)5b`@&rv2|X0?9QZb5Oru-yQv&-8uDTl`$ ztXfTf6skgZoi(a0GQFkFSNaCtExh5q<%?!zK(O254c|a%_}aYTDS~v?e?jf){1qF$ z%l#_6VWJK%97uMXXofNv0>v*>#4B9;A%6#RYiVdm`SeYpLFLmoga**oEwNK2TS%BE zDxgU)BLFm@{5qIJ%TEbDE}BWAHIG{BWwGg)?RA({vyeDM*Aj@Y@UoP60 z8G}q;@oPTNJ84TF=UVX-U-65=O6YSRqd@PE?o=ytN()!xN7rVyQghxH^(bu+CJy$_vB?XGMx-- z9)+Y4dbSB$+EZFo{epwZu&pk)o#)9%rTXzK9xfkc%X>&qAcl6+!hB2KY_UI#b?OF4 z!G7ESCzJ+Nw1vKI`~MP|{wI8=^WD10^uO>yM<|yEnd$3f=;DLw+>-gac(%Je;{OZe zlosv%lb*rMmA3iA`S?$~!#+dBHUquE_CH1z{w)!ITYM-MCthLlY#7!$sw3OgkXRb= zV_f3{Z_}~QIpp~}cu(A5*R;Dm?`^p@96HdMr31nK4diJE6gxmtpc}>6Js|{+|GpqS3U4dls{k6}T zVlQV3W`vw6PTz;4E`TR_Tki1q?7=)8`*=R`w(Kx-aLQxrW!Yjzq;Aw!U-TA6%HP4F z`$F2^;Xfp=ydD0}w8QhxXA|opH4i|L8sU#lK3CDvea(|I<8J=dp=|SOymEV+I0b|I z&=dDQp1O*yme{u<2PK@3c-lolfJD$okOBk^xcP#>+{=;7Z({@-F-|RpB=9^-(AcQy#76FsX3%U_fB5QHXkM z#9Akl0JC|p>y;0hHzHsU!mMf_ih;aHO@EE9y;drWWw&ED{xf@7_U=e*$`2&#U{pzi0q%daQ= zgu>iBb1oc0ZgI)YdP?@3*tg_6aPvq|(zd3>`$H##rb0s*KQRlq_#*>WuE5|*Q(#Lx zA*^05$qHrr$}bN7!H?ec=oF}9pM(3p?z8t}4XY`!H0Ne%mYN?2=Y*~7nq~CF~!mLR|y_KG+c^C})GhgHMmx6A3PGt_p zcF4AS#IF6|>)gW%UAILRlc)css^UGNo#eTZpx4=YT~!Dla)I4U-V%549u49;G>r!!gJ!2fC;hM`fUUGs*FP&^;QSCX$B z0o|J-fYV9FzgLf`UK#9ZiKXD}=jP>+(@y|a?bqH?+jIkRP zQ%l3*+!9uD2v)^bZ}WODS8ddk` zwG903?XnDbqL`wWfj@m2+(fIl-*JOI{b#*bf?fcYd!JeWt<3n|3&7zFq!z#wy#TOG zC{>O4_4MD^GySI=XZpXXr~gqk{i{;bA4P}B=|3_x{jG}je?0&Fsrj$Y56p$md1z!k z^eU5-smg&QHFM*YYWn+gpQEN9u#9BptNGqD{o|*~x5Id>N`0m$yjs7u{~>ImK2{fT z(?cD>;j4V^1E>>SI<&65=7F_E;NNH<53A}ii&sf7$^Nwk#HpEPhxTJW#}}>r#OJ;8 z01R>9f!HzDhQ;g9M)yG(I%kA%!sWK+e&pU=17dlbdd694;Fmitv<~g{d;hwN6}RL} z`KEo>dmtvz5=hBkyl2;k@}VTd#c4i^)@8u^nN`h-ZF<{#?{?}^Z42`5l+t1&D0er7 zvaY^f9a-F;3^<3{8%ZY?5F*^nsV#tVVE0AO&6jg(#d|Wbo%zGz6~KPGC696(LFc- z8+CNC8eqk1a|&sD7WZs_+}FJLW2-r{#=S=tpoh+kK|O?;vBz4G$^Y>eExIM1XElr~ z4-K^1GfRl7u6Swwhw`sKU$N~B^Se&*owLVkc+U+{XQQwA8n>@`Q6Y>$@`!Mf93SI* z^zqTdl?-maR;rSId?fplkjG^Gv1I+I8gq@z808Ai0yPgX1$@odyO{d@G2)h!j}y5VCZWCUe9Ta%stlA zIW!|a39A!zVP|Tc)wEe6Ias>l=UGqZ%MgZ-<;#Y;-I=UD61qVOIOOrR%%|%%A+rgS zgC%T6JU727;6nk2gCR6JdIi#(M^0WaAbQC|bt1ZXzVUcl+84URPEoj(WzatVr0{bd zPUrK^4zVDfSuisETo!7)LPgc~EYzNc-5Le~(zfzirUuStAJ?4ftK=nj? z1(-dt6riloaQdH&Z;=JV3c#-2%%bzBv#;p**xuIw{pei z(U}Lkh9wTY?mnjUhgC&Jke(ULJoGvjZg@B63hP4poMs-x@{h^>{bieVNjr`CR=9{> zoRKB}Jc!fogu50iWLH!&1{|Iz%1E<8Dvi4S=$woy`$E6{LyzE*nBWmm2#8~Hbm%Y^ zn?fxRF2;^#=?ex*p&NjSDpg2myA?UX7ag19=fw{WU=EWX3)cBau*_zEaQZ>mP?qI}kPR;REyet{+H5r~lerNPTiMm3dM5}k5s@xwW zo0Zt%ZQ4%vTj3viT%mD(8zyQDo!hN``mQ@4*626$Wvh@sI>c_H7HbbM8|vJ!E^G%$z-rnPD)ZYpIlp#s0IFC0yH-vQxw|9-Xd6v?f^b-?Znh#F5bI7 zW;k`Z^KMSYL6#uy5=xwRO)_pPaqBBVP!c;K87t)Q_1(w@NbFh3*k7pc&y=_!#Kp7M zo}xOslOZ4p#I@4tozt81~3oXWW~|O+hwxm+f)#Q6tdnyGki9>aP@; z4)~s%R#J%g*|nM!&%SIv)pk@$hq_Y_-EOXP8IK8)OC>Dks&u}5PpMRQ79Q3~CCMb! zAUp4^cC~F4O@~eSEJ(d+wT{%xK>wu*j3f|(Ic$owp-bfx7!xSJY)q&>88ao*Grm5R z@m2p^#^(rFAY5PK!WP)+mx1FOz`DZX&r^iTy~8g8vaUF#mEgK;e@Swru92alTJJGb zWzIypF}%14q!O@yE)`u?p&DC^+Jdam8TRC&^Q4t%HWyRkmydCN!3UtQ+&?p#+nmwJ zO00B#!IM$Ij&}2TAfldq99u=z)Dng{Lmf1x!wZ+1C#9`rm_@$7HCe0V{Bi0KR_!%A zWbmBvWEWOacdjM5&iRBA&C=e!pDR6|Dl+zigUns|rOMDx61IIg!D%7x%f(A( z&V$EGVm8bOukIv$|CjnhO*OTaZ|qf4U}g;+3rVFQ8?KRnJ#;I&?T=S%PXBgSnK!XXuhIV(r58Fh+pP^taVpU4#d?;+-$x#e!lg@X3b6y7sjsb6&@4w z^$M58#`X#aVxxP7r^bd7mI_lwrIh#lgT2D4zH4r#%*eH)^ON(RPMR&42-ed?8)C)b zBZ-AMPWcOfajMI9zOhk000&01AGjN@^p70F$s%oGPoEKB{pQc}h%SU@b^_Nixe#V^ z7j8a|tKE&s4`%u*-q%;EUhVn!59)JzfMbFBEe%w3E`*_Ui}Um6lXd%9TdHoO8vld3 zd34>zn7YY3X0mSB4aFLb)b8ltq;~XQE6K6XdEHd~*{i>z*>^8am8BYyoFCWL5pU*7 zAk9A>e@|=G{x?SQAMI1{%0Kna9vJdyU=_sPo}gS?!-8{#Na;6#wJe zKUeZzHNRJWl@d3$!n7y4qD;cSnym6y{#D}d)lRzxoDFAVEq0i9p|m^PiJ{gX23#RG zzHs+RkxBVYlZJ){Ffo=g@!~nE2iLycv!;`6raiS%zp+^8Ng*-YUli`n0I?4Z-&BN& z-kLyQS=%bAEsDJ)jWZK_j!b+ql}0>N)6-B>AW5oEpPALWy^l{) zpQ-jfBL4qudzVu~)85Xvj?-Sf-qm`mqz+VDs!F&lwsJ*J9X|bmsb318=!xm4Btqe@twr4$mMQ8~>b2Q~nbC$?^E|8048TnCh&Q@AVo_g3Ebr zs^k|WO(MCf%P}<8{A?;5k#K!a_-o} za^~%l9@6>T&sVXor;c&r{-57}X%E~5@txlZ#y!)xR&M#=Y9O(~LXYxb?=p+qe%J z_piq7H13CXCT;f)q}?QZ(ybn@<14pl_tZb> z?~>{N$bI&`&MA^EBO_;!%1bg`m0#E6luVNgk{oWENozJ~1YO+s)UW#kU2cmBA2wk) z&(zQJp-#WugbPjh_a%&A{8f0LZ*pVRu}_X4CA`6bIgSqD?&U1Y+^`WtZ9R8t;j zAN5PtZ%7~b;buVQ8u&^RZZ=`dgjbpHL=#?P!WWtFP7^-agb$do--JB}bpO?uaFGdL zV!~x6{0$SXHR01tc&-UwWx@?6Jl2F)neb2(USq;%nsBQL2TZujgvXfh0TV7WVb4dp zzE_%Xp$Shi;Sv+}nQ)~EPd4FN6TZ}hXPfXi6RtPmDidC5!e2Mx)h0Z_gx8pGg$Z|> zaJdP0n{c%WA2#7q6ZU+p+hc}5<?;FIe=iQk49_*EwTOcPGx^D!oz#9v8#@rZ#>;{R3? zKF7d!nQ(HwA28wM`cBSo-bmFii4T+Oz3@}rKgsY{Vu}=NUOgL!50TT|H z@Kh6CV8XLa`2S(=UEt#^%Kh=#G;Pxx-SnEYg}yB<4bYTrh)|%VNv|pNvLq=DP)s)2 zZL@TfU3NEZiWLJ?jDipfN>GGA(>A@J0THWKh*&+vgBk%PB5ICSPZiW0{q5{w)xGvpz2px<%xd3H?E# ztAxH;=z5{edS>SLTO_?%(t|>q^&qi+O1fF^I)uJe_>T&Gr_jAZe^}^KLi4&YommfV z*Q7cv=^qg~=a1SxX1%e5o+Igtgywr0bY}gTtw~iS=^qk0BJ@XvZWa0tq1%Q2n9yB9 zPZj#8(0M|e^=qckeUcs(`jpVSh0ghtu1~Abc|r@BfJh+P5RAow;YQ0JXbc9-e77YS z3Rr>WU@WdjL}S>BHPzLFX?w5^lOWR@eGLIC9u8ZfaHE-rbh;IeTG2o(+!U<~ShY>D zohlf%0?}yLsH^8g6N7tc$aDEGE_ziG-tZRucI_;ks>>Z@VuT^3{gSyl!jL7;f5H zZ#4uOpr6P|)TXI1k;RHbecx7J5R+J4G#rbGb*xaZ(aghP7}#ekQ0Hr`3xte;X|@Jm z<4%i;$1JevnK0QN)hX@a^ZTJftUB0O-4uhehK9b?35B4miQnRD2!?i6GucsV=oxNo zgyCV4YF{WC@cDOAWF#8iO7Tk7`ux>Y38lyCqQMB7$hLqpU#-}X36A(^U<*`}4wMof z3nbbRV&lO^+alFQ*J$9zCUgfoC(D<3yWIM4EMDEz2ulJIS?POcIs@me{~F9 zS=%^im(-?D2uqDtJE9o7$)e&rBYGsngAD&6v_}b!W7kbz_Z9yJ1Yl;*QBC5f2ru@D|G-Zm`E8`j6%8KcwxsA+0|% zUfR?)Y;82WEzoF1f>Qrv|FwLX`@1Dw$U@bUv5r{fAoK=u09y@)8uvbjHUJAe9l=HXo_}rFGqZW-wX*<%{jiT zSRAuW12wbPuT1M7*EeS`ORhskEex|1gJ?QAPKCCMqDG{heV?>*;!c=9wYw$fL5n%; z)g#WiFUg-ODH(5%W6O+VGz+?j9}9xEPr^8|YA5Jaaf(X_*5r_0$gJ4TSUkYr6vleC zNPDH#<%R3&nz*7My(xr|t4D9t*T_x`7mKssu@LMJ&|RZ4=}V(HppX-^VudltdFBJzQzGSjoe>1o~HD8UyM+Aq;*OOLWzu`AHM0xcU zspXYS(fW7=dj!+< z5pQkM{J8jOx4S71D%mbi+6V95+Ue=~dnfAn62Wf44neo%Q-Yo}x=_mTEG)XP_V&D+*F7(flYP_1MmZ}e_ zx7FLOw}-tw^6l|&&wP6+-^0?*{LX|ze;2Qq=oRRDhrlwXDLhrS< z(*FvS`Abj9M3-Trd#AtMYVcnw|1B!{hqHU%)1Onqtt$DKg?m!(<mJ~`CGqEakIu9p@m5#zFU$4b{!ISCwf}o#-faZ1q)GTQC6Y>p@x8FW%cb+b zx7sGT@L94n3*mb%4%c$at+(y|@a-RI{piQ;xbx$8-Q9N2o_p{6#3%1>f8bM}e(*C7 zJ>2ogqkB8|?LW|U@X+BSkA3!Y-H$)<`6s{d)EAF_>C0a^_SL7K>G|5TUqAkhZ~oJX z=f3sN&wu+n-|hY03opL({U5yC_rq6y^y-g)^3(o*`Pt7;{^FPadg@ode(m+&{PuSP z|MvSoyz%dU{L|?-|NNJ?{)*>y($;@>?u3bxCQq4~mp^U#j5E)gY0a8__MExr%quwe zyz}Q5F1R4MFS+!x#Y-+==2Zl`ryqU`tPp)e|P!+Y5VJq-0HG5 zS6sPv-TDpQtI8`X@j6=7HP>qU51sx$!v3LO>3u`&#;E<%v7oUj6vC#bKsBl+dyfUe z;c!1?1ePp}=wTz&h%9&Z%9SgJ)4k85?0fwM)*^4!$Q*UC$Fs>hQYp*IVfLJw`WiT; znj_6{IpDyq6nk$Z;g6*4%zmz&D9wmGoLYw&HaWRq0Q#dGg|Xc6aE&V&HcUsq0RlMnlYN++)wEi+T6bw5ZV%XJ!3Wh zETKK)G;Qv$SmQNq?vJ$!ZLZIE37xoKCiGh(@1)Rg3q2roxw=Ss@K>b9snMzsyQ3{= z^|11(xC){VY(-22G{bR(W9StTJ0@z=jYwm>&f~}4+;2;gVw91;C?VhE2tZ;O(zdF4 zTW$np)*(MN;6C319Yt!BYCtSYkEKY~B^dda{0HPy>UPvDit-v0rO*yZr{yn%g^YcC zs@B#ojxlmBw5*4oF<>pUq(lp~@Yy3L-4>K;UM&?%sr(PjZ?7RP_)Zm>r;+c;G!+p$h<14jU5(K6AL5{&$0duEnjkNiHAIg}h@ zVIwcuew0TWhaka%c47Pv+uCc}vaMo>(dq1QY(w^()RxmFX!%8|IAM?XZtrT8qHRYj zU0~armLx^ZjF!%FO?mH2lox@e*=m;bwK!<@5B77`m2DEVOG@^fq(md{Khj@fknFc* zTln8->m9Vq4yv2%+URnVrJ4R&q>}yTz1xd@XUBiAywv_=ENj|-u=cd4>0^WSztAyW zmt)LTg4@(1ldR;NrR{y8T9|0RQdp6rrU89Ww>x`eCMndGI$5|Pr^{@BMReOU#RnbO zm)YjLhA|p?)k6|z56WX(aqeJgjPt?QqK|M6X1b+zA~$;z(>M!<5;=5BE*LZhOns8` zyRpN&&%b&uU|(gOsDYlD8*Cj1_nqYYcA>iPUF_F{8dB;yRiW0XwFvR*4o5S`1?Qax zglIKwAI`DN(O}OEJCWwMEkUhlAI=#ZN84=)Nm)$ic+J%B|10cop*HL#T5GmHMaqZ724{pxrK<%L_0!)q#rI>(Ss@C23Fg zsKJ)vd>TjYCP?9Y%l@VRCv&cV{195phjJUycg>hH{VO@YGM)CPR9b<(S??X3v#DM$ zx7yMQZ4TCCJLE?ZXU2bW#b2Q|p!8B$cRlz9uTAVl>(%OvY3!Gk=wlnu*D5k_n7WXU zR-m>)^fdOxWJwm2F|Je7S0aaAC1+tgkH#LD)K>iWLBgewpxt7$m@`GUgD!&-apw;C zcHloR=_**5f6A6=N65c*(5%ju#5HgWG_};#h+{9(tIBe9KK`shnyv*`t*uuSebBho zf%x*KXcRX|y}r6_xWm6j-vGXs#Sqnwayn+rI9Fbr@8`VU(pm&rA=E^MIfR!)Wy~M@OHH# zP-hE9o+cljdO^OZ9Y8Gd*VO|dBgkvckYV4fgB;tCkku5E8*h+_8-TR|{nUt}{4gn$ z;f!W^3A%KhQeJqvb?Ywh`!Cp;Xdpk_d}|$?#lTKDo3E_w(uRgh`NWEL6?VTwe%PIl zN>qZTlAG|KEy|UK&+e^44+sJ)(0)`|=i^>d%hmalw3ZWt49%hCaaWX#gBXz?O^Y?< zncSvau3^bI=Dz~+srM>Kt_5)8*E|TH5LIIoE2Z%h&g68Kd<`G?(bZ)lGK@t(V?E z@E1a&U)XwvQCA(O_0{WJlFR6y8ea-6>AZprufyL3u&E#acRI#5WB4~8GXi<|$F)<( zkW+J);mw9iF=KJg;!0~A=k7wa5%$%tW3rwXO!|?#^>cRJ690OKPB-x<(&K-uuQ&9k z#n0HG<(y87@7kr~-BYw&Bfsr79lsWHPBpB)7Jqb_UXFgim{Ro1l_~L+>KfQh$0hmK zfqy+>E0Lod97fK1)O;P{%dxsFcgU#(&3N@+e);HKF5jso>M~m|{$B#GwZ!Miv3kr0 zT@BB5#JCYHEw{Ja(t-;(!)|Z6{nnOA!-wMv&WAtz;o-QE=xOn`wBl+^!MsJ@O)a=S zgNry`Z!7Xz1ud;D$fa-@r@p>ECud}HB(ftC8Fc*yVtU4a&p14P++*&wG47LT^v6Nx z7-ryIY4qJ`bXyvIPa3@^jlMUHeljbyyf38DW1&M2{4n@Y@PTIRv%@=7D7=+^p$BoX zV52=f)P-X<#(kRhApyzChXfmuV6X@QCNqiAbpd-RQCmV``w7D>zFIp^L)gECc|v}c zjP|S33DxyGBVkM_Tfo5dEm29|=~2}?7s59xJcqZHb0=MOBOVa(ZNbBUsKfal5A~+Q z`ii9$t11>$tf5#sx$0sb^EG10!%Bxm4(lYAIIM11*sz{q3B&3o3nXU(j)x0z#b^O$ zS2OO`>E{ENg`2s;D}{YUDIT-j9@rFY#4}H%*ZN`-=M6`iSUJtNF&2n!sJ#JCWv*$| z&v@Z!KP|>*e|GN>T)c>GQoPmHo+ZfQXxF58MsIHFJ2gx82)zw=tT%B}XC@N%ib--84O(Y!T#-kS%1Mx&#JQ~Dy zTH^7bcqq8FQ69K7sZ`8r4D8Tc2>bC&csyXQU6)_3)Z)cT%|hamB|!M=uGgIUxjp?b zb|LuAKVPZBLLidQfiJxLJnVdwnhOsRYBBPHO0sLI}%aLg@1e}BLF8KGu*KFTnKZQCEdFg7l*QU`l&OBAaC*i_d44bOqBUd3j zQ;BJ-&f1Ef6n;CchQ?~#n&jKgc7rt#-^3RKB&BA%{hEL_6EdW8)ZkesAD<+|!;>bf zRTm1!nxX-Us9~G>_+%r@oGHJ^cV-V_)$oZ5$?_A@oyo9+)=#THloZ-47>zf<68>N; z62glNe7ON{07OhZ1NGLssG{wj#BUdJnSWyU0%&@9}#3`QYTRS5_tF z2Wv&*PRPle_DD@f!2@mnBOBb^H+kd658m~EVQX#hl8g6M;-K9 z(0vY?`VTm0)-Uheq2hH|S=OxP{ohS4v z?7^weA_q-=9bPk!e22u*vg0qqrf4Xn@f zh|ufti@F?iYZ~3{pw}b4PiQalvpzZVO?`Q-7Uel;rh6SU^@}*@4WQc{H0#sjpjUuC z?VwkI&MQoow-R)TgJyfwJLoddZ4P=J=xzti`t&+z+UK-`roHnPB+Fy}C~?rVSB-;a zd$&4hUYF={&{u=*6}kdffmxpcp-p?emEh;qaiy{^Fy-s#_s=Y{t*Vu`C|`0bmPUtinL#HX*3@j5wW=&OHt{|<6PkZWRiKa6)QcyG+`P$OQU zs}~F=P+yk}45ACc%j=?Bah+WwSZqf*yko)ZnE_ns;ynxAU7=1};Pus0U0ymLnY9`CDY?af_Y)>olEO}IkH(hCRGnUYeiTL>AM+hs5x?K(KWwkz-Z(mI3FwVgA^ zvp3Y*S|(c{y<9#;LCNXyyid>oulv*B^hRiuNgv+bpoREsh|j(wXe8L|gUX?u**-y7 zRzDx1@3Zj=s}JoI*4YN-YeJ96RKB+2V0{_yLk8X%V_k=8!PNA@y*M>Jgt|6E9`A1I zJG@&(-&DSseSh6~eReByMQsc7I;{_K^u0VYT2j;5tEsWRC#Ubt(P|17a>^N6pH#lV z`mi7986oq?=e^kEi063Y69dT_@h(^taRF##>OfNrj_0@uqxIOkIHI)6#Mg*x+&Vrc zt&MfVE{D%z@ChR``t|*>n^3ZIPNL)(a+FuA@sGV9rsr~LSHHS+rG5)(`o7MBCUTV z_O~05-|WYXeHKZ&p{s;8_B8u7L#OToxL;x);keiHxSmgv^HH6>;xkq|vp$>l=93D1 zQjgCOq|0Isjzd2AVff8HsxWOQ#lE%!D-ib=oC6HMS>O5e1D|ctyDifjIS)sXD^q-O z92DAhFcE$Qq46KD` zuUXIWL1aH&c=lCxJnw|^x7bGXzd4BKdtvq^3cO^D<4X{u-PQo!e-2`fH}C1mVI@Jl zSI^hM4WFUSTjJ(W6Z2v*((NnImtKmJYH`6v-t|w$Z^3~h$%JG)u9_yJRVfrg=D07) ztCkBEED!~BJTC<$qo-eYk)GVaW9xG%uD{`s2KzN?d8r&nCs=dwCbP(`Z;I=yq4GMu zD!{=R=i-1B93!#97xyjTd;10FT1%E7W84?2kYg`&{snb)#vVG$0w~Wb%t~#X?2TS5P&b2+;z)lhA}zAyK*D1ZINwV1eYxQzWeKdnQ)GpZ2fJw*JOM&vI(aL0HrC;C zZFCzh&(-^I(n~OggAxKh99v=)7UD`N+S#^fydJNK^H3dJ{)c>>r98aDTFi^03u2H1 zO6j|KmVF|F)fCx*>*DVyr{cV8&Rc)p^7H0;7TJ%$J7igxFR?s!W$@3OpMzdYGeux6 z`+lLmJh-^>aynD4qBd-cuTh@eOE-6`}D!4|=et91SoY4OGmGmJ5869 zNM9l}cv{K3HkB{3Nz>_ipD5Sy$D~{%&**hp%Ilt~<+se&I51mdX$*I-*~4%G42})* zbEwYO2Qx5$(-i{t$mQteyCT!E37CEz(F=bSd^vmtd@1}g_~q~`@TN9+@NfEtGWb=< zGuNJTfPRLEm+2rl$+s{;PT!DB*b&9`_BD->rZ_b7+sB>QOAO`-zqO*G+|G=DxJ}e} zWniZl13Bj8Tpo{x3UMKAHP;8sNXv1XDI5wgdgXS^HRPp?ay-w5yZwI4N2!<(BKq05 zHH~%V0yN`sfQ$VoopQvNhT?@d+$fq%ggi(3%8KQM+X6cyR4u{dNZ(kws&ElbMe#*_ zb@uZP)CZ4MY-@_3MkL_s>g`$;7G923!5_GEZbZlPe<}PqLM{UqNEp>t^CY|iI9I|e zfoA38T6?y{mjUNUm}|Ew;wpr1lz19ED&Yzs8-w!+?@cmqmV^s|!z9eLFI&PaYq*4G z0Y^x9HgKebDJMt5QyEBqh@ zThBw>xOygt>#!Db4`3p2V=WwtS<�*yw`w;W)%q;$FEv^vKu1RhOr3HTu!}vCF6p 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 literal 0 HcmV?d00001 diff --git a/lib/pty4j-0.4.17.jar b/lib/pty4j-0.4.17.jar deleted file mode 100644 index 8ec523de3343346ed65824b01f973e4d64296209..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51090 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 diff --git a/lib/pty4j-0.4.18.jar b/lib/pty4j-0.4.18.jar new file mode 100644 index 0000000000000000000000000000000000000000..4f29d69edb7c4282c73fa6eae740ebe251871b88 GIT binary patch literal 48832 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 literal 0 HcmV?d00001 diff --git a/lib/src/pty4j-0.4.17-src.jar b/lib/src/pty4j-0.4.18-src.jar similarity index 58% rename from lib/src/pty4j-0.4.17-src.jar rename to lib/src/pty4j-0.4.18-src.jar index a89c650301ee9d789ed323813aefc7fd17b73a6a..58ae1f94b94643d3aa20c6a567e223a8ba1967f1 100644 GIT binary patch delta 8386 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 delta 8697 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 From 07df79338cabace47d3a76d199e0840826e3d9a7 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Mon, 10 Aug 2015 23:05:17 +0200 Subject: [PATCH 58/99] Update pty4j to handle older Windows 10 version number = 6.3 --- lib/pty4j-0.4.18.jar | Bin 48832 -> 48839 bytes lib/src/pty4j-0.4.18-src.jar | Bin 31592 -> 31640 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/lib/pty4j-0.4.18.jar b/lib/pty4j-0.4.18.jar index 4f29d69edb7c4282c73fa6eae740ebe251871b88..80fb15252745ad72dc1306d7e4f0d24af19944a3 100644 GIT binary patch delta 3750 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 DlMS>1 delta 3694 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 jZHvJ1qJ{B0015U9srXF008fD00000j%OJ? delta 1641 zcmV-v2A27l_W|hk0Sr(}0|W{H00;m8Ri=>)DFRfcu{SwO0*0lta!aoR4Thx(N4Vj$ z$({uO05p>>PbGg(95)dD&aZGRCEZJ}2C6iwAhbycNVJ!LxV*HgB4qY_VCu8CwimcI z{P&K>-aYTJM-tQzMS|P4=k=Lq#y%=u{>je-Db0*ke*WZw)n2OYwKX}bjP_~Ax zHFmZL=Yn5yCJoz{N^Ex)wealS@j-XdiL$oR&)Ke-h_R_{xug}6#Rz+rU-JqauRngg zMjn&ry!PkD5^wo*3JdFNReh>tNlL|?Bap#6&>{b<5t25X=N>+$QgcPd-b#H&4#y|& z_m0O0hi`w#4jIp#7l4}ZN7hur`guW(W0%4@K$Z@eHzRW;>@EOa3?LLRZRI8RA{k8{ zlI^3nzn_c_UY_h9j$Z8@ckBy&SjmHtnjtfM2oA&!^VHdZBz-!KWj`Xc!98yFAQ+jF4Vq= z@1Tsqgty!agI_xz3ttQdLv+zl^BIKA_QLLR@a;pjpn>(tENIV1Uv`=rhc4-O0Z}|08PLgaRTx2@v!c zwH<%)=RgmmCIYy6&O<+G&n0Ydp!V`w5Jm!{jcDk3#Vwx^9*NBp!MzEjn?x%~Fb0e- z>npfKAn9MY-Hi@mVIM;~;{LqYjSkTM079`a4anYgDXLJu1n#17A?o&VC#j|8@d7LU z%FMt?F$k**z0^8{gqabdkF%qt?80o&8<~HS2U}3R2MvFlGACW|jy!|MmC8^+7)HR! zSlSyRloPF?giQq~bW%AME{42V8pBvp;tijP$R~z76mvuro9rMN=s5u2`U5=?*I+o< zXEMATP7At4gMrQMOj_tkzw86rax_4cTiqewZIVx)GTpF}_X1WDAv%B);Eby=FhYN{ zg)L|-d}xf-c@pV}3UG=E(Z-W2>CdH(^xHz+5b;tcwaBJQ9YugKH&>rJ+|05Wwpp}> zx|$)0P{(YwgZxTf=7NJ~Bu}%hTG>gV zkV|L8ErzG?x?*|!>+5;fLdNm*W^I2RaeHJqgai2~c)*o{hI9QwOr#eUZvYI`UPHS! zOuNHwVt5Mfj){_H$qLZ0MiyF3T>{a(ycB?(<#xUrvxKwC5r*J;anD9dS3W~I!Hki# zLOE|bnk~T^d64Xlztvg{gD4GunYa!IDCGDvE^hUkxE;ZeP} z{D>wCr#kmA228Cc`Wqh)mWOVL2UI${9y&V2@B!;M6^5;!=BEwycHa!L$@v2-VAm#lv|Hd#@c3tt9Q#3kOplVp2R zEZ3>|`VwO++BRyAe=DXkoW0V)wEL~XWa)K9A=#qQWzs!;@>2S=`Qy`*r%&h>KGA&S zppDIqZbP;n=vCM}p$$)SxZB9H6#V%xDfi=;zJ}aBjg~U*j#0q6Rz80VI!p33FZ0-= zXo!5qOXIF-r)QURKg4g6{rZskoysGr>+6116}IU8rbXicuPUuOfaq}ic3x$doN&2u zbrrsQipgS`cBD4o%AYK#(G zXPw=d?tP$GGTc9g%?-BEI=Wf= z7qcE!-5ml|rjz}0IRaFsvp92I1p&d0GPQ zRFi>uJ^>z+zxA6%1xc@&d>Tn>{sdMW~bV3QGh7?XT@JOZs_lM#CulhS%U0bY|3 ndrAU1Z<7&w8k3)I3>HvJ1qJ{B0015U9srXF006&o00000Suqjd From bd01c8d805dde86514be77121ad3665b977fc33e Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Mon, 10 Aug 2015 23:21:32 +0200 Subject: [PATCH 59/99] Fix dll location search. --- lib/pty4j-0.4.18.jar | Bin 48839 -> 48844 bytes lib/src/pty4j-0.4.18-src.jar | Bin 31640 -> 31642 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/lib/pty4j-0.4.18.jar b/lib/pty4j-0.4.18.jar index 80fb15252745ad72dc1306d7e4f0d24af19944a3..a1ae8457ddaa5f0cfc4dba23b94770973d8a7b56 100644 GIT binary patch delta 3706 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 ZqJE`7k^tm;&A%ObbS;UC?gs`q?q98>&rtvX delta 3736 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 TEqgBkX_H-hHwN!=00000&TAEu From e80cdfeb4b270178eaf231a35146ad78c1a71479 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Mon, 10 Aug 2015 23:58:02 +0200 Subject: [PATCH 60/99] cyglaunch.exe in win10 binaries path --- lib/libpty/win/win10_x86/libwinpty.dll | Bin 192512 -> 192512 bytes lib/libpty/win/win10_x86/winpty-agent.exe | Bin 185856 -> 185856 bytes lib/libpty/win/win10_x86_64/cyglaunch.exe | Bin 0 -> 15360 bytes lib/libpty/win/win10_x86_64/libwinpty.dll | Bin 196096 -> 196096 bytes lib/libpty/win/win10_x86_64/winpty-agent.exe | Bin 185344 -> 185344 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 lib/libpty/win/win10_x86_64/cyglaunch.exe diff --git a/lib/libpty/win/win10_x86/libwinpty.dll b/lib/libpty/win/win10_x86/libwinpty.dll index 6c78cab2c98a85f6b07041160e48cca8676f8544..e1644b8ee80dfcbc28d1fc429caffca5ad3d3d41 100644 GIT binary patch delta 90 zcmZp8z}@hGd%_RqB-xXVzqkHoJo!u>$P8rw0wy4K1mX&JCWZ=K5RZWYD7XFbbHCah~84Q!C%$vSWLXF4GA$=0u=^@DQezvjMjcASnO< delta 90 zcmZp8z}@hGd%_Q9me(g5e{cQGc=DM%kQvGV1WZ8e2*efcObiveARYq)P;UF<=ZrI5 l1)ldF?S5j$>@`nmmDYuWyFPF4(PcWJ1~O-RcnH(V*#I(`Be4Jg diff --git a/lib/libpty/win/win10_x86/winpty-agent.exe b/lib/libpty/win/win10_x86/winpty-agent.exe index ece0a21d8a5e5c5b520db34fc306425749c09bf6..c818ddf391490b12290f81bc0c5d1ab63d56419e 100644 GIT binary patch delta 80 zcmZoz!`-lkd%_3iblH=QpSONy6g({tWQH;T0TU3r0PzETCWZ%+ARYq)P;R^O8ODRY c0#A)sEI-iM>ApgTiA{!Qe&6;ll1w~%06Uf%oB#j- delta 80 zcmZoz!`-lkd%_21*4HN*KX3iaD0o^P$P8rw0wy4K0pbVxObibsK|BTqpxk!lGmHm) d1#+&WWz3oL%x}$~GPm6AlFi${NHX#40RWQe9m)Uz diff --git a/lib/libpty/win/win10_x86_64/cyglaunch.exe b/lib/libpty/win/win10_x86_64/cyglaunch.exe new file mode 100644 index 0000000000000000000000000000000000000000..8e8a1c843e1510cb017d02bc69d828584ef93d93 GIT binary patch literal 15360 zcmeHO4Rlk-l^$6Z7=w}1#MEg>csPQH1ljT*$kYZ2+vK^(#0?lo1K6_kWR%E~svmyR zlsc82^{Y_p&EF>3oGzOsG){T0m5g`-~c7|PDg4-1c1fxQSB!puD!50u3ZdfUF1wB$}K|#JrGu_h2 znCH$Z6B-(2WjRxGaxQ0|0o#U>gHos!c%}o&Y4FK!dJJ3$$ZixcEoD0DS2tq<7PdXH-#rKV!w@&JM;DGTzSEI^H1g%%_F1nVIw_;Op*!C)AIRcuJ$vmMH2TEyf4= zMtx6r4k$hCtfjrw1=V*IhQ_JPu{DmY*O-;Oc~ML@}T?5xFJ+7a{l zJw8u0@zE!4Z*GPVP&>2QOGBzX9*cHO&U^v6EvlTAViwZmuDyU<^!A z>W5FY$H$}}GWjU;C(6P<^fwZAgU!cm2N3G-0+fu0o!*?fOA)sc}{hk1x?^LlEP2g#tLyMQH7x z%COiJ9gCy+-T^ULG?YrEqL%`>9TlQ{AXT)F>g0oB?}_LXC_Fz43MZUNLo*Q2GhnIw z1RN07k1Rq)Ol)uc;J8DMR>!K=HLF*`2V0Z;b0=)d&pPEHr+iE)#QY)$xJ?nT8f|7%g^l7gWNVfd6Q1rh1!}k@~POH zVtffR_K+7%@_DEHYwFh#()|kQmIAx5ccwA#-hm*=>;Qz9j{+cR6um0&jIqz0;l2e1 zH6dj-a5(=Us+E(#9r82EF~A1-HTi(@B#*sOCT)!H8x}|z!P|@6NKJ@2(qI#6#om{i zj14a+U&teW#A2jRC)iE$3(7)R<$5DGe3(ipW=JIRlz)dcQ65z0X$r7&FWE^JtpRZC zqt!x`*O>(6U6MdxQh=(R$z*4EGPiS+X6IKRsbNY>)sB$>S#a#T9>$a>#`K4Nk4_{D zJ_P}#2HwSwq(+_uPuZ^8G-x)H<2K*JDhJ=bM?kf?f^6Olo1`6sHcyP#pn_yT*qHJ% zaGn;(!V{dYe22h@vJ+tBCFp2leu!x5)%aB57@sL?#bneZ$j^%Mo65h!+ungKS2oF` zs^wF0k7@qk9Zr+bO-&|H-;eQGd-H}t<1EJY&7}HMF5Vy?R%~z?Cg$6F&dGzZ0zQSz zT-;8nvw!+3xOhOJc#hS{r@r?A23|Rfb^Oe+aVOWT7JH9IYsG|4OnyGknY?oNI*i?Z zddp!d$BbuYi}8bbVq)oekkLz=^2;Jk_Mg7BD|T9p4;VJI4PqR2L1{zV$P%>Z<e1_Er{ql+u0wL0USjg+OmCyYJo2}$Hoqi|;B1ZQT9 zETP(Qe~dj(!_Q2gek~?N1DY`Q{0C~fYcMw-q^=}yH`!`QeyYbThK_?6t@a+FT&F)kNO_0iHRO?GAJp zA$*#aFayF)y!B+^jzbg@TJr|`l`~jmoP4?!^uV5DZxNbTvu_v%$_FyV)%9@iAM(fI zt!f^IQ8ayxD4)tuA9;nmNEV!*hdjHRhC@Cu@)P82`M^jgB}d!1FRwtxv6nVas>M~j z%@I4q#*+t_WA)e@;f}L*=o|MKm=E*1MojqfoCz1!5rn;GAm(x=ET8)_It#jXEWVDt zv@65Jkl#~A$t8M!3~rm}lz*j!h#qP%3Gjk7%WpW4&GMTFrz3R|%{;IXsr*AA{XlvK zqEGQykq_zDiDScHhIb-0l&Jo}?N}lcvsL#j{h%m2YQ^L_lO2uKQe)%qKbS99&F3Xh zi8)}?TuwXIB)=!hFT$(T^9>}@h``T7c?Mp_&v(V1Za`OJcz1C3$ceOjG{2!r^(WEQ zGj|h>_bT4)Pj$izQC?*dopOVz#VI>YYoj(%{*jm{cmQ?IWP@5|R&Il;Gf@x+7h~%; z)3{-pXyf(}8m8sMHi(cnFh(zKVSi3HS$`Jtiy^PP3L(5I^;;HT*?5o>Tb3oJDn^*b zLUS|F1_~Z}?-P^DbFq_9;$Wah*fQKqD*z)qOOPFWeLwT+`1~pO@ETN^Pz5txc&n)r z-D^>wPxRqLC_>K{SPt5owE5)_)1V>Jn^Fk|_i-itW)!2lL;F>&R|+h}SZ5#^s? zh~O3+Pmk5Uk>6wE^E1(XTue^;lqjE6o`YFTZ79lzRU5M3WEK&0K@;A`5G-XUO(l_~jK=}?WN#nbi!L0RfY`0_;6E_J+IzAtSCiyw7|FA=&rPPxh|+Pd zOl`X3z0}bMKT9KT-gb!?heJBilA8QP894_JPbvM}_fa+blp8^TD-S7szKASGhs-K%hUzJ7wsq!sj=jS@gCndebM+fvkFO7QG>hUY$j+$fB2J(TlU_1zB`y7CkqMzAB5Jkws6RKx6qe zVEn5@1F z>m}CMXR+TD6Gg{ydw}(Qs6J2R3)++2(1XNlROC|Vc6bIuP|fp5V7NR z4`JhlJ>f12L%i-jm7?_$RKH5yqEcT|DW^*Hs8p#+ZBwa2mD-|GZ;~hRy0A+9oT!As z0!ox~fL+J2rPxXv%qm(4bdHJ^11(We0q86hH3OZgqIi24E>}?-ZWH!k3`9AuP^XfH zJ|k^VMY(=02tAjoZwDG`BdPk0KpR~g4FUbk975v)IhZs|Qz`Y7XjuFT1wKxfP0C&9 z9p6ascl?I+*sU~>O2Gq@2^2j>Kn~eyJZQX-Ja#R4L{XGmTEs-3okyW4@YB@$(om z!w2i&^SuMcJp<$l8t*|J`tn)W%2*S*dl`#j2Fj&Ub4r7mi)d=jvMhRW7JWF2{%``# z_s6s~mVb(leH~6J-=l(EV0n!3@Rn5=teCi(C)hy0vV?j5CB`u%g1bM<-q$Rq4w z-`ZvDy^oX<%P}4PYd5&c5t2z33_!Vez+t@iuyWs9;NUp=J3zWc3)6a%EO?B}C!eOJ zL5XmY_mpQfksBbA=p}nFUEElH6gLgDueO52(i?5sXH%~2N9lGZ>aInfAqSM!+(@yz)<*RSfWzKubW7P3v!8JV82b-{; z-iR7Ua+T==(S1TZ@N2!8TslLH505H8c^jg*(ufb*oXMr5PVAZ2U^niFpPkg~{*4$v zoGZqMa+?l}=vO4?A0w}va`OvK$>u!8gE4U?nqP1j_Z)U6_*gpS*UVA8Pn5 zY2c_=@a-%3G_)sr`Km4BGD(zgH^KW@3#O+{4I3Q`ly$H1Uf^2pu6KApf~5PRvhxk_ zlg$FIEk;J^pwyIXDpX2&W~?X#w^HRIDJ};Sfr`b%Wa~`%6peH8%fm{^yQ$P+!__xo zLhnOR*;_cFH4iISP`DBWx!}`Hl0kV9K{4)Wyi!a)azCPs^99}PIyN|P-GK`S<#UK8 z2Bz#YG)4!M?@#-$w_)d`Cj#vRFuy}@7)2WvG;!TC{=WwpE^{q<8lneLFIBpdgLpppliqH z@eWB9<*NcqRDtv8@yHw48>NcgxRq-zQ!8Gf3LCu!#vcCtz{u%W(>y5gCuG*X*CXff zr1>g!@$+vLflIZ9=vI%OY+B`B{QP@~fO~6ar~4L5d3CAB?`LhF+thZW)ai>vrEtC9 z6^TgvOWF%`wl(1D@Jm88D0qDVkKm2@{X)nU-6(j2VWDJBq=c4SJaZ!EIi7iogs>Ei zg#*4or{IZkH7Ohph8GEQBKa&LMI%0sc^)C5PL4@iBzIdVx|Ov!R*C$hj)kZtGiC5@x!yldR08#Do5z!LI>B&|VVvk#%1<6$gaAB;sWD3Gp)(F@kQgMm#_ILdv% z@KC^+#*;jpDrJ6GEa2WKd4!OUSZHN#ueB_gH?GRD3Hmjq6=2m=`W#i z;9%Iev6(F>a~ZpFWy8vP-_+92zUJ8WXk|2T(mj_h+b%wTPZ21@w~HwBTdfwr)hKzu z+W`-w6aqgE_&mx?;KP8r%NR2OF9d8xu>o%Z+=bErd^eyD8^{)t0sQY7jI9Me3fTW? z#x?>cSXYcwH*h=PgDCd^-vQ`B50T=Llw+fVD;C4Uvwmw@(TgT5<<+j-zgpo=ti<$Es`B@TD4_lf!b_bs^m)lh`G?sX0@udF?qN z*u7*5=suQjozk8cn%pvJAoqCAFm#Q1%&3!DrgiR92kHzt%uu1T>hcUMuOrv0=a#_F zpTzQSoMbh$=Z5qxIRm;YruJT;zf@Pxrdg-9=ZB^YOg?TH){m-v(E5kLptWnPx$p0UWSr>@*ZHU>Yg+;5#Fxx zw`=fz4L+*Dr!+XA!6O=cL4&{1;8_ix*C4xBZKqI!#TuNiLAwT5Y0#rVzXqck?AG9R z4c?={hcx)826t=l`x-o=!JlhzSc8fN-_{_zPxUiTgO_R0tUzb}r_}#r&WMd{llEu(me$7FU}KzkT;bvF?DzIW~YxcqRbHX+A9B zh)*`I0o~>D;kyg$OIaH(E85)QsFkf`ZCrT`Yx8x5VqpnK>o8xsc zUG9zK1T&<0z5uQP0xn#PvKcyZ4~2WkSc%RP3*qD|>gZZy6Khf-8o{p+bzZGO#vayr z>5hQy1PtRM^;54=f>3$6RY@(Zko|s>gcVItC zyq0j#?eKWQJjZX-H^=-@-_os7X;pBI&m+}ubRoC(HzGb{7ddEHLusQD^v?eWDC!I@ z=Qo>|p}!wjmN(wGqS0Ad!G$Rq{vjV7!|{ts_r&h&_@3B$0Y1rzC~J2x_KjSk)TegI zmM*`5tH+2h7^o{LFSV8kQotSb;3l%Jq;=IYi>*Y6L@@YVN|r3nucb@p zt`7fJ0s4VRT?uZD7e#P8+2x8@x_s_%FcS1eE$(2~B3GoVbW?eW(B%sFyiz2(Ijdf6qT_fO`8s@lxcAB3 znjlWmQXQyug+hLx8-{{`F_&grEUPw3LQ@0&vgZ$O#y|EvBqBwG3~3<}3x$H=D8J`l z1Cik7h_D)87`OzBWz3W&Bzf?Uza~#z$(JNt8<$sAFT@uORSPUtmF{YbtJ*7BtX7*x zlB7ycrPuo9jPU&VzAXG$KPs!sD{UP$E=#qi27Y)uJQkZ&;jy?Xs;aCN71iFFO4nb< z58KE3QRS-eR@kIUOLb*Ojisups@&4ys&QL93u-)7t}538snYgW@}so;V?8PNE?Bt0 zy>NlWW|hh mFOV delta 80 zcmZoz!QHTed%_RqGp|lG{@(hVk@K=VkQvGV1WZ8e0mKe&ObiZYARYq)P;R^O6-LD* cfi Date: Mon, 10 Aug 2015 15:02:58 -0700 Subject: [PATCH 61/99] IDEA-CR-4279 (reverted for a better solution) --- .../src/com/intellij/errorreport/itn/ITNProxy.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java b/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java index d86caed913a5..eefe2b90ee21 100644 --- a/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java +++ b/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java @@ -64,8 +64,7 @@ import java.util.Set; */ public class ITNProxy { private static final String NEW_THREAD_VIEW_URL = "https://ea.jetbrains.com/browser/ea_reports/"; - private static final String NEW_THREAD_POST_URL_SECURE = "https://ea-report.jetbrains.com/trackerRpc/idea/createScr"; - private static final String NEW_THREAD_POST_URL = "http://ea-report.jetbrains.com/trackerRpc/idea/createScr"; + private static final String NEW_THREAD_POST_URL = "https://ea-report.jetbrains.com/trackerRpc/idea/createScr"; private static final String ENCODING = "UTF8"; public static void sendError(Project project, @@ -111,8 +110,7 @@ public class ITNProxy { } Map params = createParameters(login, password, error); - String newThreadPostUrl = NetUtils.isSniEnabled() ? NEW_THREAD_POST_URL_SECURE : NEW_THREAD_POST_URL; - HttpURLConnection connection = post(new URL(newThreadPostUrl), join(params)); + HttpURLConnection connection = post(new URL(NEW_THREAD_POST_URL), join(params)); int responseCode = connection.getResponseCode(); if (responseCode != HttpURLConnection.HTTP_OK) { throw new InternalEAPException(DiagnosticBundle.message("error.http.result.code", responseCode)); From f71da0ce879ef1496a72d87e05e9333f8450feec Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 10 Aug 2015 15:03:29 -0700 Subject: [PATCH 62/99] Cleanup (proper title capitalization) --- .../src/messages/DiagnosticBundle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-resources-en/src/messages/DiagnosticBundle.properties b/platform/platform-resources-en/src/messages/DiagnosticBundle.properties index 9b044dc411e7..4dedc81be079 100644 --- a/platform/platform-resources-en/src/messages/DiagnosticBundle.properties +++ b/platform/platform-resources-en/src/messages/DiagnosticBundle.properties @@ -67,7 +67,7 @@ log.monitor.edit.aliases.show.all.checkbox.title=&Show all files coverable by pa log.console.filter.show.errors=errors log.console.filter.show.errors.and.warnings=warnings log.console.filter.show.all=all -title.submitting.error.report=Submitting error report +title.submitting.error.report=Submitting Error Report log.console.filter.show.errors.warnings.and.infos=infos error.comments.tab.title=Comments error.dialog.error.prompt=&Error message From 99c284b67d5cd49376ce4919edd436c62fd79033 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Mon, 10 Aug 2015 21:44:32 +0300 Subject: [PATCH 63/99] allow null array in of(..) --- .../util/src/com/intellij/util/containers/JBIterable.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/util/src/com/intellij/util/containers/JBIterable.java b/platform/util/src/com/intellij/util/containers/JBIterable.java index f9d9c816d5ab..9893805e5bca 100644 --- a/platform/util/src/com/intellij/util/containers/JBIterable.java +++ b/platform/util/src/com/intellij/util/containers/JBIterable.java @@ -151,8 +151,8 @@ public abstract class JBIterable implements Iterable { * Returns a {@code JBIterable} containing {@code elements} in the specified order. */ @NotNull - public static JBIterable of(E... elements) { - return from(ContainerUtil.newArrayList(elements)); + public static JBIterable of(@Nullable E... elements) { + return elements == null ? JBIterable.empty() : from(ContainerUtil.newArrayList(elements)); } private static final JBIterable EMPTY = new JBIterable() { From 701a784f1f56ce07b54ef5d1fd993505d6d778c7 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 11 Aug 2015 03:38:40 +0300 Subject: [PATCH 64/99] EA-71652 - NPE: QuickEditHandler.isValid --- .../codeInsight/intention/impl/QuickEditHandler.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java index 556b821b3569..54b85bbaab06 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java @@ -96,7 +96,6 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable { private EditorWindow mySplittedWindow; private boolean myCommittingToOriginal; - @Nullable private final PsiFile myInjectedFile; private final List> myMarkers = ContainerUtil.newLinkedList(); @@ -199,7 +198,9 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable { } public boolean isValid() { - boolean valid = myNewVirtualFile.isValid() && (myAltFullRange == null && myInjectedFile.isValid() || myAltFullRange.isValid()); + boolean valid = myNewVirtualFile.isValid() && + (myAltFullRange == null && myInjectedFile.isValid() || + myAltFullRange != null && myAltFullRange.isValid()); if (valid) { for (Trinity t : myMarkers) { if (!t.first.isValid() || !t.second.isValid() || t.third.getElement() == null) { From c4d828b9449314f6838a84d57e4d121477ea8799 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 11 Aug 2015 04:11:11 +0300 Subject: [PATCH 65/99] EA-63233 - NPE: JTextComponent.read --- .../src/com/intellij/ide/util/TipUIUtil.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java b/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java index 7ebf2a57a998..9ff495b63a61 100644 --- a/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java +++ b/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java @@ -20,10 +20,12 @@ import com.intellij.ide.BrowserUtil; import com.intellij.ide.IdeBundle; import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.ide.plugins.PluginManagerCore; +import com.intellij.ide.ui.LafManager; import com.intellij.openapi.actionSystem.KeyboardShortcut; import com.intellij.openapi.actionSystem.Shortcut; import com.intellij.openapi.application.ApplicationInfo; import com.intellij.openapi.application.ApplicationNamesInfo; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.PluginDescriptor; import com.intellij.openapi.keymap.Keymap; import com.intellij.openapi.keymap.KeymapManager; @@ -33,7 +35,6 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ObjectUtils; import com.intellij.util.ResourceUtil; import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -53,7 +54,8 @@ import java.net.URL; * @author Konstantin Bulenkov */ public class TipUIUtil { - @NonNls private static final String SHORTCUT_ENTITY = "&shortcut:"; + private static final Logger LOG = Logger.getInstance(TipUIUtil.class); + private static final String SHORTCUT_ENTITY = "&shortcut:"; private TipUIUtil() { } @@ -102,6 +104,14 @@ public class TipUIUtil { if (UIUtil.isUnderDarcula()) { replaced = replaced.replace("css/tips.css", "css/tips_darcula.css"); } + if (browser.getUI() == null) { + browser.updateUI(); + boolean succeed = browser.getUI() != null; + String message = "reinit JEditorPane.ui: " + (succeed ? "OK" : "FAIL") + + ", laf=" + LafManager.getInstance().getCurrentLookAndFeel(); + if (succeed) LOG.warn(message); + else LOG.error(message); + } browser.read(new StringReader(replaced), url); } catch (IOException e) { From 37aaefb28ed713627558da8d1c1ed04678f78aa9 Mon Sep 17 00:00:00 2001 From: Pavel Fatin Date: Mon, 10 Aug 2015 12:38:35 +0200 Subject: [PATCH 66/99] Zero-latency typing (experimental) --- .../openapi/editor/impl/DocumentImpl.java | 6 + .../ex/util/LexerEditorHighlighter.java | 40 +++++ .../openapi/editor/impl/EditorImpl.java | 166 ++++++++++++++++++ .../util/resources/misc/registry.properties | 3 + 4 files changed, 215 insertions(+) diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java index 6aee3794da28..aba7f6cd0568 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java @@ -804,6 +804,12 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { return myText; } + // Breaks encapsulation, yet required for current zero-latency typing implementation. + // TODO Sould be removed when we implement typing without starting write actions. + @NotNull + public ImmutableText getImmutableText() { + return myText; + } @Override public void addDocumentListener(@NotNull DocumentListener listener) { diff --git a/platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java b/platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java index 84119ad2f0ec..c578af5efb69 100644 --- a/platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java +++ b/platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java @@ -28,6 +28,7 @@ import com.intellij.openapi.editor.ex.PrioritizedDocumentListener; import com.intellij.openapi.editor.highlighter.EditorHighlighter; import com.intellij.openapi.editor.highlighter.HighlighterClient; import com.intellij.openapi.editor.highlighter.HighlighterIterator; +import com.intellij.openapi.editor.impl.DocumentImpl; import com.intellij.openapi.editor.impl.EditorDocumentPriorities; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.fileTypes.PlainSyntaxHighlighter; @@ -37,6 +38,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.psi.tree.IElementType; import com.intellij.util.ArrayUtil; +import com.intellij.util.text.ImmutableText; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -351,6 +353,44 @@ public class LexerEditorHighlighter implements EditorHighlighter, PrioritizedDoc return attrs; } + // Called to determine visual attributes of inserted character prior to starting a write action. + // TODO Should be removed when we implement typing without starting write actions. + public TextAttributes getAttributes(DocumentImpl document, int offset, char c) { + final int segmentIndex; + try { + segmentIndex = mySegments.findSegmentIndex(offset) - 2; + } + catch (IndexOutOfBoundsException ex) { + throw new IndexOutOfBoundsException(ex.getMessage() + " Lexer: " + myLexer); + } + int startIndex = Math.max(0, segmentIndex); + + int data; + do { + data = mySegments.getSegmentData(startIndex); + if (isInitialState(data)|| startIndex == 0) break; + startIndex--; + } + while (true); + + int startOffset = mySegments.getSegmentStart(startIndex); + + ImmutableText newText = document.getImmutableText().insert(offset, Character.toString(c)); + + myLexer.start(newText, startOffset, newText.length(), myInitialState); + + IElementType tokenType = null; + while (myLexer.getTokenType() != null) { + if (myLexer.getTokenEnd() >= offset + 1) { + tokenType = myLexer.getTokenType(); + break; + } + myLexer.advance(); + } + + return getAttributes(tokenType); + } + protected TextAttributes convertAttributes(@NotNull TextAttributesKey[] keys) { TextAttributes attrs = myScheme.getAttributes(HighlighterColors.TEXT); for (TextAttributesKey key : keys) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index ac2f73eba5af..00e1ab150d1b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -44,8 +44,10 @@ import com.intellij.openapi.editor.colors.*; import com.intellij.openapi.editor.colors.impl.DelegateColorScheme; import com.intellij.openapi.editor.event.*; import com.intellij.openapi.editor.ex.*; +import com.intellij.openapi.editor.ex.util.EditorUIUtil; import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.editor.ex.util.EmptyEditorHighlighter; +import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter; import com.intellij.openapi.editor.highlighter.EditorHighlighter; import com.intellij.openapi.editor.highlighter.HighlighterClient; import com.intellij.openapi.editor.impl.event.MarkupModelListener; @@ -318,6 +320,16 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi private boolean myDocumentChangeInProgress; private boolean myErrorStripeNeedsRepaint; + // Characters that excluded from zero-latency painting after key typing + private static final Set KEY_CHARS_TO_SKIP = new HashSet(Arrays.asList('\n', '\t', '(', ')', '[', ']', '{', '}', '"', '\'')); + + // Characters that excluded from zero-latency painting after document update + private static final Set DOCUMENT_CHARS_TO_SKIP = new HashSet(Arrays.asList(')', ']', '}', '"', '\'')); + + private Rectangle myOldArea; + private Rectangle myOldTailArea; + private boolean myEventPaintedAsChar; + static { ourCaretBlinkingCommand.start(); } @@ -1135,6 +1147,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); DataContext dataContext = getDataContext(); + + if (isZeroLatencyTypingEnabled() && myDocument.isWritable() && !isViewer() && canPaintImmediately(c)) { + paintImmediately(myCaretModel.getOffset(), c); + myEventPaintedAsChar = true; + } + actionManager.fireBeforeEditorTyping(c, dataContext); MacUIUtil.hideCursor(); EditorActionManager.getInstance().getTypedAction().actionPerformed(this, c, dataContext); @@ -1881,12 +1899,31 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (!mySoftWrapModel.isSoftWrappingEnabled() && !myUseNewRendering) { mySizeContainer.beforeChange(e); } + + if (isZeroLatencyTypingEnabled() && !myEventPaintedAsChar && canPaintImmediately(e)) { + int offset = e.getOffset(); + int length = e.getOldLength(); + + myOldArea = lineRectangleBetween(offset, offset + length); + + myOldTailArea = lineRectangleBetween(offset + length, myDocument.getLineEndOffset(myDocument.getLineNumber(offset))); + if (myOldTailArea.isEmpty()) { + myOldTailArea.width += EditorUtil.getSpaceWidth(Font.PLAIN, this); // include possible caret + } + } } private void changedUpdate(DocumentEvent e) { myDocumentChangeInProgress = false; if (myDocument.isInBulkUpdate()) return; + if (isZeroLatencyTypingEnabled()) { + if (!myEventPaintedAsChar && canPaintImmediately(e)) { + paintImmediately(e); + } + myEventPaintedAsChar = false; + } + if (myErrorStripeNeedsRepaint) { myMarkupModel.repaint(e.getOffset(), e.getOffset() + e.getNewLength()); myErrorStripeNeedsRepaint = false; @@ -2100,6 +2137,135 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi putUserData(BUFFER, image); } + private static boolean isZeroLatencyTypingEnabled() { + return Registry.is("editor.zero.latency.typing"); + } + + private boolean canPaintImmediately(char c) { + return myDocument instanceof DocumentImpl && + myHighlighter instanceof LexerEditorHighlighter && + myDocument.getTextLength() > 0 && + myCaretModel.getCaretCount() == 1 && + !mySelectionModel.hasSelection() && + !KEY_CHARS_TO_SKIP.contains(c); + } + + // Called to display a single character insertion before starting a write action. + // Bypasses RepaintManager (c.repaint, c.paintComponent) and double buffering (g.paintImmediately) to minimize visual lag. + // TODO Should be replaced with the generic paintImmediately(event) call when we implement typing without starting write actions. + private void paintImmediately(int offset, char c) { + Graphics g = myEditorComponent.getGraphics(); + + TextAttributes attributes = ((LexerEditorHighlighter)myHighlighter).getAttributes((DocumentImpl)myDocument, offset, c); + + int fontType = attributes.getFontType(); + Font font = fontFor(fontType); + + int charWidth = g.getFontMetrics(font).charWidth(c); + + Rectangle tailArea = lineRectangleBetween(offset, myDocument.getLineEndOffset(offsetToLogicalLine(offset))); + if (tailArea.isEmpty()) { + tailArea.width += EditorUtil.getSpaceWidth(fontType, this); // include caret + } + + Color lineColor = myScheme.getColor(EditorColors.CARET_ROW_COLOR); + + Rectangle newArea = lineRectangleBetween(offset, offset); + newArea.width += charWidth; + + String newText = Character.toString(c); + Point point = newArea.getLocation(); + int ascent = getAscent(); + Color color = attributes.getForegroundColor(); + + EditorUIUtil.setupAntialiasing(g); + + // pre-compute all the arguments beforehand to minimize delays between the calls (as there's no double-buffering) + shift(g, tailArea, charWidth); + fill(g, newArea, lineColor); + print(g, newText, point, ascent, font, color); + } + + private static boolean canPaintImmediately(DocumentEvent e) { + return !contains(e.getOldFragment(), '\n') && + !contains(e.getNewFragment(), '\n') && + !(e.getNewLength() == 1 && DOCUMENT_CHARS_TO_SKIP.contains(e.getNewFragment().charAt(0))); + } + + private static boolean contains(CharSequence chars, char c) { + for (int i = 0; i < chars.length(); i++) { + if (chars.charAt(i) == c) { + return true; + } + } + return false; + } + + // Called to display insertion / deletion / replacement within a single line before the general paint routine. + // Bypasses RepaintManager (c.repaint, c.paintComponent) and double buffering (g.paintImmediately) to minimize visual lag. + private void paintImmediately(DocumentEvent e) { + int offset = e.getOffset(); + String newText = e.getNewFragment().toString(); + Rectangle newArea = lineRectangleBetween(offset, offset + newText.length()); + int delta = newArea.width - myOldArea.width; + Color lineColor = myScheme.getColor(EditorColors.CARET_ROW_COLOR); + + Graphics g = myEditorComponent.getGraphics(); + + if (delta != 0) { + shift(g, myOldTailArea, delta); + + if (delta < 0) { + Rectangle remainingArea = new Rectangle(myOldTailArea.x + myOldTailArea.width + delta, + myOldTailArea.y, -delta, myOldTailArea.height); + fill(g, remainingArea, lineColor); + } + } + + if (!newArea.isEmpty()) { + TextAttributes attributes = myHighlighter.createIterator(offset).getTextAttributes(); + + Point point = newArea.getLocation(); + int ascent = getAscent(); + Font font = fontFor(attributes.getFontType()); + Color color = attributes.getForegroundColor(); + + EditorUIUtil.setupAntialiasing(g); + + // pre-compute all the arguments beforehand to minimize delay between the calls (as there's no double-buffering) + fill(g, newArea, lineColor); + print(g, newText, point, ascent, font, color); + } + } + + @NotNull + private Rectangle lineRectangleBetween(int begin, int end) { + Point p1 = offsetToXY(begin, false); + Point p2 = offsetToXY(end, false); + LOG.assertTrue(p1.y == p2.y); + return new Rectangle(p1.x, p1.y, p2.x - p1.x, getLineHeight()); + } + + @NotNull + private Font fontFor(int fontType) { + return myScheme.getFont(EditorFontType.values()[fontType]); + } + + private static void shift(Graphics g, Rectangle r, int delta) { + g.copyArea(r.x, r.y, r.width, r.height, delta, 0); + } + + private static void fill(Graphics g, Rectangle r, Color color) { + g.setColor(color); + g.fillRect(r.x, r.y, r.width, r.height); + } + + private static void print(Graphics g, String text, Point point, int ascent, Font font, Color color) { + g.setFont(font); + g.setColor(color); + g.drawString(text, point.x, point.y + ascent); + } + void paint(@NotNull Graphics2D g) { Rectangle clip = g.getClipBounds(); diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 5affd420ca95..e2162b6da368 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -531,6 +531,9 @@ editor.disable.rtl.description=Disables RTL support in editor (all characters ar editor.new.rendering=false editor.new.rendering.description=Enables new editor rendering code, with support for RTL. +editor.zero.latency.typing=false +editor.zero.latency.typing.description=Display single-line changes immediately (before write action and general painting routine) + editor.enable.optional.ligatures=false editor.enable.optional.ligatures.description=Enables optional ligatures supported by font in use editor.enable.optional.ligatures.restartRequired=true From 2888027d4affd22bbaf9bba36d6e5ed390a7c0df Mon Sep 17 00:00:00 2001 From: Alexey Utkin Date: Tue, 11 Aug 2015 11:54:47 +0300 Subject: [PATCH 67/99] OC-6187 Formatter: 'Smart tab' option doesn't convert spaces to tabs correctly --- .../src/com/intellij/formatting/CoreFormatterUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/formatting/CoreFormatterUtil.java b/platform/lang-impl/src/com/intellij/formatting/CoreFormatterUtil.java index b9b8bbf3eb83..1af833a35194 100644 --- a/platform/lang-impl/src/com/intellij/formatting/CoreFormatterUtil.java +++ b/platform/lang-impl/src/com/intellij/formatting/CoreFormatterUtil.java @@ -248,7 +248,7 @@ public class CoreFormatterUtil { } if (indent.getType() == Indent.Type.LABEL) return new IndentData(options.LABEL_INDENT_SIZE); if (indent.getType() == Indent.Type.NONE) return new IndentData(0); - if (indent.getType() == Indent.Type.SPACES) return new IndentData(0, indent.getSpaces()); + if (indent.getType() == Indent.Type.SPACES) return new IndentData(indent.getSpaces(), 0); return new IndentData(options.INDENT_SIZE); } From 5560ebd965dc361a570bf5f099e044ce8653da40 Mon Sep 17 00:00:00 2001 From: Valentin Fondaratov Date: Fri, 7 Aug 2015 15:26:46 +0300 Subject: [PATCH 68/99] Let's make ParsingTestCase check light reparse consistency --- .../testFramework/ParsingTestCase.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/platform/testFramework/src/com/intellij/testFramework/ParsingTestCase.java b/platform/testFramework/src/com/intellij/testFramework/ParsingTestCase.java index 31b0cc5a1312..70ebc35c5aad 100644 --- a/platform/testFramework/src/com/intellij/testFramework/ParsingTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/ParsingTestCase.java @@ -31,23 +31,31 @@ import com.intellij.openapi.fileEditor.impl.LoadTextUtil; import com.intellij.openapi.fileTypes.FileTypeFactory; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.options.SchemesManagerFactory; +import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.impl.ProgressManagerImpl; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.pom.PomModel; +import com.intellij.pom.core.impl.PomModelImpl; +import com.intellij.pom.tree.TreeAspect; import com.intellij.psi.*; import com.intellij.psi.impl.DebugUtil; import com.intellij.psi.impl.PsiCachedValuesFactory; import com.intellij.psi.impl.PsiFileFactoryImpl; import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry; import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistryImpl; +import com.intellij.psi.impl.source.text.BlockSupportImpl; +import com.intellij.psi.impl.source.text.DiffLog; import com.intellij.psi.util.CachedValuesManager; import com.intellij.util.CachedValuesManagerImpl; import com.intellij.util.Function; import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.MessageBusFactory; +import junit.framework.TestCase; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.picocontainer.*; @@ -129,6 +137,11 @@ public abstract class ParsingTestCase extends PlatformLiteFixture { if (myDefinitions.length > 0) { configureFromParserDefinition(myDefinitions[0], myFileExt); } + + // That's for reparse routines + final PomModelImpl pomModel = new PomModelImpl(myProject); + myProject.registerService(PomModel.class, pomModel); + new TreeAspect(pomModel); } public void configureFromParserDefinition(ParserDefinition definition, String extension) { @@ -212,6 +225,7 @@ public abstract class ParsingTestCase extends PlatformLiteFixture { assertEquals("virtual file text mismatch", text, LoadTextUtil.loadText(myFile.getVirtualFile())); assertEquals("doc text mismatch", text, myFile.getViewProvider().getDocument().getText()); assertEquals("psi text mismatch", text, myFile.getText()); + ensureCorrectReparse(myFile); if (checkResult){ checkResult(name, myFile); } @@ -314,4 +328,15 @@ public abstract class ParsingTestCase extends PlatformLiteFixture { } }); } + + public static void ensureCorrectReparse(@NotNull final PsiFile file) { + final String psiToStringDefault = DebugUtil.psiToString(file, false, false); + + final String fileText = file.getText(); + final DiffLog diffLog = new BlockSupportImpl(file.getProject()).reparseRange( + file, TextRange.allOf(fileText), fileText, new EmptyProgressIndicator(), fileText); + diffLog.performActualPsiChange(file); + + TestCase.assertEquals(psiToStringDefault, DebugUtil.psiToString(file, false, false)); + } } From d6911ebc1843ae4f1224239ae5c8ff50135a3942 Mon Sep 17 00:00:00 2001 From: Valentin Fondaratov Date: Fri, 7 Aug 2015 15:31:40 +0300 Subject: [PATCH 69/99] Empty collapsed nodes should appear in light trees, too --- .../com/intellij/lang/impl/PsiBuilderImpl.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java index 9e9e4f60bbb8..630ea0b22119 100644 --- a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java +++ b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java @@ -1660,7 +1660,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { if (child instanceof StartMarker && ((StartMarker)child).myDoneMarker.myCollapse) { int lastIndex = ((StartMarker)child).myDoneMarker.myLexemeIndex; - insertLeaf(child.getTokenType(), marker.myBuilder, child.myLexemeIndex, lastIndex); + insertLeaf(child.getTokenType(), marker.myBuilder, child.myLexemeIndex, lastIndex, true); } else { ensureCapacity(); @@ -1710,17 +1710,25 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { private int insertLeaves(int curToken, int lastIdx, PsiBuilderImpl builder) { lastIdx = Math.min(lastIdx, builder.myLexemeCount); while (curToken < lastIdx) { - insertLeaf(builder.myLexTypes[curToken], builder, curToken, curToken + 1); + insertLeaf(builder.myLexTypes[curToken], builder, curToken, curToken + 1, false); curToken++; } return curToken; } - private void insertLeaf(@NotNull IElementType type, @NotNull PsiBuilderImpl builder, int startLexemeIndex, int endLexemeIndex) { + private void insertLeaf(@NotNull IElementType type, + @NotNull PsiBuilderImpl builder, + int startLexemeIndex, + int endLexemeIndex, + boolean forceInsertion) { final int start = builder.myLexStarts[startLexemeIndex]; final int end = builder.myLexStarts[endLexemeIndex]; - if (start > end || start == end && !(type instanceof ILeafElementType)) return; + /** Corresponding code for heavy tree is located in {@link com.intellij.lang.impl.PsiBuilderImpl#insertLeaves} + * and is applied only to plain lexemes */ + if (start > end || !forceInsertion && start == end && !(type instanceof ILeafElementType)) { + return; + } final Token lexeme; if (type instanceof ILightLazyParseableElementType) { From ee5166e2f5736a9c74d625265e2dc65819f4b888 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 11 Aug 2015 10:20:58 +0200 Subject: [PATCH 70/99] LaterInvocatorTest in community --- .../application/impl/LaterInvocatorTest.java | 559 ++++++++++++++++++ 1 file changed, 559 insertions(+) create mode 100644 platform/platform-tests/testSrc/com/intellij/openapi/application/impl/LaterInvocatorTest.java diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/LaterInvocatorTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/LaterInvocatorTest.java new file mode 100644 index 000000000000..7b72162a0903 --- /dev/null +++ b/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/LaterInvocatorTest.java @@ -0,0 +1,559 @@ +package com.intellij.openapi.application.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Conditions; +import com.intellij.testFramework.PlatformTestCase; +import com.intellij.testFramework.SkipInHeadlessEnvironment; +import com.intellij.testFramework.UsefulTestCase; +import com.intellij.util.ui.UIUtil; +import junit.framework.TestCase; + +import javax.swing.*; +import java.awt.*; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; + +@SuppressWarnings({"SSBasedInspection", "SynchronizeOnThis"}) +@SkipInHeadlessEnvironment +public class LaterInvocatorTest extends PlatformTestCase { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.application.impl.LaterInvokatorTest"); + + private final ArrayList myOrder = new ArrayList(); + + @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized") private Window myWindow1; + private Window myWindow2; + + private final Runnable LEAVE_MODAL = new Runnable() { + @Override + public void run() { + LaterInvocator.leaveModal(myWindow1); + } + public String toString() { + return "leave modal later"; + } + + }; + private final Runnable ENTER_MODAL = new Runnable() { + @Override + public void run() { + LaterInvocator.enterModal(myWindow1); + } + + public String toString() { + return "enter modal later"; + } + }; + + @Override + protected void setUp() throws Exception { + myWindow1 = new Frame() { + public String toString() { + return "Window1"; + } + }; + myWindow2 = new Frame() { + public String toString() { + return "Window2"; + } + }; + final Exception[] exception = {null}; + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + try { + LaterInvocatorTest.super.setUp(); + final Object[] modalEntities = LaterInvocator.getCurrentModalEntities(); + if (modalEntities.length > 0) { + LOG.error( + "Expect no modal entries. Probably some of the previous tests didn't left their entries. Top entry is: " + modalEntities[0]); + } + } + catch (Exception e) { + exception[0] = e; + } + } + }); + if (exception[0] != null) throw exception[0]; + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + TestCase.assertFalse("Can't run test", LaterInvocator.isInModalContext()); + } + }); + + flushSwingQueue(); + } + + @Override + protected void runBareRunnable(Runnable runnable) throws Throwable { + runnable.run(); + } + + @Override + protected void tearDown() throws Exception { + myOrder.clear(); + final boolean[] inModalState = {true}; + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + synchronized (inModalState) { + inModalState[0] = false; + } + } + }, ModalityState.NON_MODAL); + flushSwingQueue(); + flushSwingQueue(); + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + while (true) { + synchronized (inModalState) { + if (!inModalState[0]) break; + } + flushSwingQueue(); + synchronized (inModalState) { + if (inModalState[0] && LaterInvocator.isInModalContext()) LaterInvocator.leaveAllModals(); + } + } + } + }); + + final Exception[] exception = {null}; + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + try { + LaterInvocatorTest.super.tearDown(); + } + catch (Exception e) { + exception[0] = e; + } + } + + public String toString() { + return "super teardown"; + } + }); + if (exception[0] != null) throw exception[0]; + } + + public void testReorder() throws InterruptedException, InvocationTargetException { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + LaterInvocator.enterModal(myWindow1); + synchronized (LaterInvocatorTest.this) { + blockSwingThread(); + ApplicationManager.getApplication().invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); + SwingUtilities.invokeLater(ENTER_MODAL); + LaterInvocator.leaveModal(myWindow1); + SwingUtilities.invokeLater(LEAVE_MODAL); + ApplicationManager.getApplication().invokeLater(new MyRunnable("2"), ModalityState.NON_MODAL); + } + flushSwingQueue(); + checkOrder(2); + } + }); + } + + public void testTrueReorder() throws InvocationTargetException, InterruptedException { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + LaterInvocator.enterModal(myWindow1); + ApplicationManager.getApplication().invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); + SwingUtilities.invokeLater(ENTER_MODAL); + LaterInvocator.leaveModal(myWindow1); + SwingUtilities.invokeLater(LEAVE_MODAL); + ApplicationManager.getApplication().invokeLater(new MyRunnable("2"), ModalityState.NON_MODAL); + } + }); + flushSwingQueue(); + flushSwingQueue(); + checkOrder(2); + } + + public void testEverInvoked() throws InvocationTargetException, InterruptedException { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + LaterInvocator.enterModal(myWindow1); + ApplicationManager.getApplication().invokeLater(ENTER_MODAL, ModalityState.NON_MODAL); + ApplicationManager.getApplication().invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); + LaterInvocator.leaveModal(myWindow1); + flushSwingQueue(); + flushSwingQueue(); + checkOrder(0); + SwingUtilities.invokeLater(LEAVE_MODAL); + flushSwingQueue(); + flushSwingQueue(); + checkOrder(1); + } + }); + } + + public void testDoesNotInvokeWhenModal() throws InvocationTargetException, InterruptedException { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + LaterInvocator.enterModal(myWindow1); + + ApplicationManager.getApplication().invokeLater(ENTER_MODAL, ModalityState.NON_MODAL); + ApplicationManager.getApplication().invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); + LaterInvocator.leaveModal(myWindow1); + flushSwingQueue(); + checkOrder(0); + LaterInvocator.leaveModal(myWindow1); + flushSwingQueue(); + checkOrder(1); + } + }); + } + + public void testRunQueuedRunnablesOnLeavingModality() { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + LaterInvocator.invokeLater(ENTER_MODAL, ModalityState.NON_MODAL); + LaterInvocator.invokeLater(new MyRunnable("3"), ModalityState.NON_MODAL); + flushSwingQueue(); + checkOrder(0); + + final ModalityState modalityState = ModalityState.stateForComponent(myWindow1); + LaterInvocator.invokeLater(new MyRunnable("1") { + @Override + public void run() { + super.run(); + checkOrder(1); + LaterInvocator.invokeLater(new MyRunnable("2"), modalityState); + checkOrder(1); + LaterInvocator.leaveModal(myWindow1); + checkOrder(2); + } + }, modalityState); + flushSwingQueue(); // let "1" run + + flushSwingQueue(); // let "3" run + checkOrder(3); + } + }); + } + + public void testStress() throws Exception { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + int N = 1000; + //long start = System.currentTimeMillis(); + for (int i = 0; i < N; i++) { + /* + if (i % 10 == 0) { + long elapsed = System.currentTimeMillis() - start; + System.out.println("i = " + i+"; elapsed="+elapsed); + start = System.currentTimeMillis(); + } + */ + + //assertEquals(null, Toolkit.getDefaultToolkit().getSystemEventQueue().peekEvent()); + //assertEquals(null, LaterInvocator.dumpQueue()); + + UsefulTestCase.assertEmpty(LaterInvocator.getCurrentModalEntities()); + LaterInvocator.enterModal(myWindow2); + //some weird things like MyFireIdleRequest may still sneak in + //assertEquals(null, LaterInvocator.dumpQueue()); + TestCase.assertTrue(LaterInvocator.isInModalContext()); + TestCase.assertEquals(1, LaterInvocator.getCurrentModalEntities().length); + + LaterInvocator.invokeLater(new Runnable() { + @Override + public void run() { + TestCase.assertTrue(!LaterInvocator.isInModalContext()); + } + + public String toString() { + return "ass2"; + } + }, ModalityState.NON_MODAL); + LaterInvocator.invokeLater(ENTER_MODAL, ModalityState.NON_MODAL); + + LaterInvocator.invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); + + //some weird things like MyFireIdleRequest may still sneak in + //java.util.List dump = LaterInvocator.dumpQueue(); + //assertEquals(dump.toString(), 3, dump.size()); + + LaterInvocator.leaveModal(myWindow2); + flushSwingQueue(); + if (!LaterInvocator.isInModalContext()) { + //System.out.println("inv queue" + LaterInvocator.dumpQueue()); + TestCase.fail(); + } + + checkOrder(0); + + SwingUtilities.invokeLater(LEAVE_MODAL); + flushSwingQueue(); + TestCase.assertTrue(!LaterInvocator.isInModalContext()); + + checkOrder(1); + + + LaterInvocator.leaveAllModals(); + myOrder.clear(); + flushSwingQueue(); + } + } + }); + } + + + public void testOrderWithSwingInvokeLater2() throws InterruptedException, InvocationTargetException { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + LaterInvocator.enterModal(myWindow1); + synchronized (LaterInvocatorTest.this) { + blockSwingThread(); + ApplicationManager.getApplication().invokeLater(new MyRunnable("2"), ModalityState.NON_MODAL); + SwingUtilities.invokeLater(LEAVE_MODAL); + SwingUtilities.invokeLater(new MyRunnable("1")); + ApplicationManager.getApplication().invokeLater(new MyRunnable("3"), ModalityState.NON_MODAL); + } + flushSwingQueue(); + checkOrder(3); + } + }); + } + + public void testOrderWithSwingInvokeLater3() throws InterruptedException, InvocationTargetException { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + LaterInvocator.enterModal(myWindow1); + synchronized (LaterInvocatorTest.this) { + blockSwingThread(); + SwingUtilities.invokeLater(new MyRunnable("1")); + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().invokeLater(new MyRunnable("3"), ModalityState.NON_MODAL); + } + }, ModalityState.NON_MODAL); + SwingUtilities.invokeLater(LEAVE_MODAL); + ApplicationManager.getApplication().invokeLater(new MyRunnable("2"), ModalityState.NON_MODAL); + } + flushSwingQueue(); + checkOrder(3); + } + }); + } + + public void testExpired() throws Exception { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + final ArrayList consumed = new ArrayList(); + synchronized (LaterInvocatorTest.this) { + blockSwingThread(); + ApplicationManager.getApplication().getInvokator().invokeLater(new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().invokeLater(new MyRunnable("1") { + @Override + public void run() { + super.run(); + TestCase.fail("Should not be executed"); + } + }, Conditions.alwaysTrue()); + } + }, ModalityState.NON_MODAL).doWhenDone(new Runnable() { + @Override + public void run() { + consumed.add("1"); + } + }); + ApplicationManager.getApplication().getInvokator().invokeLater(new MyRunnable("2"), ModalityState.NON_MODAL) + .doWhenDone(new Runnable() { + @Override + public void run() { + consumed.add("2"); + } + }); + } + flushSwingQueue(); + + TestCase.assertEquals(consumed.toString(), 2, consumed.size()); + } + }); + } + + public void testOrderWithSwingInvokeLater4() throws InterruptedException, InvocationTargetException { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + SwingUtilities.invokeLater(ENTER_MODAL); + flushSwingQueue(); + synchronized (LaterInvocatorTest.this) { + blockSwingThread(); + SwingUtilities.invokeLater(new MyRunnable("1")); + ApplicationManager.getApplication().invokeLater(new MyRunnable("3"), ModalityState.NON_MODAL); + SwingUtilities.invokeLater(LEAVE_MODAL); + SwingUtilities.invokeLater(ENTER_MODAL); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + SwingUtilities.invokeLater(new MyRunnable("2")); + ApplicationManager.getApplication().invokeLater(new MyRunnable("5"), ModalityState.NON_MODAL); + } + }); + ApplicationManager.getApplication().invokeLater(new MyRunnable("4"), ModalityState.NON_MODAL); + } + flushSwingQueue(); + SwingUtilities.invokeLater(LEAVE_MODAL); + flushSwingQueue(); + checkOrder(5); + } + }); + } + + public void testDeadLock() throws InvocationTargetException, InterruptedException { + final Object lock = new Object(); + final boolean[] started = { false }; + final Thread thread = new Thread("later invokator test") { + @Override + public void run() { + synchronized (lock) { + started[0] = true; + ApplicationManager.getApplication().invokeLater(new MyRunnable("1"), ModalityState.NON_MODAL); + lock.notifyAll(); + } + } + }; + + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + synchronized (LaterInvocatorTest.this) { + blockSwingThread(); + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + thread.start(); + while (!started[0]) { + try { + //noinspection BusyWait + Thread.sleep(5); + } + catch (InterruptedException e) { + TestCase.fail(e.getMessage()); + } + } + synchronized (lock) { + checkOrder(0); + } + } + }, ModalityState.NON_MODAL); + } + flushSwingQueue(); + flushSwingQueue(); + checkOrder(1); + } + }); + } + + private static void flushSwingQueue() { + + try { + Thread.sleep(10); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + + if (SwingUtilities.isEventDispatchThread()) { + UIUtil.dispatchAllInvocationEvents(); + } + else { + UIUtil.pump(); + } + /* + final AtomicBoolean hasEventsInQueue = new AtomicBoolean(true); + while (hasEventsInQueue.get()) { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + hasEventsInQueue.set(Toolkit.getDefaultToolkit().getSystemEventQueue().peekEvent() != null); + } + }); + } + */ + + //some weird things like MyFireIdleRequest may still sneak in + //assertEquals(null, Toolkit.getDefaultToolkit().getSystemEventQueue().peekEvent()); + } + + private void blockSwingThread() { + SwingUtilities.invokeLater(new Lock(this)); + } + + private void checkOrder(int count) { + synchronized(myOrder) { + String order = printOrder(); + if (count != myOrder.size()) { + TestCase.fail(order + "Expected " + count + " items but was " + myOrder.size()); + } + for (int i = 1; i <= count; i++) + if (!String.valueOf(i).equals(myOrder.get(i - 1))) { + //System.out.println("Count: " + count); + TestCase.fail(order + "Bad order"); + } + } + } + + private String printOrder() { + StringBuilder out = new StringBuilder("Order: "); + for (String order : myOrder) { + out.append(order).append(" "); + } + out.append('\n'); + return out.toString(); + } + + private class MyRunnable implements Runnable { + private final String myId; + + public MyRunnable(String id) { + myId = id; + } + + @Override + public void run() { + //System.out.println("executed: " + myId); + synchronized(myOrder) { + myOrder.add(myId); + } + } + + public String toString() { + return "myrun " + myId; + } + } + + private static class Lock implements Runnable { + private final Object myLock; + + public Lock(Object lock) { + myLock = lock; + } + + @Override + public void run() { + //noinspection EmptySynchronizedStatement + synchronized (myLock) { + //System.out.print(""); + } + } + } +} From 989077fcc0130c142ac87bdf5e0fad702500dd89 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 11 Aug 2015 12:21:16 +0300 Subject: [PATCH 71/99] IDEA-CR-4237: perform actual commit in remembered modality state --- .../core/MockDocumentCommitProcessor.java | 8 +- .../psi/impl/DocumentCommitProcessor.java | 19 ++-- .../psi/impl/DocumentCommitThread.java | 26 +++--- .../psi/impl/PsiDocumentManagerBase.java | 3 +- .../psi/impl/PsiDocumentManagerImpl.java | 2 +- .../psi/impl/PsiDocumentManagerImplTest.java | 88 +++++++++++++++++++ 6 files changed, 125 insertions(+), 21 deletions(-) diff --git a/platform/core-impl/src/com/intellij/core/MockDocumentCommitProcessor.java b/platform/core-impl/src/com/intellij/core/MockDocumentCommitProcessor.java index 9a7ac2c4243b..e08fc7b9b1f0 100644 --- a/platform/core-impl/src/com/intellij/core/MockDocumentCommitProcessor.java +++ b/platform/core-impl/src/com/intellij/core/MockDocumentCommitProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -15,6 +15,7 @@ */ package com.intellij.core; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.psi.impl.DocumentCommitProcessor; @@ -30,6 +31,9 @@ class MockDocumentCommitProcessor extends DocumentCommitProcessor { } @Override - public void commitAsynchronously(@NotNull Project project, @NotNull Document document, @NonNls @NotNull Object reason) { + public void commitAsynchronously(@NotNull Project project, + @NotNull Document document, + @NonNls @NotNull Object reason, + @NotNull ModalityState currentModalityState) { } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java index de29abbbb4f1..49450a51519d 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java +++ b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java @@ -17,6 +17,7 @@ package com.intellij.psi.impl; import com.intellij.lang.ASTNode; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Attachment; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; @@ -51,28 +52,34 @@ public abstract class DocumentCommitProcessor { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.DocumentCommitThread"); public abstract void commitSynchronously(@NotNull Document document, @NotNull Project project); - public abstract void commitAsynchronously(@NotNull final Project project, @NotNull final Document document, @NonNls @NotNull Object reason); + public abstract void commitAsynchronously(@NotNull final Project project, + @NotNull final Document document, + @NonNls @NotNull Object reason, + @NotNull ModalityState currentModalityState); protected static class CommitTask { - @NotNull public final Document document; - @NotNull public final Project project; + @NotNull final Document document; + @NotNull final Project project; // when queued it's not started // when dequeued it's started // when failed it's canceled - @NotNull public final ProgressIndicator indicator; // progress to commit this doc under. - @NotNull public final Object reason; + @NotNull final ProgressIndicator indicator; // progress to commit this doc under. + @NotNull final Object reason; + @NotNull final ModalityState myCreationModalityState; private final CharSequence myLastCommittedText; public boolean removed; // task marked as removed, should be ignored. public CommitTask(@NotNull Document document, @NotNull Project project, @NotNull ProgressIndicator indicator, - @NotNull Object reason) { + @NotNull Object reason, + @NotNull ModalityState currentModalityState) { this.document = document; this.project = project; this.indicator = indicator; this.reason = reason; + myCreationModalityState = currentModalityState; myLastCommittedText = PsiDocumentManager.getInstance(project).getLastCommittedText(document); } diff --git a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java index 004ed153776d..c753bf72ccb3 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java +++ b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java @@ -157,24 +157,30 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run } @Override - public void commitAsynchronously(@NotNull final Project project, @NotNull final Document document, @NonNls @NotNull Object reason) { - queueCommit(project, document, reason); + public void commitAsynchronously(@NotNull final Project project, + @NotNull final Document document, + @NonNls @NotNull Object reason, + @NotNull ModalityState currentModalityState) { + queueCommit(project, document, reason, currentModalityState); } - void queueCommit(@NotNull final Project project, @NotNull final Document document, @NonNls @NotNull Object reason) { + void queueCommit(@NotNull final Project project, + @NotNull final Document document, + @NonNls @NotNull Object reason, + @NotNull ModalityState currentModalityState) { assert !isDisposed : "already disposed"; if (!project.isInitialized()) return; PsiFile psiFile = PsiDocumentManager.getInstance(project).getCachedPsiFile(document); if (psiFile == null) return; - doQueue(project, document, reason); + doQueue(project, document, reason, currentModalityState); } - private void doQueue(@NotNull Project project, @NotNull Document document, @NotNull Object reason) { + private void doQueue(@NotNull Project project, @NotNull Document document, @NotNull Object reason, @NotNull ModalityState currentModalityState) { synchronized (documentsToCommit) { ProgressIndicator indicator = createProgressIndicator(); - CommitTask newTask = new CommitTask(document, project, indicator, reason); + CommitTask newTask = new CommitTask(document, project, indicator, reason, currentModalityState); markRemovedFromDocsToCommit(newTask); markRemovedCurrentTask(newTask); @@ -358,7 +364,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run if (success) { assert !myApplication.isDispatchThread(); - myApplication.invokeLater(finishRunnable, ModalityState.NON_MODAL); + myApplication.invokeLater(finishRunnable, task.myCreationModalityState); log("Invoked later finishRunnable", task, false, finishRunnable, indicator); } } @@ -379,7 +385,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run synchronized (documentsToCommit) { if (!success && !task.removed) { // sync commit has not intervened // reset status for queue back successfully - doQueue(project, document, "re-added on failure"); + doQueue(project, document, "re-added on failure", task.myCreationModalityState); } currentTask = null; // do not cancel, it's being invokeLatered } @@ -402,7 +408,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run } ProgressIndicator indicator = createProgressIndicator(); - CommitTask task = new CommitTask(document, project, indicator, "Sync commit"); + CommitTask task = new CommitTask(document, project, indicator, "Sync commit", ModalityState.any()); synchronized (documentsToCommit) { markRemovedFromDocsToCommit(task); markRemovedCurrentTask(task); @@ -529,7 +535,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run } if (!success) { // add document back to the queue - queueCommit(project, document, "Re-added back"); + queueCommit(project, document, "Re-added back", task.myCreationModalityState); } } }; diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java index 619d8137771a..f71e1cea8983 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java @@ -42,7 +42,6 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl; import com.intellij.psi.impl.source.PsiFileImpl; -import com.intellij.psi.impl.source.text.BlockSupportImpl; import com.intellij.psi.text.BlockSupport; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.*; @@ -716,7 +715,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen commitDocument(document); } else if (!((DocumentEx)document).isInBulkUpdate() && myPerformBackgroundCommit) { - myDocumentCommitProcessor.commitAsynchronously(myProject, document, event); + myDocumentCommitProcessor.commitAsynchronously(myProject, document, event, ApplicationManager.getApplication().getCurrentModalityState()); } } else { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java index f69bd2974ae4..198d50920a5c 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java @@ -79,7 +79,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManagerBase implements Se busConnection.subscribe(DocumentBulkUpdateListener.TOPIC, new DocumentBulkUpdateListener.Adapter() { @Override public void updateFinished(@NotNull Document doc) { - documentCommitThread.queueCommit(project, doc, "Bulk update finished"); + documentCommitThread.queueCommit(project, doc, "Bulk update finished", ApplicationManager.getApplication().getCurrentModalityState()); } }); } diff --git a/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java b/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java index 71bdbf819ce2..647a7f2fe29d 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java +++ b/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java @@ -19,6 +19,10 @@ import com.intellij.diagnostic.ThreadDumper; import com.intellij.ide.impl.ProjectUtil; import com.intellij.mock.MockDocument; import com.intellij.mock.MockPsiFile; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.impl.LaterInvocator; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.impl.DocumentImpl; @@ -26,6 +30,7 @@ import com.intellij.openapi.editor.impl.event.DocumentEventImpl; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.ThrowableComputable; import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.text.StringUtil; @@ -41,7 +46,9 @@ import com.intellij.testFramework.PlatformTestUtil; import com.intellij.util.Processor; import com.intellij.util.concurrency.Semaphore; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.io.File; import java.io.IOException; import java.util.concurrent.atomic.AtomicInteger; @@ -60,6 +67,16 @@ public class PsiDocumentManagerImplTest extends PlatformTestCase { UIUtil.dispatchAllInvocationEvents(); } + @Override + protected void tearDown() throws Exception { + Object[] entities = LaterInvocator.getCurrentModalEntities(); + for (int i = entities.length - 1; i >= 0; i--) { + Object state = entities[i]; + LaterInvocator.leaveModal(state); + } + super.tearDown(); + } + public void testGetCachedPsiFile_NoFile() throws Exception { final PsiFile file = getPsiDocumentManager().getCachedPsiFile(new MockDocument()); assertNull(file); @@ -471,4 +488,75 @@ public class PsiDocumentManagerImplTest extends PlatformTestCase { } }); } + + public void testCommitDocumentInModalDialog() throws IOException { + VirtualFile vFile = getVirtualFile(createTempFile("a.txt", "abc")); + PsiFile psiFile = getPsiManager().findFile(vFile); + final Document document = getPsiDocumentManager().getDocument(psiFile); + + final DialogWrapper dialog = new DialogWrapper(getProject()) { + @Nullable + @Override + protected JComponent createCenterPanel() { + return null; + } + }; + + disposeOnTearDown(new Disposable() { + @Override + public void dispose() { + dialog.close(DialogWrapper.OK_EXIT_CODE); + } + }); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + // commit thread is paused + document.setText("xx"); + + LaterInvocator.enterModal(dialog); + } + }); + assertNotSame(ModalityState.NON_MODAL, ApplicationManager.getApplication().getCurrentModalityState()); + + long start = System.currentTimeMillis(); + while (System.currentTimeMillis() - start < 10000) { + UIUtil.dispatchAllInvocationEvents(); + // must not be committed until exit modal dialog + assertFalse(getPsiDocumentManager().isCommitted(document)); + } + LaterInvocator.leaveModal(dialog); + assertEquals(ModalityState.NON_MODAL, ApplicationManager.getApplication().getCurrentModalityState()); + + start = System.currentTimeMillis(); + + // must committ + while (System.currentTimeMillis() - start < 10000 && !getPsiDocumentManager().isCommitted(document)) { + UIUtil.dispatchAllInvocationEvents(); + } + + assertTrue(getPsiDocumentManager().isCommitted(document)); + + + + // check that inside modal dialog commit is possible + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + // commit thread is paused + + LaterInvocator.enterModal(dialog); + document.setText("yyy"); + } + }); + assertNotSame(ModalityState.NON_MODAL, ApplicationManager.getApplication().getCurrentModalityState()); + + // must committ + while (System.currentTimeMillis() - start < 10000 && !getPsiDocumentManager().isCommitted(document)) { + UIUtil.dispatchAllInvocationEvents(); + } + + assertTrue(getPsiDocumentManager().isCommitted(document)); + LaterInvocator.leaveModal(dialog); + } } From 6b1158b829f58fd992e093821449b0ea3cc03a8d Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 11 Aug 2015 13:09:35 +0300 Subject: [PATCH 72/99] IDEA-143619 Quick Documentation (Ctrl-Q) for Java only shows "Fetching Documentation" - added debug logging --- .../codeInsight/documentation/DocumentationManager.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java index 4d9741996d4a..ead031227ea7 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java @@ -712,6 +712,7 @@ public class DocumentationManager extends DockablePopupManager() { @Override @@ -745,6 +748,7 @@ public class DocumentationManager extends DockablePopupManager Date: Tue, 11 Aug 2015 12:47:08 +0200 Subject: [PATCH 73/99] IDEA-143690 Project view of non-Java IDEs is not refreshed when directory moved --- .../com/intellij/psi/impl/PsiManagerImpl.java | 4 + .../psi/impl/PsiModificationTrackerImpl.java | 3 +- ...ficationTrackerTreeChangesUpdatesTest.java | 81 +++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 platform/platform-tests/testSrc/com/intellij/psi/PsiModificationTrackerTreeChangesUpdatesTest.java diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/PsiManagerImpl.java index 37148091656e..2c304dec8f5a 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiManagerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiManagerImpl.java @@ -374,6 +374,10 @@ public class PsiManagerImpl extends PsiManagerEx { myTreeChangePreprocessors.add(preprocessor); } + public void removeTreeChangePreprocessor(@NotNull PsiTreeChangePreprocessor preprocessor) { + myTreeChangePreprocessors.remove(preprocessor); + } + private void fireEvent(@NotNull PsiTreeChangeEventImpl event) { boolean isRealTreeChange = event.getCode() != PsiTreeChangeEventImpl.PsiEventType.PROPERTY_CHANGED && event.getCode() != PsiTreeChangeEventImpl.PsiEventType.BEFORE_PROPERTY_CHANGE; diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java index f4d79f7370fd..3ab8b34f4311 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java @@ -77,7 +77,8 @@ public class PsiModificationTrackerImpl implements PsiModificationTracker, PsiTr @Override public void treeChanged(@NotNull PsiTreeChangeEventImpl event) { myModificationCount.getAndIncrement(); - if (event.getParent() instanceof PsiDirectory) { + if (event.getParent() instanceof PsiDirectory + || event.getOldParent() instanceof PsiDirectory /* move events */) { myOutOfCodeBlockModificationCount.getAndIncrement(); } diff --git a/platform/platform-tests/testSrc/com/intellij/psi/PsiModificationTrackerTreeChangesUpdatesTest.java b/platform/platform-tests/testSrc/com/intellij/psi/PsiModificationTrackerTreeChangesUpdatesTest.java new file mode 100644 index 000000000000..af1eb62b4973 --- /dev/null +++ b/platform/platform-tests/testSrc/com/intellij/psi/PsiModificationTrackerTreeChangesUpdatesTest.java @@ -0,0 +1,81 @@ +/* + * Copyright 2000-2015 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.psi; + +import com.intellij.openapi.application.Result; +import com.intellij.openapi.application.WriteAction; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.PsiModificationTrackerImpl; +import com.intellij.testFramework.PlatformTestCase; +import org.jetbrains.annotations.NotNull; + +public class PsiModificationTrackerTreeChangesUpdatesTest extends PlatformTestCase { + private PsiModificationTrackerImpl myTracker; + + @Override + public void setUp() throws Exception { + super.setUp(); + // since we want to test PsiModificationTrackerImpl in isolation, we create a separate instance: + // The existing PsiModificationTrackerImpl is affected by various components. + myTracker = new PsiModificationTrackerImpl(getProject()); + ((PsiManagerImpl)PsiManager.getInstance(getProject())).addTreeChangePreprocessor(myTracker); + } + + @Override + public void tearDown() throws Exception { + ((PsiManagerImpl)PsiManager.getInstance(getProject())).removeTreeChangePreprocessor(myTracker); + super.tearDown(); + } + + public void testMoveFile() throws Exception { + new WriteAction() { + @Override + protected void run(@NotNull Result result) throws Throwable { + final VirtualFile dir1 = getProject().getBaseDir().createChildDirectory(this, "dir1"); + final VirtualFile dir2 = getProject().getBaseDir().createChildDirectory(this, "dir2"); + VirtualFile child = dir1.createChildData(this, "child"); + + long outOfCodeBlockCount = myTracker.getOutOfCodeBlockModificationCount(); + child.move(this, dir2); + assertFalse(myTracker.getOutOfCodeBlockModificationCount() == outOfCodeBlockCount); + + outOfCodeBlockCount = myTracker.getOutOfCodeBlockModificationCount(); + child.move(this, dir1); + assertFalse(myTracker.getOutOfCodeBlockModificationCount() == outOfCodeBlockCount); + } + }.execute(); + } + + public void testMoveDir() throws Exception { + new WriteAction() { + @Override + protected void run(@NotNull Result result) throws Throwable { + final VirtualFile dir1 = getProject().getBaseDir().createChildDirectory(this, "dir1"); + final VirtualFile dir2 = getProject().getBaseDir().createChildDirectory(this, "dir2"); + VirtualFile child = dir1.createChildDirectory(this, "child"); + + long outOfCodeBlockCount = myTracker.getOutOfCodeBlockModificationCount(); + child.move(this, dir2); + assertFalse(myTracker.getOutOfCodeBlockModificationCount() == outOfCodeBlockCount); + + outOfCodeBlockCount = myTracker.getOutOfCodeBlockModificationCount(); + child.move(this, dir1); + assertFalse(myTracker.getOutOfCodeBlockModificationCount() == outOfCodeBlockCount); + } + }.execute(); + } +} From af74f9fc2073899a369553553982e8ee4333910d Mon Sep 17 00:00:00 2001 From: Sergey Savenko Date: Tue, 11 Aug 2015 14:05:56 +0300 Subject: [PATCH 74/99] Do not extract and execute startup scripts when running unit tests --- .../src/com/intellij/ide/script/IdeStartupScripts.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java b/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java index 3d6c8aeaba9f..7b8d8a2053e3 100644 --- a/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java +++ b/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java @@ -17,6 +17,7 @@ package com.intellij.ide.script; import com.intellij.ide.extensionResources.ExtensionsRootType; import com.intellij.ide.plugins.PluginManagerCore; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.PluginId; @@ -57,6 +58,10 @@ class IdeStartupScripts extends ApplicationComponent.Adapter { @Override public void initComponent() { + if (ApplicationManager.getApplication().isUnitTestMode()) { + return; + } + List scripts = getScripts(); if (scripts.isEmpty()) { LOG.debug("No startup scripts detected"); From a7d1e0d33a9c7a55d720ab3386b8ab8594a82ced Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Tue, 11 Aug 2015 12:04:18 +0300 Subject: [PATCH 75/99] Addded "iter" postfix template working like "for" one to be consistent with live templates --- .../template/postfix/templates/ForeachPostfixTemplate.java | 4 ++-- .../postfix/templates/JavaPostfixTemplateProvider.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForeachPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForeachPostfixTemplate.java index 72404efa582f..7daeb5e3e1ca 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForeachPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForeachPostfixTemplate.java @@ -28,8 +28,8 @@ import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplate import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorTopmost; public class ForeachPostfixTemplate extends StringBasedPostfixTemplate { - public ForeachPostfixTemplate() { - super("for", "for (T item : expr)", selectorTopmost(IS_ITERABLE_OR_ARRAY)); + public ForeachPostfixTemplate(String name) { + super(name, "for (T item : expr)", selectorTopmost(IS_ITERABLE_OR_ARRAY)); } @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java index 7f21ad2bfcca..dbfe90d7a27f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java @@ -42,7 +42,8 @@ public class JavaPostfixTemplateProvider implements PostfixTemplateProvider { new ElseStatementPostfixTemplate(), new ForAscendingPostfixTemplate(), new ForDescendingPostfixTemplate(), - new ForeachPostfixTemplate(), + new ForeachPostfixTemplate("iter"), + new ForeachPostfixTemplate("for"), new FormatPostfixTemplate(), new IfStatementPostfixTemplate(), new InstanceofExpressionPostfixTemplate(), From 29b0da34521a5f95fbcac4354ada1842054863e8 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Tue, 11 Aug 2015 12:06:23 +0300 Subject: [PATCH 76/99] Refactoring to track what code is throwing NPE --- .../DetectedIndentOptionsNotificationProvider.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/DetectedIndentOptionsNotificationProvider.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/DetectedIndentOptionsNotificationProvider.java index f8a8915f3159..a1e7a3788ceb 100644 --- a/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/DetectedIndentOptionsNotificationProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/DetectedIndentOptionsNotificationProvider.java @@ -116,12 +116,14 @@ public class DetectedIndentOptionsNotificationProvider extends EditorNotificatio if (!ApplicationManager.getApplication().isHeadlessEnvironment() || ApplicationManager.getApplication().isUnitTestMode() && myShowNotificationInTest) { - FileEditor fileEditor = FileEditorManager.getInstance(file.getProject()).getSelectedEditor(vFile); + Project project = file.getProject(); + FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); + FileEditor fileEditor = fileEditorManager.getSelectedEditor(vFile); if (fileEditor != null) { Boolean notifiedFlag = fileEditor.getUserData(NOTIFIED_FLAG); if (notifiedFlag == null || enforce) { fileEditor.putUserData(NOTIFIED_FLAG, Boolean.TRUE); - EditorNotifications.getInstance(file.getProject()).updateNotifications(vFile); + EditorNotifications.getInstance(project).updateNotifications(vFile); } } } From 8eea8eb13fcd59fae8bad365554abdeff47b606e Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Tue, 11 Aug 2015 14:31:30 +0300 Subject: [PATCH 77/99] Do not reformat parent code block on "complete current statement" action (IDEA-102479) --- .../smartEnter/JavaSmartEnterProcessor.java | 8 +------- .../completeStatement/AddMissingParen_after.java | 3 +-- .../completeStatement/AddMissingSemicolon_after.java | 3 +-- .../completeStatement/IncompleteElseIf_after.java | 1 - .../codeInsight/completeStatement/NoBlockReformat.java | 9 +++++++++ .../completeStatement/NoBlockReformat_after.java | 9 +++++++++ .../com/intellij/codeInsight/CompleteStatementTest.java | 2 ++ 7 files changed, 23 insertions(+), 12 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completeStatement/NoBlockReformat.java create mode 100644 java/java-tests/testData/codeInsight/completeStatement/NoBlockReformat_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java index a5b28cb663bd..7915984fa253 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java @@ -189,13 +189,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor { return; } PsiElement parent = atCaret.getParent(); - if (parent instanceof PsiCodeBlock) { - final PsiCodeBlock block = (PsiCodeBlock) parent; - if (block.getStatements().length > 0 && block.getStatements()[0] == atCaret) { - atCaret = block; - } - } - else if (parent instanceof PsiForStatement) { + if (parent instanceof PsiForStatement) { atCaret = parent; } diff --git a/java/java-tests/testData/codeInsight/completeStatement/AddMissingParen_after.java b/java/java-tests/testData/codeInsight/completeStatement/AddMissingParen_after.java index 3cf8eb4381a0..37db1a8c03f9 100644 --- a/java/java-tests/testData/codeInsight/completeStatement/AddMissingParen_after.java +++ b/java/java-tests/testData/codeInsight/completeStatement/AddMissingParen_after.java @@ -1,8 +1,7 @@ class Foo { abstract void a(); - { - a(); + a(); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completeStatement/AddMissingSemicolon_after.java b/java/java-tests/testData/codeInsight/completeStatement/AddMissingSemicolon_after.java index 3cf8eb4381a0..37db1a8c03f9 100644 --- a/java/java-tests/testData/codeInsight/completeStatement/AddMissingSemicolon_after.java +++ b/java/java-tests/testData/codeInsight/completeStatement/AddMissingSemicolon_after.java @@ -1,8 +1,7 @@ class Foo { abstract void a(); - { - a(); + a(); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completeStatement/IncompleteElseIf_after.java b/java/java-tests/testData/codeInsight/completeStatement/IncompleteElseIf_after.java index eb6478527b9c..5950c16978b5 100644 --- a/java/java-tests/testData/codeInsight/completeStatement/IncompleteElseIf_after.java +++ b/java/java-tests/testData/codeInsight/completeStatement/IncompleteElseIf_after.java @@ -1,6 +1,5 @@ class Foo { boolean a; - { if (a) { } else { diff --git a/java/java-tests/testData/codeInsight/completeStatement/NoBlockReformat.java b/java/java-tests/testData/codeInsight/completeStatement/NoBlockReformat.java new file mode 100644 index 000000000000..cea4b2e627c4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completeStatement/NoBlockReformat.java @@ -0,0 +1,9 @@ +public class Test { + public void foo(int x) { + int a = 2 + + System.out.println(""); + System.out.println(""); + System.out.println(""); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completeStatement/NoBlockReformat_after.java b/java/java-tests/testData/codeInsight/completeStatement/NoBlockReformat_after.java new file mode 100644 index 000000000000..12eca8780923 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completeStatement/NoBlockReformat_after.java @@ -0,0 +1,9 @@ +public class Test { + public void foo(int x) { + int a = 2; + + System.out.println(""); + System.out.println(""); + System.out.println(""); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java index 5741767274c8..d0a25d0bc7b2 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java @@ -67,6 +67,8 @@ public class CompleteStatementTest extends EditorActionTestCase { } } + public void testNoBlockReformat() { doTest(); } + public void testCompleteCatchWithExpression() throws Exception { doTest(); } public void testCompleteCatchBody() throws Exception { doTest(); } From 695553d76db49d343f0ef1de200cac8e4db03703 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Tue, 11 Aug 2015 14:17:57 +0300 Subject: [PATCH 78/99] fix escaping for chars in (127, 255] --- .../src/com/intellij/xml/actions/EscapeEntitiesAction.java | 2 +- .../editorActions/EscapeEntitiesActionTest.java | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/xml/impl/src/com/intellij/xml/actions/EscapeEntitiesAction.java b/xml/impl/src/com/intellij/xml/actions/EscapeEntitiesAction.java index 4dccfddd38de..9c275e856634 100644 --- a/xml/impl/src/com/intellij/xml/actions/EscapeEntitiesAction.java +++ b/xml/impl/src/com/intellij/xml/actions/EscapeEntitiesAction.java @@ -79,7 +79,7 @@ public class EscapeEntitiesAction extends SimpleCodeInsightAction { char c = text.charAt(i); final PsiElement element = file.findElementAt(start + i); if (element != null && isCharacterElement(element)) { - if (c == '<' || c == '>' || c == '&' || c == '"' || c == '\'' || c > 0xff) { + if (c == '<' || c == '>' || c == '&' || c == '"' || c == '\'' || c > 0x7f) { final String escape = ESCAPES.getValue(file).get(c); if (escape != null) { result.append("&").append(escape).append(";"); diff --git a/xml/tests/src/com/intellij/codeInsight/editorActions/EscapeEntitiesActionTest.java b/xml/tests/src/com/intellij/codeInsight/editorActions/EscapeEntitiesActionTest.java index 9cd5a3cdb71b..e7b6bfb52453 100644 --- a/xml/tests/src/com/intellij/codeInsight/editorActions/EscapeEntitiesActionTest.java +++ b/xml/tests/src/com/intellij/codeInsight/editorActions/EscapeEntitiesActionTest.java @@ -23,6 +23,7 @@ import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; */ public class EscapeEntitiesActionTest extends LightCodeInsightFixtureTestCase { private static final String NDASH = new String(new byte[]{-30, -128, -109}, CharsetToolkit.UTF8_CHARSET); + private static final String COPY = new String(new byte[]{-62, -82}, CharsetToolkit.UTF8_CHARSET); public void testSimpleHtml() { doTest("<<<", "html", "<<<"); @@ -32,10 +33,14 @@ public class EscapeEntitiesActionTest extends LightCodeInsightFixtureTestCase { doTest(">>>", "xml", ">>>"); } - public void testWide() { + public void testVeryWide() { doTest(NDASH, "html", "–"); } + public void testWide() { + doTest(COPY, "html", "®"); + } + public void testAttributeValue() { doTest("", "html", ""); } From 8d45af895f01bd1f15bd1fd223e4dc0b10ebfe0b Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Tue, 11 Aug 2015 14:51:40 +0300 Subject: [PATCH 79/99] perform test with explicit UTF8 --- .../EscapeEntitiesActionTest.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/xml/tests/src/com/intellij/codeInsight/editorActions/EscapeEntitiesActionTest.java b/xml/tests/src/com/intellij/codeInsight/editorActions/EscapeEntitiesActionTest.java index e7b6bfb52453..e6691070ec8d 100644 --- a/xml/tests/src/com/intellij/codeInsight/editorActions/EscapeEntitiesActionTest.java +++ b/xml/tests/src/com/intellij/codeInsight/editorActions/EscapeEntitiesActionTest.java @@ -16,6 +16,7 @@ package com.intellij.codeInsight.editorActions; import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; /** @@ -62,12 +63,15 @@ public class EscapeEntitiesActionTest extends LightCodeInsightFixtureTestCase { "<\n"); } - private void doTest(String text, String extension, String expected) { - if (!text.contains("")) { - text = "" + text + ""; - } - myFixture.configureByText(getTestName(true) + "." + extension, text); - myFixture.performEditorAction("EscapeEntities"); - myFixture.checkResult(expected); + private void doTest(String text, final String extension, final String expected) { + final String finalText = !text.contains("") ? "" + text + "" : text; + PlatformTestUtil.withEncoding("UTF8", new Runnable() { + @Override + public void run() { + myFixture.configureByText(getTestName(true) + "." + extension, finalText); + myFixture.performEditorAction("EscapeEntities"); + myFixture.checkResult(expected); + } + }); } } From f1049564f01a39127a8a5a79063d3fc5012d56d2 Mon Sep 17 00:00:00 2001 From: Pavel Fatin Date: Tue, 11 Aug 2015 13:53:30 +0200 Subject: [PATCH 80/99] Zero-latency typing: prevent possible NPEs --- .../openapi/editor/impl/DocumentImpl.java | 2 +- .../openapi/editor/impl/EditorImpl.java | 29 +++++++++++-------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java index aba7f6cd0568..a92586c8e110 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java @@ -805,7 +805,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { } // Breaks encapsulation, yet required for current zero-latency typing implementation. - // TODO Sould be removed when we implement typing without starting write actions. + // TODO Should be removed when we implement typing without starting write actions. @NotNull public ImmutableText getImmutableText() { return myText; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 00e1ab150d1b..386fee97fe53 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -326,8 +326,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi // Characters that excluded from zero-latency painting after document update private static final Set DOCUMENT_CHARS_TO_SKIP = new HashSet(Arrays.asList(')', ']', '}', '"', '\'')); - private Rectangle myOldArea; - private Rectangle myOldTailArea; + private Rectangle myOldArea = new Rectangle(0, 0, 0, 0); + private Rectangle myOldTailArea = new Rectangle(0, 0, 0, 0); private boolean myEventPaintedAsChar; static { @@ -2150,12 +2150,14 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi !KEY_CHARS_TO_SKIP.contains(c); } - // Called to display a single character insertion before starting a write action. + // Called to display a single character insertion before starting a write action and the general painting routine. // Bypasses RepaintManager (c.repaint, c.paintComponent) and double buffering (g.paintImmediately) to minimize visual lag. // TODO Should be replaced with the generic paintImmediately(event) call when we implement typing without starting write actions. private void paintImmediately(int offset, char c) { Graphics g = myEditorComponent.getGraphics(); + if (g == null) return; // editor component is currently not displayable + TextAttributes attributes = ((LexerEditorHighlighter)myHighlighter).getAttributes((DocumentImpl)myDocument, offset, c); int fontType = attributes.getFontType(); @@ -2186,13 +2188,13 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi print(g, newText, point, ascent, font, color); } - private static boolean canPaintImmediately(DocumentEvent e) { + private static boolean canPaintImmediately(@NotNull DocumentEvent e) { return !contains(e.getOldFragment(), '\n') && !contains(e.getNewFragment(), '\n') && !(e.getNewLength() == 1 && DOCUMENT_CHARS_TO_SKIP.contains(e.getNewFragment().charAt(0))); } - private static boolean contains(CharSequence chars, char c) { + private static boolean contains(@NotNull CharSequence chars, char c) { for (int i = 0; i < chars.length(); i++) { if (chars.charAt(i) == c) { return true; @@ -2201,17 +2203,19 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi return false; } - // Called to display insertion / deletion / replacement within a single line before the general paint routine. + // Called to display insertion / deletion / replacement within a single line before the general painting routine. // Bypasses RepaintManager (c.repaint, c.paintComponent) and double buffering (g.paintImmediately) to minimize visual lag. - private void paintImmediately(DocumentEvent e) { + private void paintImmediately(@NotNull DocumentEvent e) { + Graphics g = myEditorComponent.getGraphics(); + + if (g == null) return; // editor component is currently not displayable + int offset = e.getOffset(); String newText = e.getNewFragment().toString(); Rectangle newArea = lineRectangleBetween(offset, offset + newText.length()); int delta = newArea.width - myOldArea.width; Color lineColor = myScheme.getColor(EditorColors.CARET_ROW_COLOR); - Graphics g = myEditorComponent.getGraphics(); - if (delta != 0) { shift(g, myOldTailArea, delta); @@ -2251,16 +2255,17 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi return myScheme.getFont(EditorFontType.values()[fontType]); } - private static void shift(Graphics g, Rectangle r, int delta) { + private static void shift(@NotNull Graphics g, @NotNull Rectangle r, int delta) { g.copyArea(r.x, r.y, r.width, r.height, delta, 0); } - private static void fill(Graphics g, Rectangle r, Color color) { + private static void fill(@NotNull Graphics g, @NotNull Rectangle r, @NotNull Color color) { g.setColor(color); g.fillRect(r.x, r.y, r.width, r.height); } - private static void print(Graphics g, String text, Point point, int ascent, Font font, Color color) { + private static void print(@NotNull Graphics g, @NotNull String text, @NotNull Point point, + int ascent, @NotNull Font font, @NotNull Color color) { g.setFont(font); g.setColor(color); g.drawString(text, point.x, point.y + ascent); From 464818c24d3040b1198c42d9152a22569a9ae228 Mon Sep 17 00:00:00 2001 From: Pavel Fatin Date: Tue, 11 Aug 2015 15:18:34 +0200 Subject: [PATCH 81/99] Zero-latency typing: handle absent caret row background correctly --- .../com/intellij/openapi/editor/impl/EditorImpl.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 386fee97fe53..0cbe383b83e5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -2170,7 +2170,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi tailArea.width += EditorUtil.getSpaceWidth(fontType, this); // include caret } - Color lineColor = myScheme.getColor(EditorColors.CARET_ROW_COLOR); + Color lineColor = getCaretRowBackground(); Rectangle newArea = lineRectangleBetween(offset, offset); newArea.width += charWidth; @@ -2214,7 +2214,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi String newText = e.getNewFragment().toString(); Rectangle newArea = lineRectangleBetween(offset, offset + newText.length()); int delta = newArea.width - myOldArea.width; - Color lineColor = myScheme.getColor(EditorColors.CARET_ROW_COLOR); + Color lineColor = getCaretRowBackground(); if (delta != 0) { shift(g, myOldTailArea, delta); @@ -2250,6 +2250,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi return new Rectangle(p1.x, p1.y, p2.x - p1.x, getLineHeight()); } + @NotNull + private Color getCaretRowBackground() { + Color color = myScheme.getColor(EditorColors.CARET_ROW_COLOR); + return color == null ? myScheme.getDefaultBackground() : color; + } + @NotNull private Font fontFor(int fontType) { return myScheme.getFont(EditorFontType.values()[fontType]); From 836aff8fb292b57c4b727309bf57b0b86b754dba Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 11 Aug 2015 15:20:01 +0200 Subject: [PATCH 82/99] proper pty4j library name (IDEA-143758) --- lib/required_for_dist.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/required_for_dist.txt b/lib/required_for_dist.txt index e061ec282a91..a014761aea97 100644 --- a/lib/required_for_dist.txt +++ b/lib/required_for_dist.txt @@ -55,7 +55,7 @@ oromatcher.jar picocontainer.jar protobuf-2.5.0.jar proxy-vole_20131209.jar -pty4j-0.4.17.jar +pty4j-0.4.18.jar purejavacomm.jar resolver.jar rhino-js-1_7R4.jar From b8a185b33562019703f651916892863f082ef443 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 11 Aug 2015 15:29:56 +0200 Subject: [PATCH 83/99] Added following plugin versions as incompatible: - com.jetbrains.plugins.meteor 142.2481 - org.intellij.scala 1.7.4, 1.7.2, 1.6.2, 1.6.1 - Pythonid 4.1, 142.176 v4.5 - org.jetbrains.plugins.ruby 8.0.0.20150624 8.0.0.20150616 - NodeJS 142.3224 142.2650 --- platform/platform-resources/src/brokenPlugins.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/platform/platform-resources/src/brokenPlugins.txt b/platform/platform-resources/src/brokenPlugins.txt index 42907a5adba7..2f8d7013f0b5 100644 --- a/platform/platform-resources/src/brokenPlugins.txt +++ b/platform/platform-resources/src/brokenPlugins.txt @@ -1,14 +1,14 @@ // This file contains list of broken plugins. // Each line contains plugin ID and list of versions that are broken. // If plugin name or version contains a space you can quote it like in command line. -NodeJS 142.2492 142.2481 142.2064 141.1108 140.2045 140.1669 140.642 139.173 139.105 139.496 139.1 139.8 138.2196 138.2254 138.1684 138.1744 138.1879 138.2051 138.1367 138.1495 138.1189 138.1145 138.937 138.1013 138.921 138.447 138.172 138.317 138.21 138.35 138.96 138.85 136.1205 134.1276 134.1163 134.1145 134.1081 134.1039 134.985 134.680 134.31 134.307 134.262 134.198 134.125 136.1141 +NodeJS 142.3224 142.2650 142.2492 142.2481 142.2064 141.1108 140.2045 140.1669 140.642 139.173 139.105 139.496 139.1 139.8 138.2196 138.2254 138.1684 138.1744 138.1879 138.2051 138.1367 138.1495 138.1189 138.1145 138.937 138.1013 138.921 138.447 138.172 138.317 138.21 138.35 138.96 138.85 136.1205 134.1276 134.1163 134.1145 134.1081 134.1039 134.985 134.680 134.31 134.307 134.262 134.198 134.125 136.1141 com.jetbrains.php 140.2765 141.332 139.732 139.659 139.496 139.173 139.105 138.2502 138.2000.2262 138.1751 138.1806 138.1505 138.1161 138.826 136.1768 136.1672 134.1456 133.982 133.679 133.51 133.326 131.98 131.374 131.332 131.235 131.205 130.1639 130.1481 130.1176 129.91 129.814 129.672 129.362 127.67 127.100 126.334 123.66 122.875 121.62 121.390 121.215 121.12 com.jetbrains.lang.ejs 131.17 131.12 com.jetbrains.twig 133.51 130.1639 -org.jetbrains.plugins.ruby 7.0.0.20150216 7.0.0.20150204 7.0.0.20141010 7.0.0.20140915 7.0.0.20140901 7.0.0.20140807 6.0.0.20140207 6.5.2.20140512 7.0.0.20140704 7.0.0.20140707 7.0.0.20140724 -Pythonid "4.1 141.4 EAP" 3.1 4.0.25 4.0.26 +org.jetbrains.plugins.ruby 8.0.0.20150624 8.0.0.20150616 7.0.0.20150216 7.0.0.20150204 7.0.0.20141010 7.0.0.20140915 7.0.0.20140901 7.0.0.20140807 6.0.0.20140207 6.5.2.20140512 7.0.0.20140704 7.0.0.20140707 7.0.0.20140724 +Pythonid "142.176 v4.5" 4.1 "4.1 141.4 EAP" 3.1 4.0.25 4.0.26 Karma 140.2109 138.1684 138.1879 138.317 138.21 134.1163 134.1039 134.686 134.31 -org.intellij.scala 1.6.0 1.2.67.3.EAP 1.3.2-14.1 1.3.3-14.1 1.0.93.10.EAP 1.0.93.4.EAP 1.0.93.9.EAP 1.0.58 1.0.16 1.0.14 1.0.13 0.42.28 0.42.23 0.40.20 0.40.18 0.40.16 0.32.593 0.32.562 0.32.558 0.32.550 0.32.520 0.32.512 +org.intellij.scala 1.7.4 1.7.2 1.6.2 1.6.1 1.6.0 1.2.67.3.EAP 1.3.2-14.1 1.3.3-14.1 1.0.93.10.EAP 1.0.93.4.EAP 1.0.93.9.EAP 1.0.58 1.0.16 1.0.14 1.0.13 0.42.28 0.42.23 0.40.20 0.40.18 0.40.16 0.32.593 0.32.562 0.32.558 0.32.550 0.32.520 0.32.512 org.jetbrains.kannotator 0.2.420 org.jetbrains.kotlin 0.10.555 0.10.4 0.8.1615 0.7.1360 0.7.1376 0.8.7 SBT 1.0.0 1.1.0 1.2.0 1.3.0 1.3.1 1.4.0 1.5.0 1.5.1 1.6.0 1.6.1 @@ -28,4 +28,5 @@ AWSCloudFormation 0.3.9 com.jetbrains.typoscript 0.1.1 0.1.0 Dart 133.239 133.432 133.726 130.1494 130.549 131.17 132.1045 132.207 132.835 130.1494 131.17 0.5.1 IdeaVIM 0.15.59 0.16.60 0.20.75 0.20.80 0.21.86 0.22.90 0.23.111 0.23.115 0.23.93 0.24-148 0.25 0.26 0.27 0.28 0.29 0.30 0.31 0.32 0.33 0.34 0.35 0.36 0.37 0.38 0.39 -IDETalk 0.5 0.5.1 0.5.2 0.5.3 0.5.5 0.5.6 0.5.6.1 0.5.6.2 0.5.4 0.1.2 0.1.1 141.177.4 \ No newline at end of file +IDETalk 0.5 0.5.1 0.5.2 0.5.3 0.5.5 0.5.6 0.5.6.1 0.5.6.2 0.5.4 0.1.2 0.1.1 141.177.4 +com.jetbrains.plugins.meteor 142.2481 \ No newline at end of file From b9698fefdb399116e17774d945893a756860f304 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 11 Aug 2015 16:29:47 +0300 Subject: [PATCH 84/99] run context menu: keep executors at the top --- .../src/com/intellij/execution/ExecutorRegistryImpl.java | 2 +- platform/platform-resources/src/idea/LangActions.xml | 4 +++- plugins/devkit/resources/META-INF/plugin.xml | 5 +---- plugins/junit/src/META-INF/plugin.xml | 2 +- resources/src/idea/RichPlatformActions.xml | 6 +----- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java b/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java index 2e1bf628e5bf..e479c5c94a25 100644 --- a/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java @@ -47,7 +47,7 @@ public class ExecutorRegistryImpl extends ExecutorRegistry { private static final Logger LOG = Logger.getInstance(ExecutorRegistryImpl.class); @NonNls public static final String RUNNERS_GROUP = "RunnerActions"; - @NonNls public static final String RUN_CONTEXT_GROUP = "RunContextGroup"; + @NonNls public static final String RUN_CONTEXT_GROUP = "RunContextGroupInner"; private List myExecutors = new ArrayList(); private ActionManager myActionManager; diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index 1f043ec05433..2589cbd4903e 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -12,6 +12,9 @@ + + + @@ -849,7 +852,6 @@ - diff --git a/plugins/devkit/resources/META-INF/plugin.xml b/plugins/devkit/resources/META-INF/plugin.xml index 131ebeddc940..1730a1cef508 100644 --- a/plugins/devkit/resources/META-INF/plugin.xml +++ b/plugins/devkit/resources/META-INF/plugin.xml @@ -209,14 +209,11 @@ + - - - - diff --git a/plugins/junit/src/META-INF/plugin.xml b/plugins/junit/src/META-INF/plugin.xml index a80c2bde3994..52e8d652e22f 100644 --- a/plugins/junit/src/META-INF/plugin.xml +++ b/plugins/junit/src/META-INF/plugin.xml @@ -78,7 +78,7 @@ - + diff --git a/resources/src/idea/RichPlatformActions.xml b/resources/src/idea/RichPlatformActions.xml index ab2573813a96..4c82664c9e6f 100644 --- a/resources/src/idea/RichPlatformActions.xml +++ b/resources/src/idea/RichPlatformActions.xml @@ -341,11 +341,7 @@ - - - - - + From 540bc1da2765b403f48cc0df331137334520522b Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 11 Aug 2015 15:19:12 +0200 Subject: [PATCH 85/99] IDEA-143741 GroovyPositionManager#locationsOfLine too eager --- .../jetbrains/plugins/groovy/debugger/GroovyPositionManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java index f1b1d1d5d6af..f86495fa97d3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java @@ -72,6 +72,7 @@ public class GroovyPositionManager implements PositionManager { @Override @NotNull public List locationsOfLine(@NotNull ReferenceType type, @NotNull SourcePosition position) throws NoDataException { + checkGroovyFile(position); try { if (LOG.isDebugEnabled()) { LOG.debug("locationsOfLine: " + type + "; " + position); From 1bda9a4e62c57ec387715d03d61520fd4d32e2e1 Mon Sep 17 00:00:00 2001 From: Alexey Utkin Date: Tue, 11 Aug 2015 16:30:32 +0300 Subject: [PATCH 86/99] CPP-4184 Remove code duplication. --- .../EnterAfterUnmatchedBraceHandler.java | 111 +++++++++++++----- 1 file changed, 81 insertions(+), 30 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java index dd2899548bc3..17abf8bf0c45 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterUnmatchedBraceHandler.java @@ -31,6 +31,7 @@ import com.intellij.openapi.editor.highlighter.EditorHighlighter; import com.intellij.openapi.editor.highlighter.HighlighterIterator; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; @@ -57,15 +58,32 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter final EditorActionHandler originalHandler) { int caretOffset = caretOffsetRef.get(); + if (!isApplicable(file, caretOffset)) { + return Result.Continue; + } + int maxRBraceCount = getMaxRBraceCount(file, editor, caretOffset); - if (maxRBraceCount > 0 && insertRBraces(file, editor, caretOffset, - getRBraceOffset(file, editor, caretOffset), - adjustRBraceCountForPosition(editor, caretOffset, maxRBraceCount))) { + if (maxRBraceCount > 0) { + insertRBraces(file, editor, + caretOffset, + getRBraceOffset(file, editor, caretOffset), + adjustRBraceCountForPosition(editor, caretOffset, maxRBraceCount)); return Result.DefaultForceIndent; } return Result.Continue; } + /** + * Checks that the text context is in responsibility of the handler. + * + * @param file target PSI file + * @param caretOffset target caret offset + * @return true, if handler is in charge + */ + public boolean isApplicable(@NotNull PsiFile file, int caretOffset) { + return true; + } + /** * Calculates the maximum number of '}' that can be inserted by handler. * Can return 0 or less in custom implementation to skip '}' insertion in the preprocessEnter call @@ -84,10 +102,10 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter } /** - * Calculates the precise number of '}' that have be inserted by handler. + * Calculates the precise number of '}' that have to be inserted by handler. * - * @param editor target editor - * @param caretOffset target caret offset + * @param editor target editor + * @param caretOffset target caret offset * @param maxRBraceCount the maximum number of '}' for insert at position, it always positive * @return number of '}' that has to be inserted by handler, it has to positive */ @@ -96,23 +114,29 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter CharSequence text = editor.getDocument().getCharsSequence(); int bracesToInsert = 0; - outer: for (int i = caretOffset - 1; i >= 0 && bracesToInsert < maxRBraceCount; --i) { - switch (text.charAt(i)) { - case ' ': - case '\n': - case '\t': - continue; - case '{': - bracesToInsert++; - break; - default: - break outer; + final char c = text.charAt(i); + if (c == '{') { + ++bracesToInsert; + } + else if (isStopChar(c)) { + break; } } return Math.max(bracesToInsert, 1); } + /** + * Checks the character before the inserted '}' to reduce the count of inserted '}'. + * The number of inserted '}' will increase for each found '{'. + * + * @param c character to check + * @return true, to stop back iteration + */ + protected boolean isStopChar(char c) { + return " \n\t".indexOf(c) < 0; + } + /** * Calculates the position for insertion of one or more '}'. * @@ -126,7 +150,7 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter int offset = CharArrayUtil.shiftForward(text, caretOffset, " \t"); final int fileLength = text.length(); if (offset < fileLength && ")];,%rBracesCount of '}' at the rBracesInsertOffset position. + * + * @param document target document + * @param caretOffset target caret offset + * @param rBracesInsertOffset target position to insert + * @param rBracesCount count of '}' to insert + */ + protected void insertRBracesAtPosition(Document document, int caretOffset, int rBracesInsertOffset, int rBracesCount) { document.insertString(rBracesInsertOffset, "\n" + StringUtil.repeatSymbol('}', rBracesCount)); // We need to adjust indents of the text that will be moved, hence, need to insert preliminary line feed. // Example: @@ -165,7 +201,22 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter // to 'if' code block('{}')). So, we insert temporary line feed between 'if' and 'else', correct indent and remove that temporary // line feed. document.insertString(caretOffset, "\n"); + } + /** + * Formats the code block between caret and inserted braces. + * + * @param file target PSI file + * @param document target document + * @param caretOffset target caret offset + * @param rBracesInsertOffset target position to insert + * @param rBracesCount count of '}' to insert + */ + protected void formatCodeFragmentBetweenBraces(@NotNull PsiFile file, + @NotNull Document document, + int caretOffset, + int rBracesInsertOffset, + int rBracesCount) { Project project = file.getProject(); long stamp = document.getModificationStamp(); boolean closingBraceIndentAdjusted; @@ -178,6 +229,7 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter } finally { closingBraceIndentAdjusted = stamp != document.getModificationStamp(); + // do you remember that we insert the '\n'? here we take it back! document.deleteString(caretOffset, caretOffset + 1); } @@ -202,7 +254,6 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter document.insertString(rBracesInsertOffset + 1, buffer); } } - return true; } /** @@ -235,13 +286,13 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter * @param file target PSI file * @param text text from the given file * @param offset target offset where line feed will be inserted - * @return offset to use for inserting closing brace + * @return pair of (element, offset). The element is the '}' owner, if applicable; the offset is the position for inserting closing brace */ - protected int calculateOffsetToInsertClosingBrace(PsiFile file, CharSequence text, final int offset) { + protected Pair calculateOffsetToInsertClosingBrace(@NotNull PsiFile file, @NotNull CharSequence text, final int offset) { PsiElement element = PsiUtilCore.getElementAtOffset(file, offset); ASTNode node = element.getNode(); if (node != null && node.getElementType() == TokenType.WHITE_SPACE) { - return CharArrayUtil.shiftForwardUntil(text, offset, "\n"); + return Pair.create(null, CharArrayUtil.shiftForwardUntil(text, offset, "\n")); } for (PsiElement parent = element.getParent(); parent != null; parent = parent.getParent()) { ASTNode parentNode = parent.getNode(); @@ -251,9 +302,9 @@ public class EnterAfterUnmatchedBraceHandler extends EnterHandlerDelegateAdapter element = parent; } if (element.getTextOffset() != offset) { - return CharArrayUtil.shiftForwardUntil(text, offset, "\n"); + return Pair.create(null, CharArrayUtil.shiftForwardUntil(text, offset, "\n")); } - return element.getTextRange().getEndOffset(); + return Pair.create(element, element.getTextRange().getEndOffset()); } public static boolean isAfterUnmatchedLBrace(Editor editor, int offset, FileType fileType) { From c7dfe22f31ca925e61c31cc6e2aaf463c4fd17e2 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 11 Aug 2015 06:00:37 -0700 Subject: [PATCH 87/99] extract method: enable duplicates inside inner classes called methods from outer (IDEA-143504) --- .../util/duplicates/DuplicatesFinder.java | 11 ++++++---- .../DuplicatesFromAnonymous.java | 16 +++++++++++++++ .../DuplicatesFromAnonymous_after.java | 20 +++++++++++++++++++ .../refactoring/ExtractMethodTest.java | 4 ++++ 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/refactoring/extractMethod/DuplicatesFromAnonymous.java create mode 100644 java/java-tests/testData/refactoring/extractMethod/DuplicatesFromAnonymous_after.java diff --git a/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java b/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java index cc65ad2184c5..c34982debacf 100644 --- a/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java +++ b/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java @@ -376,10 +376,13 @@ public class DuplicatesFinder { final PsiClass patternClass = RefactoringChangeUtil.getThisClass(pattern); final PsiClass candidateClass = RefactoringChangeUtil.getThisClass(candidate); if (resolveResult1 == resolveResult2 && - resolveResult1 instanceof PsiMember && - !InheritanceUtil.isInheritorOrSelf(candidateClass, patternClass, true) && - InheritanceUtil.isInheritorOrSelf(candidateClass, ((PsiMember)resolveResult1).getContainingClass(), true)) { - return false; + resolveResult1 instanceof PsiMember) { + final PsiClass containingClass = ((PsiMember)resolveResult1).getContainingClass(); + if (!InheritanceUtil.isInheritorOrSelf(candidateClass, patternClass, true) && + InheritanceUtil.isInheritorOrSelf(candidateClass, containingClass, true) && + InheritanceUtil.isInheritorOrSelf(patternClass, containingClass, true)) { + return false; + } } } diff --git a/java/java-tests/testData/refactoring/extractMethod/DuplicatesFromAnonymous.java b/java/java-tests/testData/refactoring/extractMethod/DuplicatesFromAnonymous.java new file mode 100644 index 000000000000..bc0df8f53d7d --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/DuplicatesFromAnonymous.java @@ -0,0 +1,16 @@ +import java.util.*; + +class Main { + + private final Map> myScheduledUpdates = null; + + void foo() { + new Runnable() { + @Override + public void run() { + myScheduledUpdates.keySet().toArray(new Object[myScheduledUpdates.keySet().size()]); + } + }; + myScheduledUpdates.keySet().toArray(new Object[myScheduledUpdates.keySet().size()]); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/DuplicatesFromAnonymous_after.java b/java/java-tests/testData/refactoring/extractMethod/DuplicatesFromAnonymous_after.java new file mode 100644 index 000000000000..e6de04ac5a6c --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/DuplicatesFromAnonymous_after.java @@ -0,0 +1,20 @@ +import java.util.*; + +class Main { + + private final Map> myScheduledUpdates = null; + + void foo() { + new Runnable() { + @Override + public void run() { + newMethod(); + } + }; + newMethod(); + } + + private Object[] newMethod() { + return myScheduledUpdates.keySet().toArray(new Object[myScheduledUpdates.keySet().size()]); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java index 47a038460eb7..ba1d6b03ed9f 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java @@ -225,6 +225,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase { doDuplicatesTest(); } + public void testDuplicatesFromAnonymous() throws Exception { + doDuplicatesTest(); + } + public void testCodeDuplicatesWithContinueNoReturn() throws Exception { doDuplicatesTest(); } From 24c7193e08d464f862427cb15ded74db7a32a3f3 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 11 Aug 2015 06:12:35 -0700 Subject: [PATCH 88/99] javadoc (coverage moved to community) --- platform/lang-api/src/com/intellij/execution/Executor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-api/src/com/intellij/execution/Executor.java b/platform/lang-api/src/com/intellij/execution/Executor.java index e803e85b6bcc..3275cbd51125 100644 --- a/platform/lang-api/src/com/intellij/execution/Executor.java +++ b/platform/lang-api/src/com/intellij/execution/Executor.java @@ -25,7 +25,7 @@ import javax.swing.*; /** * Describes a specific way of executing any possible run configuration. The three default executors provided by the IntelliJ Platform - * by default are Run, Debug and (in IntelliJ IDEA Ultimate and certain platform-based IDEs) Run with Coverage. Each executor gets its + * by default are Run, Debug and Run with Coverage. Each executor gets its * own toolbar button, which starts the selected run configuration using this executor, and its own context menu item for starting * a configuration using this executor. * From 41dc3567a6a25520aa1a091ab62f675111cebbea Mon Sep 17 00:00:00 2001 From: Liana Bakradze Date: Tue, 11 Aug 2015 16:48:09 +0300 Subject: [PATCH 89/99] added ability to create lessons in the middle of course (part of EDU-331) --- .../coursecreator/PyCCProjectGenerator.java | 8 +- .../course-creator/course-creator.iml | 1 + .../coursecreator/CCFileDeletedListener.java | 4 +- .../jetbrains/edu/coursecreator/CCUtils.java | 75 +++++--- .../coursecreator/actions/CCCreateLesson.java | 171 +++++++++--------- .../ui/CCCreateStudyItemDialog.java | 33 ++++ .../ui/CCCreateStudyItemPanel.form | 42 +++++ .../ui/CCCreateStudyItemPanel.java | 33 ++++ .../coursecreator/ui/CCItemPositionPanel.form | 37 ++++ .../coursecreator/ui/CCItemPositionPanel.java | 30 +++ .../src/com/jetbrains/edu/EduNames.java | 2 + .../src/com/jetbrains/edu/EduUtils.java | 17 +- 12 files changed, 338 insertions(+), 115 deletions(-) create mode 100644 python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateStudyItemDialog.java create mode 100644 python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateStudyItemPanel.form create mode 100644 python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateStudyItemPanel.java create mode 100644 python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCItemPositionPanel.form create mode 100644 python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCItemPositionPanel.java diff --git a/python/edu/course-creator-python/src/com/jetbrains/edu/coursecreator/PyCCProjectGenerator.java b/python/edu/course-creator-python/src/com/jetbrains/edu/coursecreator/PyCCProjectGenerator.java index 1f82439e6ca3..3b8c4154f24b 100644 --- a/python/edu/course-creator-python/src/com/jetbrains/edu/coursecreator/PyCCProjectGenerator.java +++ b/python/edu/course-creator-python/src/com/jetbrains/edu/coursecreator/PyCCProjectGenerator.java @@ -8,6 +8,7 @@ import com.intellij.ide.fileTemplates.FileTemplateManager; import com.intellij.ide.fileTemplates.FileTemplateUtil; import com.intellij.ide.util.DirectoryUtil; import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; @@ -30,6 +31,7 @@ import javax.swing.*; public class PyCCProjectGenerator extends PythonProjectGenerator implements DirectoryProjectGenerator { + private static final Logger LOG = Logger.getInstance(PyCCProjectGenerator.class); private CCNewProjectPanel mySettingsPanel; @Nls @@ -83,7 +85,11 @@ public class PyCCProjectGenerator extends PythonProjectGenerator implements Dire catch (Exception ignored) { } DirectoryUtil.createSubdirectories(EduNames.HINTS, projectDir, "\\/"); - final PsiDirectory lessonDir = CCCreateLesson.createLessonDir(project, 1, null, null); + PsiDirectory lessonDir = CCCreateLesson.createLesson(null, project, baseDir, course); + if (lessonDir == null) { + LOG.error("Failed to create lesson"); + return; + } CCCreateTask.createTask(null, project, lessonDir, false); } }.execute(); diff --git a/python/educational/course-creator/course-creator.iml b/python/educational/course-creator/course-creator.iml index b54f05e2bd7e..46da5de45628 100644 --- a/python/educational/course-creator/course-creator.iml +++ b/python/educational/course-creator/course-creator.iml @@ -12,5 +12,6 @@ + \ No newline at end of file diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCFileDeletedListener.java b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCFileDeletedListener.java index 095cc44746b1..a28b44709bae 100644 --- a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCFileDeletedListener.java +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCFileDeletedListener.java @@ -55,7 +55,7 @@ class CCFileDeletedListener extends VirtualFileAdapter { public StudyOrderable fun(VirtualFile file) { return course.getLesson(file.getName()); } - }, removedLesson, EduNames.LESSON); + }, removedLesson.getIndex(), EduNames.LESSON, -1); course.getLessons().remove(removedLesson); } @@ -77,7 +77,7 @@ class CCFileDeletedListener extends VirtualFileAdapter { public StudyOrderable fun(VirtualFile file) { return lesson.getTask(file.getName()); } - }, task, EduNames.TASK); + }, task.getIndex(), EduNames.TASK, -1); ModifiableRootModel model = EduUtils.getModel(lessonDir, project); if (model == null) { return; diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCUtils.java b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCUtils.java index aaaccb4939c8..9148afad4a32 100644 --- a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCUtils.java +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCUtils.java @@ -1,5 +1,7 @@ package com.jetbrains.edu.coursecreator; +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; import com.intellij.lang.Language; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -7,12 +9,14 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.util.Function; +import com.jetbrains.edu.EduUtils; import com.jetbrains.edu.courseFormat.Course; import com.jetbrains.edu.courseFormat.StudyOrderable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.util.*; public class CCUtils { private static final Logger LOG = Logger.getInstance(CCUtils.class); @@ -20,7 +24,7 @@ public class CCUtils { @Nullable public static CCLanguageManager getStudyLanguageManager(@NotNull final Course course) { Language language = Language.findLanguageByID(course.getLanguage()); - return language == null ? null : CCLanguageManager.INSTANCE.forLanguage(language); + return language == null ? null : CCLanguageManager.INSTANCE.forLanguage(language); } public static boolean isAnswerFile(PsiElement element) { @@ -34,37 +38,54 @@ public class CCUtils { /** * This method decreases index and updates directory names of * all tasks/lessons that have higher index than specified object - * @param dirs directories that are used to get tasks/lessons + * + * @param dirs directories that are used to get tasks/lessons * @param getStudyOrderable function that is used to get task/lesson from VirtualFile. This function can return null - * @param thresholdObject task/lesson which index is used as threshold - * @param prefix task or lesson directory name prefix + * @param threshold index is used as threshold + * @param prefix task or lesson directory name prefix */ public static void updateHigherElements(VirtualFile[] dirs, - @NotNull Function getStudyOrderable, - @NotNull final StudyOrderable thresholdObject, - final String prefix) { - int threshold = thresholdObject.getIndex(); - for (final VirtualFile dir : dirs) { - final StudyOrderable orderable = getStudyOrderable.fun(dir); - if (orderable == null) { - continue; - } - int index = orderable.getIndex(); - if (index > threshold) { - final int newIndex = index - 1; - orderable.setIndex(newIndex); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - try { - dir.rename(this, prefix + newIndex); - } - catch (IOException e) { - LOG.error(e); - } + @NotNull final Function getStudyOrderable, + final int threshold, + final String prefix, + final int delta) { + ArrayList dirsToRename = new ArrayList + (Collections2.filter(Arrays.asList(dirs), new Predicate() { + @Override + public boolean apply(VirtualFile dir) { + final StudyOrderable orderable = getStudyOrderable.fun(dir); + if (orderable == null) { + return false; } - }); + int index = orderable.getIndex(); + return index > threshold; + } + })); + Collections.sort(dirsToRename, new Comparator() { + @Override + public int compare(VirtualFile o1, VirtualFile o2) { + StudyOrderable orderable1 = getStudyOrderable.fun(o1); + StudyOrderable orderable2 = getStudyOrderable.fun(o2); + //if we delete some dir we should start increasing numbers in dir names from the end + return (-delta) * EduUtils.INDEX_COMPARATOR.compare(orderable1, orderable2); } + }); + + for (final VirtualFile dir : dirsToRename) { + final StudyOrderable orderable = getStudyOrderable.fun(dir); + final int newIndex = orderable.getIndex() + delta; + orderable.setIndex(newIndex); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + try { + dir.rename(this, prefix + newIndex); + } + catch (IOException e) { + LOG.error(e); + } + } + }); } } } diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateLesson.java b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateLesson.java index a305acffeaf6..7259d34afa80 100644 --- a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateLesson.java +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateLesson.java @@ -7,30 +7,33 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiManager; +import com.intellij.util.Function; import com.intellij.util.PlatformIcons; import com.jetbrains.edu.EduNames; import com.jetbrains.edu.EduUtils; import com.jetbrains.edu.courseFormat.Course; import com.jetbrains.edu.courseFormat.Lesson; +import com.jetbrains.edu.courseFormat.StudyOrderable; import com.jetbrains.edu.coursecreator.CCProjectService; +import com.jetbrains.edu.coursecreator.CCUtils; +import com.jetbrains.edu.coursecreator.ui.CCCreateStudyItemDialog; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; -import java.util.List; +import java.util.Collections; public class CCCreateLesson extends DumbAwareAction { - private static final Logger LOG = Logger.getInstance(CCCreateLesson.class.getName()); + public static final String TITLE = "Create New " + EduNames.LESSON_TITLED; public CCCreateLesson() { - super("Lesson", "Create new Lesson", PlatformIcons.DIRECTORY_CLOSED_ICON); + super(EduNames.LESSON_TITLED, TITLE, PlatformIcons.DIRECTORY_CLOSED_ICON); } @Override @@ -47,85 +50,87 @@ public class CCCreateLesson extends DumbAwareAction { if (course == null) { return; } - //"Create Lesson" invoked from project root creates new lesson as last lesson - if (directory.getVirtualFile().equals(project.getBaseDir())) { - final int size = course.getLessons().size(); - createLesson(project, size + 1, view); - return; - } - //"Create Lesson" invoked from any of lesson directories creates new lesson as next lesson - Lesson lesson = course.getLesson(directory.getName()); - if (lesson != null) { - int index = lesson.getIndex(); - List lessons = course.getLessons(); - int lessonNum = lessons.size(); - for (int i = lessonNum; i >= index + 1; i--) { - updateLesson(project, EduNames.LESSON, i); - } - final PsiDirectory parent = directory.getParent(); - if (parent == null) { - return; - } - createLesson(project, index + 1, view); - } - } - - private static void createLesson(@NotNull final Project project, - final int index, - final IdeView view) { - final String lessonName = Messages.showInputDialog("Name:", "Lesson Name", null, EduNames.LESSON + index, null); - if (lessonName == null) { - return; - } - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - createLessonDir(project, index, lessonName, view); - } - }); - } - - private void updateLesson(@NotNull final Project project, final String lessonDirName, int i) { - final VirtualFile lessonDir = project.getBaseDir().findChild(lessonDirName + i); - if (lessonDir == null) { - return; - } - final CCProjectService service = CCProjectService.getInstance(project); - Lesson l = service.getCourse().getLesson(lessonDir.getName()); - if (l == null) { - return; - } - l.setIndex(l.getIndex() + 1); - final int next = i + 1; - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - try { - lessonDir.rename(this, lessonDirName + next); - } - catch (IOException e1) { - LOG.error(e1); - } - } - }); + createLesson(view, project, directory.getVirtualFile(), course); } @Nullable - public static PsiDirectory createLessonDir(@NotNull final Project project, int index, String name, final IdeView view) { - String lessonFolderName = EduNames.LESSON + index; - final PsiDirectory projectDir = PsiManager.getInstance(project).findDirectory(project.getBaseDir()); - final PsiDirectory lessonDirectory = DirectoryUtil.createSubdirectories(EduNames.LESSON + index, projectDir, "\\/"); - final CCProjectService service = CCProjectService.getInstance(project); - if (lessonDirectory != null) { - if (view != null) { - view.selectElement(lessonDirectory); - } - final Lesson lesson = new Lesson(); - lesson.setName(name != null ? name : lessonFolderName); - lesson.setIndex(index); - service.getCourse().addLesson(lesson); + public static PsiDirectory createLesson(@Nullable IdeView view, @NotNull final Project project, + @NotNull final VirtualFile directory, @NotNull final Course course) { + Lesson lesson = getLesson(directory, project, course, view); + if (lesson == null) { + return null; } - return lessonDirectory; + VirtualFile courseDir = project.getBaseDir(); + int lessonIndex = lesson.getIndex(); + CCUtils.updateHigherElements(courseDir.getChildren(), new Function() { + @Override + public StudyOrderable fun(VirtualFile file) { + return course.getLesson(file.getName()); + } + }, lessonIndex - 1, EduNames.LESSON, 1); + course.addLesson(lesson); + Collections.sort(course.getLessons(), EduUtils.INDEX_COMPARATOR); + return createLessonDir(project, lessonIndex, view); + } + + @Nullable + private static Lesson getLesson(@NotNull final VirtualFile sourceDirectory, + @NotNull final Project project, + @NotNull final Course course, + @Nullable IdeView view) { + + VirtualFile courseDir = project.getBaseDir(); + String lessonName; + int lessonIndex; + if (sourceDirectory.equals(courseDir)) { + lessonIndex = course.getLessons().size() + 1; + String suggestedName = EduNames.LESSON + lessonIndex; + lessonName = view == null ? suggestedName : Messages.showInputDialog("Name:", TITLE, null, suggestedName, null); + } else { + Lesson sourceLesson = course.getLesson(sourceDirectory.getName()); + if (sourceLesson == null) { + return null; + } + final int index = sourceLesson.getIndex(); + CCCreateStudyItemDialog dialog = new CCCreateStudyItemDialog(project, EduNames.LESSON, sourceLesson.getName(), index); + dialog.show(); + if (dialog.getExitCode() != DialogWrapper.OK_EXIT_CODE) { + return null; + } + lessonName = dialog.getName(); + lessonIndex = index + dialog.getIndexDelta(); + } + if (lessonName == null) { + return null; + } + return createAndInitLesson(course, lessonName, lessonIndex); + } + + @NotNull + private static Lesson createAndInitLesson(@NotNull final Course course, @NotNull String lessonName, int lessonIndex) { + Lesson lesson = new Lesson(); + lesson.setName(lessonName); + lesson.setCourse(course); + lesson.setIndex(lessonIndex); + return lesson; + } + + @Nullable + public static PsiDirectory createLessonDir(@NotNull final Project project, final int index, final IdeView view) { + final PsiDirectory projectDir = PsiManager.getInstance(project).findDirectory(project.getBaseDir()); + final PsiDirectory[] lessonDirectory = new PsiDirectory[1]; + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + lessonDirectory[0] = DirectoryUtil.createSubdirectories(EduNames.LESSON + index, projectDir, "\\/"); + } + }); + if (lessonDirectory[0] != null) { + if (view != null) { + view.selectElement(lessonDirectory[0]); + } + } + return lessonDirectory[0]; } @Override @@ -151,9 +156,9 @@ public class CCCreateLesson extends DumbAwareAction { } final CCProjectService service = CCProjectService.getInstance(project); Course course = service.getCourse(); - - if (directory != null && course != null && project.getBaseDir().equals(directory)) { - EduUtils.enableAction(event, false); + if (directory != null && course != null && course.getLesson(directory.getName()) != null) { + EduUtils.enableAction(event, true); + return; } EduUtils.enableAction(event, false); } diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateStudyItemDialog.java b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateStudyItemDialog.java new file mode 100644 index 000000000000..f986357dc695 --- /dev/null +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateStudyItemDialog.java @@ -0,0 +1,33 @@ +package com.jetbrains.edu.coursecreator.ui; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public class CCCreateStudyItemDialog extends DialogWrapper { + private final CCCreateStudyItemPanel myPanel; + + public CCCreateStudyItemDialog(@Nullable Project project, String itemName, String thresholdName, int thresholdIndex) { + super(project); + myPanel = new CCCreateStudyItemPanel(itemName, thresholdName, thresholdIndex); + setTitle("Create New " + StringUtil.toTitleCase(itemName)); + init(); + } + + @Nullable + @Override + protected JComponent createCenterPanel() { + return myPanel; + } + + public String getName() { + return myPanel.getItemName(); + } + + public int getIndexDelta() { + return myPanel.getIndexDelta(); + } +} diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateStudyItemPanel.form b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateStudyItemPanel.form new file mode 100644 index 000000000000..c1af900e81b3 --- /dev/null +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateStudyItemPanel.form @@ -0,0 +1,42 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateStudyItemPanel.java b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateStudyItemPanel.java new file mode 100644 index 000000000000..adf934b325b5 --- /dev/null +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCCreateStudyItemPanel.java @@ -0,0 +1,33 @@ +package com.jetbrains.edu.coursecreator.ui; + +import javax.swing.*; +import java.awt.*; + +public class CCCreateStudyItemPanel extends JPanel { + private final String myItemName; + private JPanel myPanel; + private JTextField myNameField; + private CCItemPositionPanel myPositionalPanel; + private String myThresholdName; + private int myThresholdIndex; + + public CCCreateStudyItemPanel(String itemName, String thresholdName, int thresholdIndex) { + myThresholdName = thresholdName; + myThresholdIndex = thresholdIndex; + myItemName = itemName; + myNameField.setText(itemName + thresholdIndex); + add(myPanel, BorderLayout.CENTER); + } + + private void createUIComponents() { + myPositionalPanel = new CCItemPositionPanel(myItemName, myThresholdName, myThresholdIndex); + } + + public String getItemName() { + return myNameField.getText(); + } + + public int getIndexDelta() { + return myPositionalPanel.getIndexDelta(); + } +} diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCItemPositionPanel.form b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCItemPositionPanel.form new file mode 100644 index 000000000000..922a21098153 --- /dev/null +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCItemPositionPanel.form @@ -0,0 +1,37 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCItemPositionPanel.java b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCItemPositionPanel.java new file mode 100644 index 000000000000..72fa3666b9ee --- /dev/null +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCItemPositionPanel.java @@ -0,0 +1,30 @@ +package com.jetbrains.edu.coursecreator.ui; + +import com.intellij.ui.components.JBLabel; +import com.intellij.ui.components.JBRadioButton; + +import javax.swing.*; +import java.awt.*; + +public class CCItemPositionPanel extends JPanel { + private JPanel myPanel; + private JBRadioButton myBeforeButton; + private JBRadioButton myAfterButton; + private JBLabel mySpecifyPositionLabel; + + public CCItemPositionPanel(String itemName, String thresholdName, int thresholdNum) { + this.add(myPanel, BorderLayout.CENTER); + mySpecifyPositionLabel.setText("Specify " + itemName + " position:"); + String postfix = itemName + " " + thresholdNum + " '" + thresholdName + "'"; + ButtonGroup group = new ButtonGroup(); + group.add(myBeforeButton); + group.add(myAfterButton); + myBeforeButton.setText("before " + postfix); + myAfterButton.setText("after " + postfix); + myBeforeButton.setSelected(true); + } + + public int getIndexDelta() { + return myBeforeButton.isSelected() ? 0 : 1; + } +} diff --git a/python/educational/src/com/jetbrains/edu/EduNames.java b/python/educational/src/com/jetbrains/edu/EduNames.java index 4c45d9e33a7e..e6b2fd99a427 100644 --- a/python/educational/src/com/jetbrains/edu/EduNames.java +++ b/python/educational/src/com/jetbrains/edu/EduNames.java @@ -15,6 +15,7 @@ */ package com.jetbrains.edu; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NonNls; @NonNls @@ -22,6 +23,7 @@ public class EduNames { public static final String TASK_HTML = "task.html"; public static final String HINTS = "hints"; public static final String LESSON = "lesson"; + public static final String LESSON_TITLED = StringUtil.toTitleCase(LESSON); public static final String COURSE = "course"; public static final String TEST_TAB_NAME = "test"; public static final String USER_TEST_INPUT = "input"; diff --git a/python/educational/src/com/jetbrains/edu/EduUtils.java b/python/educational/src/com/jetbrains/edu/EduUtils.java index c4b305d11d47..de3d7f0a2264 100644 --- a/python/educational/src/com/jetbrains/edu/EduUtils.java +++ b/python/educational/src/com/jetbrains/edu/EduUtils.java @@ -19,6 +19,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.jetbrains.edu.courseFormat.AnswerPlaceholder; +import com.jetbrains.edu.courseFormat.StudyOrderable; import com.jetbrains.edu.courseFormat.Task; import com.jetbrains.edu.courseFormat.TaskFile; import org.jetbrains.annotations.NotNull; @@ -28,6 +29,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.Collection; +import java.util.Comparator; import java.util.Map; public class EduUtils { @@ -35,6 +37,13 @@ public class EduUtils { } private static final Logger LOG = Logger.getInstance(EduUtils.class.getName()); + public static Comparator INDEX_COMPARATOR = new Comparator() { + @Override + public int compare(StudyOrderable o1, StudyOrderable o2) { + return o1.getIndex() - o2.getIndex(); + } + }; + public static void commitAndSaveModel(final ModifiableRootModel model) { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override @@ -83,10 +92,14 @@ public class EduUtils { * @return index of object */ public static int getIndex(@NotNull final String fullName, @NotNull final String logicalName) { - if (!fullName.contains(logicalName)) { + if (!fullName.startsWith(logicalName)) { + return -1; + } + try { + return Integer.parseInt(fullName.substring(logicalName.length())) - 1; + } catch(NumberFormatException e) { return -1; } - return Integer.parseInt(fullName.substring(logicalName.length())) - 1; } public static boolean indexIsValid(int index, Collection collection) { From 3db0e7eb65379ac3a0877155cd158b47332535b1 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 11 Aug 2015 16:51:17 +0300 Subject: [PATCH 90/99] reimplemented fix in commit 614a2c0 now EditorComposite instance's state is consistent when added editor becomes visible --- .../openapi/fileEditor/impl/EditorComposite.java | 11 ++++++----- .../fileEditor/impl/EditorWithProviderComposite.java | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java index 6a343a2049dd..5491f1cdef55 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -171,9 +171,11 @@ public abstract class EditorComposite implements Disposable { }); wrapper.getTabs().getComponent().setBorder(new EmptyBorder(0, 0, 1, 0)); + boolean firstEditor = true; for (FileEditor editor : editors) { - JComponent component = myEditors.length == 1 && editor == myEditors[0] ? (JComponent)myComponent.getComponent(0) : createEditorComponent(editor); + JComponent component = firstEditor && myComponent != null ? (JComponent)myComponent.getComponent(0) : createEditorComponent(editor); wrapper.addTab(editor.getName(), component); + firstEditor = false; } wrapper.addChangeListener(new MyChangeListener()); @@ -458,9 +460,9 @@ public abstract class EditorComposite implements Disposable { void addEditor(@NotNull FileEditor editor) { ApplicationManager.getApplication().assertIsDispatchThread(); - FileEditor[] editors = ArrayUtil.append(myEditors, editor); + myEditors = ArrayUtil.append(myEditors, editor); if (myTabbedPaneWrapper == null) { - myTabbedPaneWrapper = createTabbedPaneWrapper(editors); + myTabbedPaneWrapper = createTabbedPaneWrapper(myEditors); myComponent.setComponent(myTabbedPaneWrapper.getComponent()); } else { @@ -469,7 +471,6 @@ public abstract class EditorComposite implements Disposable { } myFocusWatcher.deinstall(myFocusWatcher.getTopComponent()); myFocusWatcher.install(myComponent); - myEditors = editors; } private static class TopBottomPanel extends JPanel { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java index a11827777575..7e6f4d371014 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -62,6 +62,7 @@ public class EditorWithProviderComposite extends EditorComposite { public Pair getSelectedEditorWithProvider() { LOG.assertTrue(myEditors.length > 0, myEditors.length); if (myEditors.length == 1) { + LOG.assertTrue(myTabbedPaneWrapper == null); return Pair.create(myEditors[0], myProviders[0]); } else { // we have to get myEditor from tabbed pane From dbec7a91a2964d9874c6c0597a68264aeddac25c Mon Sep 17 00:00:00 2001 From: Sergey Savenko Date: Tue, 11 Aug 2015 16:50:52 +0300 Subject: [PATCH 91/99] IdeStartupScripts: remove readme.txt, do not create startup scripts directory --- platform/lang-impl/lang-impl.iml | 1 - .../resources/extensions/startup/readme.txt | 14 -------------- .../com/intellij/ide/script/IdeStartupScripts.java | 3 +-- 3 files changed, 1 insertion(+), 17 deletions(-) delete mode 100644 platform/lang-impl/resources/extensions/startup/readme.txt diff --git a/platform/lang-impl/lang-impl.iml b/platform/lang-impl/lang-impl.iml index c2c7a543e97a..5bc3dcc67da9 100644 --- a/platform/lang-impl/lang-impl.iml +++ b/platform/lang-impl/lang-impl.iml @@ -6,7 +6,6 @@ - diff --git a/platform/lang-impl/resources/extensions/startup/readme.txt b/platform/lang-impl/resources/extensions/startup/readme.txt deleted file mode 100644 index 621ed6fec72a..000000000000 --- a/platform/lang-impl/resources/extensions/startup/readme.txt +++ /dev/null @@ -1,14 +0,0 @@ -Scripts contained in this directory are executed on IDE startup. - -## Bindings -* 'IDE' binding from the IDE Scripting Console is available -* script output is redirected to the IDE's log - -## Execution -* each script is executed exactly once after a project's initialization is complete -* scripts are executed in alphabetical order -* a script engine for a script is looked up by script's extension - -## Script Languages -Enabling scripting in your favourite scripting language is easy: -put your language runtime, JSR-223, and required libraries to %IDE_HOME%/lib/ \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java b/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java index 7b8d8a2053e3..b8cecbe387c0 100644 --- a/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java +++ b/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java @@ -52,7 +52,6 @@ import java.util.concurrent.atomic.AtomicBoolean; class IdeStartupScripts extends ApplicationComponent.Adapter { @SuppressWarnings("FieldCanBeLocal") private static String SCRIPT_DIR_NAME = "startup"; - private static String README_FILE_NAME = "readme.txt"; private static Logger LOG = Logger.getInstance(IdeStartupScripts.class); @@ -178,7 +177,7 @@ class IdeStartupScripts extends ApplicationComponent.Adapter { private final ExtensionsRootType myExtensionsRootType = ExtensionsRootType.getInstance(); @Override public boolean value(VirtualFile file) { - return !file.isDirectory() && !myExtensionsRootType.isBackupFile(file) && !README_FILE_NAME.equals(file.getName()); + return !file.isDirectory() && !myExtensionsRootType.isBackupFile(file); } }); From 3c5580ab0be7fe5130cf29f95899d10fc34d4cf9 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Tue, 11 Aug 2015 12:25:13 +0300 Subject: [PATCH 92/99] updated course zip --- .../courses/Introduction to Python.zip | Bin 93192 -> 93195 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/python/edu/interactive-learning-python/resources/courses/Introduction to Python.zip b/python/edu/interactive-learning-python/resources/courses/Introduction to Python.zip index 372a7c257b06f7ff059b21ecbc58bb955d3baa15..04e50d0a7686078b7896ae3cdbe3eacff19ee2eb 100644 GIT binary patch delta 3317 zcmY*bX;@T87NuSz1{zurL~J%upj*)ZqDWX&SM~H^TfQl9cM}hj$X;z3(xaD2(Z-pM+~pM*gv{xle5ll-;Kvb zd6~|mjF%=IGr#)uPJK{+MWJ^WxPRWsGiNyRH7#zuK4K{7Y?vwke7E+{4^d~%yg3Pc zV$I?eI0i5~W)Gv4_|L+Isf4&FXtZOlul#zUevsh(QC9FMpLs&J4O0uYF@sY7a5jlQ zk5#E0aGgv{82){|!5I5mz}w@7LiKPqOQ?$bBdG!hTc#5n<6o0dX3OH)yKu>t<+GdO zL(A23lu&HPbnL&-V8>PnHuFTe2BJo=IN=2W9-OFxR5dpDzY*Bn`|4$Tg@<7k{RRk(LShDcJY6)uu4TANvaM z#J+lE)^&}Qc(OcUzsS0-CF4(?nB`$9flLicWM$x{Wm@Rcu<5K@{9GbjTSxH|S`?34 zPvGrwEP(|>**M(RFT{tI-zrnmmqtGxOB~)H3N;WA&V0Dn#y2;5^hPPjGdHT>EiXKK zK_5b+4-Q=Hg#+)D!A&n5c;`nHiJgGe|F(%h%LH7c=FJ4cCZfl6iv+k~ixu=t#yLAD zigSKU5|_8p9A8e7t>t#`GFUp53EnuX${S}j0)8$LEIuW}LvJ*MR1iq_!C9w4gAdMH zCqA^ir&1~IJ>OIH=3q5dqD8|yt1O^;Bnr&=n}V0yND#`0!8?<1a_7HLk-AAZ#d|VP z`r+hyH^0{eh_V$Lh;#1{Ky*#kH>;BsNZEbA{_)z9KB(rVlQ;CIFY* zzwQA(_#s!KExS2ztCkQvQCI~lkvG}<}$lU|IBDXFW4d3k*fd-7hxPbNF ziU99P1KuJPA=tKRA2IDAIJ@0`0!PyE0$3Hw)XX2MLfN~*ebEJ2ueoWK@6dJf58RSxq5&zU&Q4VX3) z%S>;QRJ^Ro9v;oaH8gY!NM1QDN#SJ#_F8&|e82K3r=q`$ga(M$xF&L3bjv6i#+gjtalH+6DKAi+0i3O zVQCV!HTe$tR@`xd-;!|Ax+Fpad+^->Ta!^Aa#xgS_`19D!4p!D9n~kX(u)LEBE$Xx zl_{)L*nAHf4R~mLQ*o|)GN?|)^%!%XBGwDA@Y)|Gz>odtDBTpo$_Et1J=Y6YWUwp^ zeU~3nq%Vy{Gk5Scu=m+{@!=`n6nbGozZlo>!hR*hrsE7wMk3OT77!nbvj3!G$IBl{ zER4^7);fd*kU0H0E@ZB%u2+c-^kLgo-j3#`GS1`9+Drxw}7os%r}>Gp3qjn{LKc;#UJed2Ny_M AssI20 delta 3473 zcmY*bdt6mj7G@t&US3}El0d+Oi;4=O2!iquMR_PFC?LoMQShP;ids%G;13;NklI$4 zHCbt?1*DKv=%Asa`SVp8S_%O&PBY~LXqqe^*nH>g!@ckaKkoOfZ$0*2d#|&1+#a~~ z_Q0COv6`8CO=Ii}3b&M*n3&Y_!q_N2a=vrP^zul{bN&v|zlB`bmEf@5%yzZ?ZriIi zJ^P<$>9;pGwbWVVh5XW1UD;iK^4zGErH7-MTn^u1$11~qdeHf0;S6*8(VI=WvI}x+ z7nF@z-?VmkNLprdU0vL>H6cefRc;Gx+7M*+QJ{-oYKqP0N6S`>XowkeQ#+w`#~-Z+ z!?&Nw&l)h^`6<_(4WmX|W_DtCT=#kMbYP|yhC=CeTb4+bxojM1?3lF_A4dmmnGa2~ zW6@Hz3Xa>c1j#l*SZ1WL@igC_xw40}%AT!}UY{cjnjvhq>e|%5;VPsU!5) zQ-mbciOrRo=gUA#pEZHm{ z@xW?xmI?EaNhtcB2h1IMh2h=>PBhsQTWGahNa~yr;fg0Ddcp8x%hfK1dx6bgA#|l) z=wj7M5v6OT8s+hygtc%u_9CTFfR^DX;muV7%y}7pvsMegiq*~(pO5Toi)fWK^Wa?@ z2T{Zb_}=V8RE>cDgEdBlhc{wq*BJ<2u+D`Fh9OSLD+ZF3y$JO|&24?y4L%6ww%#b~ z_Cc^8|7;+*-)oN4;)h_x8w@11Yf;qqMuK}5tGiO{iwsT0M(G(}1oSB}5L{nkN0UMk zFr>7XG^eVOXzqRkVZqx=EvY>f2O?$^0@iNqmD-cPJ=jw+>t5E&np4jx+{55aDzSGE z1%;z?Z;ytI`mn8|v0mD2knxty>cK1XgS7Fl1`D0{V+*9yTa1LMJ0dP01DV@a1Iu+= zHPoGrlI|*&ZG9};22+~Ct9kb~IC zpy8*xMck5HB>nI0v(aLm1TLgBMm1r}lOS@NN<6ovmY_$~lvG6)I6&n{ow&6_AcFF&I zX@3$6;LXSTH}=wTS+C_bHI~X)<(9Sm1y5>(AiUPnIJ=n_MMNTGPXt<0D*rB$+D=fU z%(X_MCBM`OkQl{crTR}rP0C<-5QPpneN;&Sz9mJ`)w*I43M@7G$rSR{(D~??M%`& z9bwbQG<0UmV$6p3#QU;9tDeW|#0Ei%+glkdrA!k2#1Gk>oAm$jzv z%f*R2({MBY@q?_<(%;kYRN3@z%3cT%l#Z6&6M&EWj}=v?W0@X53ajHnbZi~z7P5`f z>iaV1P39Ts*bNmFWv~Qxoz7+;zSkomNYBKKxvYXanNW}HR4jZ&r!p(>w(9D?HAB0E zAhT;Qm3zsPeGztJWw!`8Itv9m|4cV@C^%T2BwuC0yiPE@;b$x5#YRy&u*d!@bj}gj ziKYMRzY{5RU5BMi{8a>gH5xc*6f8y_ zizf=h6P~D_zjm1&_EhLRb8-4+J`a>pS}#G~92Klzf?hA{5tc_w;CJhV z0J^0tP0Ig6fV)fKb5R9xdGL8)LTB}Odez(?L|^2=FI_Sc??}v5ywDB|kXdh1PFZU{ zihQmz5vEM7J!u)}N2Wr^omn7VSca?r$w0w89>{F^%-&7Zs7Diu^|*rf Date: Tue, 11 Aug 2015 16:02:36 +0300 Subject: [PATCH 93/99] default font size to 14 for the pycharm edu --- .../jetbrains/python/edu/PyCharmEduInitialConfigurator.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java b/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java index 083956f79691..a9647f8b4dd3 100644 --- a/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java +++ b/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java @@ -32,6 +32,8 @@ import com.intellij.ide.util.PropertiesComponent; import com.intellij.ide.util.TipAndTrickBean; import com.intellij.notification.EventLog; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.extensions.ExtensionsArea; @@ -143,6 +145,8 @@ public class PyCharmEduInitialConfigurator { }); PyCodeInsightSettings.getInstance().SHOW_IMPORT_POPUP = false; } + final EditorColorsScheme editorColorsScheme = EditorColorsManager.getInstance().getScheme(EditorColorsScheme.DEFAULT_SCHEME_NAME); + editorColorsScheme.setEditorFontSize(14); if (!propertiesComponent.isValueSet(DISPLAYED_PROPERTY)) { From 4a8b5dab42f78d25c85c819eff2d212107f3b567 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Tue, 11 Aug 2015 16:40:53 +0300 Subject: [PATCH 94/99] cleaned up menu in PyCharm Edu --- python/edu/src/META-INF/PyCharmEduPlugin.xml | 12 ---- .../edu/PyCharmEduInitialConfigurator.java | 60 +++++++++---------- 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/python/edu/src/META-INF/PyCharmEduPlugin.xml b/python/edu/src/META-INF/PyCharmEduPlugin.xml index b93c60e27277..2e77c3055b96 100644 --- a/python/edu/src/META-INF/PyCharmEduPlugin.xml +++ b/python/edu/src/META-INF/PyCharmEduPlugin.xml @@ -32,20 +32,8 @@ - - - - - - - - - - - - diff --git a/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java b/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java index a9647f8b4dd3..3d76c16a278c 100644 --- a/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java +++ b/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java @@ -72,6 +72,7 @@ import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; +import java.util.HashSet; import java.util.Set; /** @@ -227,56 +228,53 @@ public class PyCharmEduInitialConfigurator { for (int i = 0; i < mainMenu.getChildCount(); i++) { final DefaultMutableTreeNode menuItem = (DefaultMutableTreeNode)mainMenu.getChildAt(i); if ("File".equals(getItemId(menuItem))) { - final String[] fileItems = {"ExportToHTML", "SaveAll", "Export/Import Actions", "Synchronize", "ChangeFileEncodingAction", - "Line Separators", "ToggleReadOnlyAttribute"}; - for (String item : fileItems) { - hideAction(schema, root, menuItem, item); - } + final HashSet fileItems = ContainerUtil.newHashSet("TemplateProjectProperties", "ExportToHTML", "SaveAll", + "Export/Import Actions", "Add to Favorites", "Synchronize", + "ChangeFileEncodingAction", "Line Separators", "ToggleReadOnlyAttribute"); + hideActions(schema, root, menuItem, fileItems); } + else if ("Edit".equals(getItemId(menuItem))) { - final String[] fileItems = {"CopyAsPlainText", "CopyAsReachText", "CopyReference", "EditorPasteSimple", "Macros", "EditorToggleCase", - "TemplateParametersNavigation", "EscapeEntities"}; - for (String item : fileItems) { - hideAction(schema, root, menuItem, item); - } + final HashSet + editItems = ContainerUtil.newHashSet("CopyAsPlainText", "CopyAsReachText", "CopyReference", "EditorPasteSimple", "Macros", + "EditorToggleCase", "EditorJoinLines", "FillParagraph", "Convert Indents", + "TemplateParametersNavigation", "EscapeEntities"); + hideActions(schema, root, menuItem, editItems); } else if ("View".equals(getItemId(menuItem))) { - final String[] fileItems = {"QuickDefinition", "ExpressionTypeInfo", "EditorContextInfo", "ShowErrorDescription", - "RecentChanges", "CompareActions", "QuickChangeScheme"}; - for (String item : fileItems) { - hideAction(schema, root, menuItem, item); - } + final HashSet + viewItems = ContainerUtil.newHashSet("QuickDefinition", "ExpressionTypeInfo", "EditorContextInfo", "ShowErrorDescription", + "RecentChanges", "CompareActions", "QuickChangeScheme"); + hideActions(schema, root, menuItem, viewItems); } else if ("Navigate".equals(getItemId(menuItem))) { - final String[] fileItems = {"GotoCustomRegion", "JumpToLastChange", "JumpToNextChange", "SelectIn", "GotoTypeDeclaration", - "GotoTest", "GotoRelated", "ShowFilePath", "Hierarchy Actions", "Goto Error/Bookmark Actions", "GoToEditPointGroup", - "Change Navigation Actions", "Method Navigation Actions"}; - for (String item : fileItems) { - hideAction(schema, root, menuItem, item); - } + final HashSet + navigateItems = ContainerUtil.newHashSet("GotoCustomRegion", "JumpToLastChange", "JumpToNextChange", "SelectIn", "GotoTypeDeclaration", + "GotoTest", "GotoRelated", "ShowFilePath", "Hierarchy Actions", "Bookmarks", + "Goto Error/Bookmark Actions","GoToEditPointGroup","Change Navigation Actions", + "Method Navigation Actions"); + hideActions(schema, root, menuItem, navigateItems); } } - final String[] menuItems = {"Tools", "VCS", "Refactor", "Code", "Window", "Run"}; - for (String item : menuItems) { - hideAction(schema, root, mainMenu, item); - } + final HashSet menuItems = ContainerUtil.newHashSet("Tools", "VCS", "Refactor", "Code", "Window", "Run"); + hideActions(schema, root, mainMenu, menuItems); } - private static void hideAction(@NotNull final CustomActionsSchema schema, @NotNull final DefaultMutableTreeNode root, - @NotNull final TreeNode actionGroup, @NotNull final String actionId) { + private static void hideActions(@NotNull CustomActionsSchema schema, @NotNull DefaultMutableTreeNode root, + @NotNull final TreeNode actionGroup, Set items) { for(int i = 0; i < actionGroup.getChildCount(); i++){ final DefaultMutableTreeNode child = (DefaultMutableTreeNode)actionGroup.getChildAt(i); final int childCount = child.getChildCount(); - if (childCount > 0) { - hideAction(schema, child, child, actionId); - } final String childId = getItemId(child); - if (childId != null && childId.equals(actionId)){ + if (childId != null && items.contains(childId)){ final TreePath treePath = TreeUtil.getPath(root, child); final ActionUrl url = CustomizationUtil.getActionUrl(treePath, ActionUrl.DELETED); schema.addAction(url); } + else if (childCount > 0) { + hideActions(schema, child, child, items); + } } } From 439d7dc6f65ee2f333f90a8cf828ba1da6d2fb5c Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Tue, 11 Aug 2015 17:16:23 +0300 Subject: [PATCH 95/99] cleaned up popup menus in PyCharm Edu --- python/edu/src/META-INF/PyCharmEduPlugin.xml | 2 -- .../edu/PyCharmEduInitialConfigurator.java | 34 ++++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/python/edu/src/META-INF/PyCharmEduPlugin.xml b/python/edu/src/META-INF/PyCharmEduPlugin.xml index 2e77c3055b96..149b839ef69f 100644 --- a/python/edu/src/META-INF/PyCharmEduPlugin.xml +++ b/python/edu/src/META-INF/PyCharmEduPlugin.xml @@ -32,8 +32,6 @@ - - diff --git a/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java b/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java index 3d76c16a278c..1ad20f1a6627 100644 --- a/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java +++ b/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java @@ -216,14 +216,40 @@ public class PyCharmEduInitialConfigurator { actionsTree.setModel(model); schema.fillActionGroups(root); - hideActionFromMainMenu(root, schema); + for (int i = 0; i < root.getChildCount(); i++) { + final DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)root.getChildAt(i); + if ("Main menu".equals(getItemId(treeNode))) { + hideActionFromMainMenu(root, schema, treeNode); + } + if ("Editor Popup Menu".equals(getItemId(treeNode))) { + final HashSet items = ContainerUtil.newHashSet("CopyAsPlainText", "CopyAsRichText", "CopyReference", "EditorPasteSimple", + "Folding", "Generate", "CompareClipboardWithSelection", + "ChangeFileEncodingAction"); + hideActions(schema, root, treeNode, items); + } + if ("Editor Tab Popup Menu".equals(getItemId(treeNode))) { + final HashSet items = ContainerUtil.newHashSet("CloseAllUnmodifiedEditors", "CloseAllUnpinnedEditors", + "CloseAllEditorsButActive", "CopyReference", "MoveTabRight", "MoveTabDown", + "MoveEditorToOppositeTabGroup", "OpenEditorInOppositeTabGroup", + "ChangeSplitOrientation", "PinActiveTab", "Tabs Placement", + "TabsAlphabeticalMode", "AddNewTabToTheEndMode", "NextTab", "PreviousTab", + "Add to Favorites", "Add All To Favorites", "External Tools", "ValidateXml"); + hideActions(schema, root, treeNode, items); + } + if ("Project View Popup Menu".equals(getItemId(treeNode))) { + final HashSet items = ContainerUtil.newHashSet("NewHtmlFile", "CopyAsPlainText", "CopyAsRichText", "CopyReference", + "CleanPyc", "Add to Favorites", "Images.ShowThumbnails", "CompareTwoFiles", + "CompareFileWithEditor", "SynchronizeCurrentFile", "Mark Directory As", + "ShowFilePath"); + hideActions(schema, root, treeNode, items); + } + } CustomActionsSchema.getInstance().copyFrom(schema); } private static void hideActionFromMainMenu(@NotNull final DefaultMutableTreeNode root, - @NotNull final CustomActionsSchema schema){ - final TreeNode mainMenu = root.getFirstChild(); + @NotNull final CustomActionsSchema schema, DefaultMutableTreeNode mainMenu){ for (int i = 0; i < mainMenu.getChildCount(); i++) { final DefaultMutableTreeNode menuItem = (DefaultMutableTreeNode)mainMenu.getChildAt(i); @@ -236,7 +262,7 @@ public class PyCharmEduInitialConfigurator { else if ("Edit".equals(getItemId(menuItem))) { final HashSet - editItems = ContainerUtil.newHashSet("CopyAsPlainText", "CopyAsReachText", "CopyReference", "EditorPasteSimple", "Macros", + editItems = ContainerUtil.newHashSet("CopyAsPlainText", "CopyAsRichText", "CopyReference", "EditorPasteSimple", "Macros", "EditorToggleCase", "EditorJoinLines", "FillParagraph", "Convert Indents", "TemplateParametersNavigation", "EscapeEntities"); hideActions(schema, root, menuItem, editItems); From ca9eb29afa3a00696a8b3bc5e324a56767ae9e76 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 11 Aug 2015 16:54:04 +0300 Subject: [PATCH 96/99] IDEA-142224 add settings to adjust color scheme for people with red-green color blindness --- .../com/intellij/ide/ui/ColorBlindness.java | 67 +++++++++++ .../src/com/intellij/ide/ui/UISettings.java | 1 + .../colors/impl/AbstractColorsScheme.java | 6 +- .../ide/ui/AppearanceConfigurable.java | 15 ++- .../com/intellij/ide/ui/AppearancePanel.form | 10 +- .../intellij/ide/ui/ColorBlindnessPanel.java | 104 ++++++++++++++++++ .../src/messages/IdeBundle.properties | 8 ++ .../util/resources/misc/registry.properties | 4 - 8 files changed, 202 insertions(+), 13 deletions(-) create mode 100644 platform/editor-ui-api/src/com/intellij/ide/ui/ColorBlindness.java create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/ColorBlindnessPanel.java diff --git a/platform/editor-ui-api/src/com/intellij/ide/ui/ColorBlindness.java b/platform/editor-ui-api/src/com/intellij/ide/ui/ColorBlindness.java new file mode 100644 index 000000000000..bf8ac42bcd9b --- /dev/null +++ b/platform/editor-ui-api/src/com/intellij/ide/ui/ColorBlindness.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.ui; + +/** + * @author Sergey.Malenkov + */ +public enum ColorBlindness { + /** + * Lacking the long-wavelength sensitive retinal cones, + * those with this condition are unable to distinguish + * between colors in the green–yellow–red section of the spectrum. + * Protanopes are more likely to confuse + *
    + *
  • black with many shades of red;
  • + *
  • dark brown with dark green, dark orange and dark red;
  • + *
  • some blues with some reds, purples and dark pinks;
  • + *
  • mid-greens with some oranges.
  • + *
+ */ + protanopia, + /** + * Lacking the medium-wavelength sensitive retinal cones, + * those with this condition are unable to distinguish + * between colors in the green–yellow–red section of the spectrum. + * Deuteranopes are more likely to confuse + *
    + *
  • mid-reds with mid-greens;
  • + *
  • blue-greens with grey and mid-pinks;
  • + *
  • bright greens with yellows;
  • + *
  • pale pinks with light grey;
  • + *
  • mid-reds with mid-brown
  • + *
  • light blues with lilac.
  • + *
+ */ + deuteranopia, + /** + * Lacking the short-wavelength sensitive retinal cones, + * those affected see short-wavelength colors (blue, indigo and a spectral violet) + * greenish and drastically dimmed, some of these colors even as black. + * Tritanopes are more likely to confuse + *
    + *
  • light blues with greys;
  • + *
  • dark purples with black;
  • + *
  • mid-greens with blues;
  • + *
  • oranges with reds.
  • + *
+ */ + tritanopia, + /** + * Total color blindness is defined as the inability to see color. + */ + achromatopsia +} diff --git a/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java b/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java index 6c922b21772e..8a3eefdffbff 100644 --- a/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java +++ b/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java @@ -101,6 +101,7 @@ public class UISettings extends SimpleModificationTracker implements PersistentS public boolean ANTIALIASING_IN_EDITOR = true; public boolean ANTIALIASING_IN_IDE = ANTIALIASING_IN_EDITOR; public LCDRenderingScope LCD_RENDERING_SCOPE = UIUtil.isRetina() ? LCDRenderingScope.OFF : LCDRenderingScope.IDE; + public ColorBlindness COLOR_BLINDNESS; public boolean USE_LCD_RENDERING_IN_EDITOR = true; public boolean MOVE_MOUSE_ON_DEFAULT_BUTTON = false; public boolean ENABLE_ALPHA_MODE = false; diff --git a/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java b/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java index 2d232020deac..47d503a8b1f6 100644 --- a/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java +++ b/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java @@ -19,6 +19,7 @@ */ package com.intellij.openapi.editor.colors.impl; +import com.intellij.ide.ui.ColorBlindness; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.editor.HighlighterColors; import com.intellij.openapi.editor.colors.*; @@ -271,8 +272,9 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme { } public void readExternal(Element parentNode) { - String blindness = Registry.stringValue("color.blindness"); // TODO: get blindness - myValueReader.setAttribute(blindness); + UISettings settings = UISettings.getInstance(); + ColorBlindness blindness = settings == null ? null : settings.COLOR_BLINDNESS; + myValueReader.setAttribute(blindness == null ? null : blindness.name()); if (SCHEME_ELEMENT.equals(parentNode.getName())) { readScheme(parentNode); } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java b/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java index bbb103d6c9e4..17cf08ba0fab 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java @@ -34,8 +34,6 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; import java.util.Dictionary; import java.util.Hashtable; @@ -199,6 +197,13 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab update |= settings.NAVIGATE_TO_PREVIEW != (myComponent.myNavigateToPreviewCheckBox.isVisible() && myComponent.myNavigateToPreviewCheckBox.isSelected()); settings.NAVIGATE_TO_PREVIEW = myComponent.myNavigateToPreviewCheckBox.isSelected(); + ColorBlindness blindness = myComponent.myColorBlindnessPanel.getColorBlindness(); + if (settings.COLOR_BLINDNESS != blindness) { + settings.COLOR_BLINDNESS = blindness; + update = true; + //TODO:SAM: reload + } + update |= settings.DISABLE_MNEMONICS_IN_CONTROLS != myComponent.myDisableMnemonicInControlsCheckBox.isSelected(); settings.DISABLE_MNEMONICS_IN_CONTROLS = myComponent.myDisableMnemonicInControlsCheckBox.isSelected(); @@ -308,6 +313,7 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab myComponent.myRightLayoutCheckBox.setSelected(settings.RIGHT_HORIZONTAL_SPLIT); myComponent.myNavigateToPreviewCheckBox.setSelected(settings.NAVIGATE_TO_PREVIEW); myComponent.myNavigateToPreviewCheckBox.setVisible(false);//disabled for a while + myComponent.myColorBlindnessPanel.setColorBlindness(settings.COLOR_BLINDNESS); myComponent.myDisableMnemonicInControlsCheckBox.setSelected(settings.DISABLE_MNEMONICS_IN_CONTROLS); boolean alphaModeEnabled = WindowManagerEx.getInstanceEx().isAlphaModeSupported(); @@ -355,6 +361,7 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab isModified |= myComponent.myLeftLayoutCheckBox.isSelected() != settings.LEFT_HORIZONTAL_SPLIT; isModified |= myComponent.myRightLayoutCheckBox.isSelected() != settings.RIGHT_HORIZONTAL_SPLIT; isModified |= myComponent.myNavigateToPreviewCheckBox.isSelected() != settings.NAVIGATE_TO_PREVIEW; + isModified |= myComponent.myColorBlindnessPanel.getColorBlindness() != settings.COLOR_BLINDNESS; isModified |= myComponent.myHideIconsInQuickNavigation.isSelected() != settings.SHOW_ICONS_IN_QUICK_NAVIGATION; @@ -429,9 +436,7 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab private JSlider myInitialTooltipDelaySlider; private ComboBox myPresentationModeFontSize; private JCheckBox myNavigateToPreviewCheckBox; - private JCheckBox myAllowStatusBar; - private JCheckBox myAllowLineNumbers; - private JCheckBox myAllowAnnotations; + private ColorBlindnessPanel myColorBlindnessPanel; public MyComponent() { myOverrideLAFFonts.addActionListener( new ActionListener() { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form b/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form index 548ce66676e7..2f74192e7759 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form +++ b/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form @@ -3,7 +3,7 @@ - + @@ -16,7 +16,7 @@ - + @@ -226,6 +226,12 @@ + + + + + + diff --git a/platform/platform-impl/src/com/intellij/ide/ui/ColorBlindnessPanel.java b/platform/platform-impl/src/com/intellij/ide/ui/ColorBlindnessPanel.java new file mode 100644 index 000000000000..36acab939e15 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/ui/ColorBlindnessPanel.java @@ -0,0 +1,104 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.ui; + +import com.intellij.ide.IdeBundle; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.ui.components.panels.HorizontalLayout; +import com.intellij.util.ui.JBUI; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +/** + * @author Sergey.Malenkov + */ +final class ColorBlindnessPanel extends JPanel implements ChangeListener { + private final JCheckBox myCheckBox = new JCheckBox(); + private final JComboBox myComboBox = new ComboBox(); + + public ColorBlindnessPanel() { + super(new HorizontalLayout(JBUI.scale(10))); + add(HorizontalLayout.LEFT, myCheckBox); + add(HorizontalLayout.LEFT, myComboBox); + myCheckBox.setSelected(false); + myCheckBox.addChangeListener(this); + myCheckBox.setText(IdeBundle.message("checkbox.color.blindness")); + int count = 0; + for (ColorBlindness blindness : ColorBlindness.values()) { + String name = IdeBundle.message("combobox.color.blindness." + blindness.name()); + if (!name.isEmpty()) { + myComboBox.addItem(new Item(blindness, name)); + count++; + } + } + myComboBox.setEnabled(false); + myComboBox.setVisible(count > 1); + setVisible(count > 0); + } + + @Override + public void stateChanged(ChangeEvent event) { + myComboBox.setEnabled(myCheckBox.isSelected()); + } + + public ColorBlindness getColorBlindness() { + if (myCheckBox.isSelected()) { + Object object = myComboBox.getSelectedItem(); + if (object instanceof Item) { + Item item = (Item)object; + return item.myBlindness; + } + } + return null; + } + + public void setColorBlindness(ColorBlindness blindness) { + Item item = null; + if (blindness != null) { + int count = myComboBox.getItemCount(); + for (int i = 0; i < count && item == null; i++) { + Object object = myComboBox.getItemAt(i); + if (object instanceof Item) { + item = (Item)object; + if (item.myBlindness != blindness) { + item = null; + } + } + } + } + myCheckBox.setSelected(item != null); + if (item != null) { + myComboBox.setSelectedItem(item); + } + } + + private static final class Item { + private final ColorBlindness myBlindness; + private final String myName; + + private Item(ColorBlindness blindness, String name) { + myBlindness = blindness; + myName = name; + } + + @Override + public String toString() { + return myName; + } + } +} diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 524ab5648139..f1695f65c1e6 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -1182,3 +1182,11 @@ new.dir.project.error.buck=Project directory name must not contain the ''$'' cha go.to.file.toolwindow.title=Files matching pattern go.to.class.toolwindow.title=Classes matching pattern go.to.class.dumb.mode.message=Go To Class action is not available until indices are built, using Go To File instead + +checkbox.color.blindness=Adjust for red-green color deficiency (restart required) +# define at least one name to show checkbox +# define more that one name to show combobox +combobox.color.blindness.protanopia=Protanopia +combobox.color.blindness.deuteranopia= +combobox.color.blindness.tritanopia= +combobox.color.blindness.achromatopsia= diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index e2162b6da368..b6e22632e3fb 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -644,7 +644,3 @@ ruby.remote.debugger.supports.catchpoint.removal=true use.read.action.to.init.service=true ruby.debugger.support.file.filtering=false - -color.blindness= -color.blindness.restartRequired=true -color.blindness.description=Use one of the following values: deuteranopia, protanopia, tritanopia, achromatopsia From c5957dd45a311b0da08925f82f0994a1c71d0b70 Mon Sep 17 00:00:00 2001 From: Vyacheslav Karpukhin Date: Tue, 11 Aug 2015 16:21:47 +0200 Subject: [PATCH 97/99] rebuilt pty4j with lost fixes --- .idea/libraries/pty4j.xml | 4 ++-- lib/pty4j-0.4.18.jar | Bin 48844 -> 0 bytes lib/pty4j-0.4.19.jar | Bin 0 -> 51165 bytes lib/required_for_dist.txt | 2 +- ...4j-0.4.18-src.jar => pty4j-0.4.19-src.jar} | Bin 31642 -> 31952 bytes 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 lib/pty4j-0.4.18.jar create mode 100644 lib/pty4j-0.4.19.jar rename lib/src/{pty4j-0.4.18-src.jar => pty4j-0.4.19-src.jar} (58%) diff --git a/.idea/libraries/pty4j.xml b/.idea/libraries/pty4j.xml index faec40e44f2e..bf8da8019521 100644 --- a/.idea/libraries/pty4j.xml +++ b/.idea/libraries/pty4j.xml @@ -1,11 +1,11 @@ - + - + diff --git a/lib/pty4j-0.4.18.jar b/lib/pty4j-0.4.18.jar deleted file mode 100644 index a1ae8457ddaa5f0cfc4dba23b94770973d8a7b56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48844 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%0Ao|%2OnBz^N?; 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 D^pyhT literal 0 HcmV?d00001 diff --git a/lib/required_for_dist.txt b/lib/required_for_dist.txt index a014761aea97..40c93b595f4a 100644 --- a/lib/required_for_dist.txt +++ b/lib/required_for_dist.txt @@ -55,7 +55,7 @@ oromatcher.jar picocontainer.jar protobuf-2.5.0.jar proxy-vole_20131209.jar -pty4j-0.4.18.jar +pty4j-0.4.19.jar purejavacomm.jar resolver.jar rhino-js-1_7R4.jar diff --git a/lib/src/pty4j-0.4.18-src.jar b/lib/src/pty4j-0.4.19-src.jar similarity index 58% rename from lib/src/pty4j-0.4.18-src.jar rename to lib/src/pty4j-0.4.19-src.jar index 6ca2f205b1ef69d5e0f85bf8fbc5a9cff05e9b17..58124381fab3100c6601135bcacf430f7a14d1cd 100644 GIT binary patch delta 8694 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 KBQv=DM*jyXhK{lT delta 8457 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 From 5125e023f482c5a7cf4a96b2d9af581b344c7ccf Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Tue, 11 Aug 2015 17:37:41 +0300 Subject: [PATCH 98/99] simplified hide action functionality --- .../edu/PyCharmEduInitialConfigurator.java | 81 ++++++------------- 1 file changed, 25 insertions(+), 56 deletions(-) diff --git a/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java b/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java index 1ad20f1a6627..902df9c7f6f2 100644 --- a/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java +++ b/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java @@ -87,6 +87,30 @@ public class PyCharmEduInitialConfigurator { private static final Set UNRELATED_TIPS = Sets.newHashSet("LiveTemplatesDjango.html", "TerminalOpen.html", "Terminal.html", "ConfiguringTerminal.html"); + private static final Set HIDDEN_ACTIONS = ContainerUtil.newHashSet("CopyAsPlainText", "CopyAsRichText", "EditorPasteSimple", + "Folding", "Generate", "CompareClipboardWithSelection", + "ChangeFileEncodingAction", "CloseAllUnmodifiedEditors", + "CloseAllUnpinnedEditors", "CloseAllEditorsButActive", + "CopyReference", "MoveTabRight", "MoveTabDown", "External Tools", + "MoveEditorToOppositeTabGroup", "OpenEditorInOppositeTabGroup", + "ChangeSplitOrientation", "PinActiveTab", "Tabs Placement", + "TabsAlphabeticalMode", "AddNewTabToTheEndMode", "NextTab", + "PreviousTab", "Add to Favorites", "Add All To Favorites", + "ValidateXml", "NewHtmlFile", "CleanPyc", "Images.ShowThumbnails", + "CompareFileWithEditor", "SynchronizeCurrentFile", + "Mark Directory As", "CompareTwoFiles", "ShowFilePath", + "ChangesView.ApplyPatch", "TemplateProjectProperties", + "ExportToHTML", "SaveAll", "Export/Import Actions", + "Synchronize", "Line Separators", "ToggleReadOnlyAttribute", + "Macros", "EditorToggleCase", "EditorJoinLines", "FillParagraph", + "Convert Indents", "TemplateParametersNavigation", "EscapeEntities", + "QuickDefinition", "ExpressionTypeInfo", "EditorContextInfo", + "ShowErrorDescription", "RecentChanges", "CompareActions", + "GotoCustomRegion", "JumpToLastChange", "JumpToNextChange", + "SelectIn", "GotoTypeDeclaration", "QuickChangeScheme", + "GotoTest", "GotoRelated", "Hierarchy Actions", "Bookmarks", + "Goto Error/Bookmark Actions", "GoToEditPointGroup", + "Change Navigation Actions", "Method Navigation Actions"); public static class First { @@ -221,68 +245,13 @@ public class PyCharmEduInitialConfigurator { if ("Main menu".equals(getItemId(treeNode))) { hideActionFromMainMenu(root, schema, treeNode); } - if ("Editor Popup Menu".equals(getItemId(treeNode))) { - final HashSet items = ContainerUtil.newHashSet("CopyAsPlainText", "CopyAsRichText", "CopyReference", "EditorPasteSimple", - "Folding", "Generate", "CompareClipboardWithSelection", - "ChangeFileEncodingAction"); - hideActions(schema, root, treeNode, items); - } - if ("Editor Tab Popup Menu".equals(getItemId(treeNode))) { - final HashSet items = ContainerUtil.newHashSet("CloseAllUnmodifiedEditors", "CloseAllUnpinnedEditors", - "CloseAllEditorsButActive", "CopyReference", "MoveTabRight", "MoveTabDown", - "MoveEditorToOppositeTabGroup", "OpenEditorInOppositeTabGroup", - "ChangeSplitOrientation", "PinActiveTab", "Tabs Placement", - "TabsAlphabeticalMode", "AddNewTabToTheEndMode", "NextTab", "PreviousTab", - "Add to Favorites", "Add All To Favorites", "External Tools", "ValidateXml"); - hideActions(schema, root, treeNode, items); - } - if ("Project View Popup Menu".equals(getItemId(treeNode))) { - final HashSet items = ContainerUtil.newHashSet("NewHtmlFile", "CopyAsPlainText", "CopyAsRichText", "CopyReference", - "CleanPyc", "Add to Favorites", "Images.ShowThumbnails", "CompareTwoFiles", - "CompareFileWithEditor", "SynchronizeCurrentFile", "Mark Directory As", - "ShowFilePath"); - hideActions(schema, root, treeNode, items); - } + hideActions(schema, root, treeNode, HIDDEN_ACTIONS); } - CustomActionsSchema.getInstance().copyFrom(schema); } private static void hideActionFromMainMenu(@NotNull final DefaultMutableTreeNode root, @NotNull final CustomActionsSchema schema, DefaultMutableTreeNode mainMenu){ - - for (int i = 0; i < mainMenu.getChildCount(); i++) { - final DefaultMutableTreeNode menuItem = (DefaultMutableTreeNode)mainMenu.getChildAt(i); - if ("File".equals(getItemId(menuItem))) { - final HashSet fileItems = ContainerUtil.newHashSet("TemplateProjectProperties", "ExportToHTML", "SaveAll", - "Export/Import Actions", "Add to Favorites", "Synchronize", - "ChangeFileEncodingAction", "Line Separators", "ToggleReadOnlyAttribute"); - hideActions(schema, root, menuItem, fileItems); - } - - else if ("Edit".equals(getItemId(menuItem))) { - final HashSet - editItems = ContainerUtil.newHashSet("CopyAsPlainText", "CopyAsRichText", "CopyReference", "EditorPasteSimple", "Macros", - "EditorToggleCase", "EditorJoinLines", "FillParagraph", "Convert Indents", - "TemplateParametersNavigation", "EscapeEntities"); - hideActions(schema, root, menuItem, editItems); - } - else if ("View".equals(getItemId(menuItem))) { - final HashSet - viewItems = ContainerUtil.newHashSet("QuickDefinition", "ExpressionTypeInfo", "EditorContextInfo", "ShowErrorDescription", - "RecentChanges", "CompareActions", "QuickChangeScheme"); - hideActions(schema, root, menuItem, viewItems); - } - else if ("Navigate".equals(getItemId(menuItem))) { - final HashSet - navigateItems = ContainerUtil.newHashSet("GotoCustomRegion", "JumpToLastChange", "JumpToNextChange", "SelectIn", "GotoTypeDeclaration", - "GotoTest", "GotoRelated", "ShowFilePath", "Hierarchy Actions", "Bookmarks", - "Goto Error/Bookmark Actions","GoToEditPointGroup","Change Navigation Actions", - "Method Navigation Actions"); - hideActions(schema, root, menuItem, navigateItems); - } - } - final HashSet menuItems = ContainerUtil.newHashSet("Tools", "VCS", "Refactor", "Code", "Window", "Run"); hideActions(schema, root, mainMenu, menuItems); } From 751d8fa41c7a88fe1193290fb86b46543c98f780 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Tue, 11 Aug 2015 17:40:22 +0300 Subject: [PATCH 99/99] fixed EDU-392 NPE at com.jetbrains.edu.coursecreator.actions.CCRunTestsAction.update(CCRunTestsAction.java:80) --- .../jetbrains/edu/coursecreator/actions/CCRunTestsAction.java | 1 + 1 file changed, 1 insertion(+) diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCRunTestsAction.java b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCRunTestsAction.java index aa065bf35451..eb04c491c0ef 100644 --- a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCRunTestsAction.java +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCRunTestsAction.java @@ -77,6 +77,7 @@ public abstract class CCRunTestsAction extends AnAction { final CCProjectService service = CCProjectService.getInstance(project); final Course course = service.getCourse(); final PsiDirectory taskDir = psiFile.getContainingDirectory(); + if (taskDir == null) return; final PsiDirectory lessonDir = taskDir.getParent(); if (lessonDir == null) return; if (course == null) return;

Jc4t=O2^clkQr7zY~!4>QXA^l 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⁣SH8J+d_m$9jTlaUkES-+FB0t2u?%wfvm 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 literal 0 HcmV?d00001 diff --git a/lib/libpty/win/win10_x86_64/libwinpty.dll b/lib/libpty/win/win10_x86_64/libwinpty.dll new file mode 100644 index 0000000000000000000000000000000000000000..471bc626c2463c980f693ee6826a2f5c63cecdb1 GIT binary patch literal 196096 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