diff --git a/build.xml b/build.xml
index 7f432c016be6..33716395f4f7 100644
--- a/build.xml
+++ b/build.xml
@@ -75,7 +75,7 @@
-
+
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java b/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java
index cfd345758fcc..1d8570aa03c9 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java
@@ -15,6 +15,7 @@
*/
package com.intellij.debugger.engine;
+import com.intellij.debugger.EvaluatingComputable;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.impl.DebuggerUtilsEx;
@@ -25,6 +26,7 @@ import com.intellij.psi.util.InheritanceUtil;
import com.intellij.util.Range;
import com.sun.jdi.Location;
import com.sun.jdi.Method;
+import com.sun.jdi.ObjectReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -65,7 +67,12 @@ public class BasicStepMethodFilter implements NamedMethodFilter {
return myTargetMethodName;
}
- public boolean locationMatches(final DebugProcessImpl process, final Location location) throws EvaluateException {
+ public boolean locationMatches(DebugProcessImpl process, Location location) throws EvaluateException {
+ return locationMatches(process, location, () -> null);
+ }
+
+ public boolean locationMatches(DebugProcessImpl process, Location location, @NotNull EvaluatingComputable thisProvider)
+ throws EvaluateException {
Method method = location.method();
String name = method.name();
if (!myTargetMethodName.equals(name)) {
@@ -96,7 +103,15 @@ public class BasicStepMethodFilter implements NamedMethodFilter {
if (method.isBridge()) { // skip bridge methods
return false;
}
- return DebuggerUtilsEx.isAssignableFrom(myDeclaringClassName.getName(process), location.declaringType());
+ String declaringClassNameName = myDeclaringClassName.getName(process);
+ boolean res = DebuggerUtilsEx.isAssignableFrom(declaringClassNameName, location.declaringType());
+ if (!res && !method.isStatic()) {
+ ObjectReference thisObject = thisProvider.compute();
+ if (thisObject != null) {
+ res = DebuggerUtilsEx.isAssignableFrom(declaringClassNameName, thisObject.referenceType());
+ }
+ }
+ return res;
}
private static boolean signatureMatches(Method method, final String expectedSignature) throws EvaluateException {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/MethodFilter.java b/java/debugger/impl/src/com/intellij/debugger/engine/MethodFilter.java
index 757272c8b777..b90829d82b3f 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/MethodFilter.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/MethodFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2016 JetBrains s.r.o.
+ * Copyright 2000-2017 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,22 @@
*/
package com.intellij.debugger.engine;
+import com.intellij.debugger.EvaluatingComputable;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.util.Range;
import com.sun.jdi.Location;
+import com.sun.jdi.ObjectReference;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface MethodFilter {
boolean locationMatches(DebugProcessImpl process, Location location) throws EvaluateException;
+
+ default boolean locationMatches(DebugProcessImpl process, Location location, @NotNull EvaluatingComputable thisProvider)
+ throws EvaluateException {
+ return locationMatches(process, location);
+ }
+
@Nullable Range getCallingExpressionLines();
default int onReached(SuspendContextImpl context, RequestHint hint) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/RequestHint.java b/java/debugger/impl/src/com/intellij/debugger/engine/RequestHint.java
index d6d00f5207e5..f5adb418da5a 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/RequestHint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/RequestHint.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2016 JetBrains s.r.o.
+ * Copyright 2000-2017 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.
@@ -192,7 +192,7 @@ public class RequestHint {
if (myMethodFilter != null &&
frameProxy != null &&
!(myMethodFilter instanceof BreakpointStepMethodFilter) &&
- myMethodFilter.locationMatches(context.getDebugProcess(), frameProxy.location()) &&
+ myMethodFilter.locationMatches(context.getDebugProcess(), frameProxy.location(), frameProxy::thisObject) &&
!isTheSameFrame(context)
) {
myTargetMethodMatched = true;
diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsImpl.java
index 1812ade79721..c0f6c45d86d3 100644
--- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsImpl.java
@@ -226,20 +226,16 @@ public class DebuggerUtilsImpl extends DebuggerUtilsEx{
return Boolean.TRUE.equals(debugProcess.getUserData(BatchEvaluator.REMOTE_SESSION_KEY));
}
- public interface SupplierThrowing {
- T get() throws E;
- }
-
- public static T suppressExceptions(SupplierThrowing supplier, T defaultValue) throws E {
+ public static T suppressExceptions(ThrowableComputable supplier, T defaultValue) throws E {
return suppressExceptions(supplier, defaultValue, true, null);
}
- public static T suppressExceptions(SupplierThrowing supplier,
+ public static T suppressExceptions(ThrowableComputable supplier,
T defaultValue,
boolean ignorePCE,
Class rethrow) throws E {
try {
- return supplier.get();
+ return supplier.compute();
}
catch (ProcessCanceledException e) {
if (!ignorePCE) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java
index cb67d2b23a8d..55ebaef45f6a 100644
--- a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java
@@ -25,8 +25,8 @@ import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.jdi.VirtualMachineProxy;
-import com.intellij.debugger.impl.DebuggerUtilsImpl;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.ThreeState;
@@ -357,13 +357,13 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy {
return myVirtualMachine.mirrorOf(s);
}
- public StringReference mirrorOfStringLiteral(String s, DebuggerUtilsImpl.SupplierThrowing generator)
+ public StringReference mirrorOfStringLiteral(String s, ThrowableComputable generator)
throws EvaluateException {
StringReference reference = myStringLiteralCache.get(s);
if (reference != null && !reference.isCollected()) {
return reference;
}
- reference = generator.get();
+ reference = generator.compute();
myStringLiteralCache.put(s, reference);
return reference;
}
diff --git a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java
index fe6612b10d08..2fa79311b8c6 100644
--- a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java
+++ b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java
@@ -259,7 +259,7 @@ public class JUnitUtil {
return aPackage != null && aPackage.getDirectories(scope).length > 0;
};
- return foundCondition.value(TEST5_PACKAGE_FQN) || foundCondition.value("org.junit.platform.engine");
+ return foundCondition.value(TEST5_PACKAGE_FQN);
}
public static boolean isTestAnnotated(final PsiMethod method) {
diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationTasksImpl.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationTasksImpl.groovy
index 81050a164483..8995de6c7476 100644
--- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationTasksImpl.groovy
+++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationTasksImpl.groovy
@@ -42,7 +42,6 @@ class CompilationTasksImpl extends CompilationTasks {
ensureKotlinCompilerAddedToClassPath()
- context.projectBuilder.cleanOutput()
context.messages.progress("Compiling project")
try {
if (moduleNames == null) {
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalProjectsManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalProjectsManager.java
index 87b9c3ac01ca..e6472e0f49a3 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalProjectsManager.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalProjectsManager.java
@@ -118,35 +118,35 @@ public class ExternalProjectsManager implements PersistentStateComponent systemManager : ExternalSystemApiUtil.getAllManagers()) {
- final Collection externalProjects =
- ExternalProjectsDataStorage.getInstance(myProject).list(systemManager.getSystemId());
- for (ExternalProjectInfo externalProject : externalProjects) {
- if (externalProject.getExternalProjectStructure() == null) continue;
- Collection> taskData =
- ExternalSystemApiUtil.findAllRecursively(externalProject.getExternalProjectStructure(), TASK);
- myShortcutsManager.scheduleKeymapUpdate(taskData);
- }
-
- if (!externalProjects.isEmpty()) {
- myShortcutsManager.scheduleRunConfigurationKeymapUpdate(systemManager.getSystemId());
- }
+ // init shortcuts manager
+ myShortcutsManager.init();
+ for (ExternalSystemManager, ?, ?, ?, ?> systemManager : ExternalSystemApiUtil.getAllManagers()) {
+ final Collection externalProjects =
+ ExternalProjectsDataStorage.getInstance(myProject).list(systemManager.getSystemId());
+ for (ExternalProjectInfo externalProject : externalProjects) {
+ if (externalProject.getExternalProjectStructure() == null) continue;
+ Collection> taskData =
+ ExternalSystemApiUtil.findAllRecursively(externalProject.getExternalProjectStructure(), TASK);
+ myShortcutsManager.scheduleKeymapUpdate(taskData);
}
- // init task activation info
- myTaskActivator.init();
+ if (!externalProjects.isEmpty()) {
+ myShortcutsManager.scheduleRunConfigurationKeymapUpdate(systemManager.getSystemId());
+ }
+ }
+ // init task activation info
+ myTaskActivator.init();
+
+ synchronized (isInitializationFinished) {
isInitializationFinished.set(true);
ApplicationManager.getApplication().executeOnPooledThread(() -> {
myPostInitializationActivities.run();
@@ -156,10 +156,13 @@ public class ExternalProjectsManager implements PersistentStateComponent implements Runnable {
+import java.util.List;
+
+public class CompositeRunnable implements Runnable {
+ private List list = new SmartList<>();
+
+ public boolean add(Runnable runnable) {
+ return list.add(runnable);
+ }
+
+ public void clear() {
+ list = new SmartList<>();
+ }
+
@Override
public void run() {
- for (Runnable runnable : this) {
+ for (Runnable runnable : list) {
runnable.run();
}
}
diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/ColorSchemeActions.java b/platform/lang-impl/src/com/intellij/application/options/colors/ColorSchemeActions.java
index 20f8de4e2a88..0f89dc4ef762 100644
--- a/platform/lang-impl/src/com/intellij/application/options/colors/ColorSchemeActions.java
+++ b/platform/lang-impl/src/com/intellij/application/options/colors/ColorSchemeActions.java
@@ -76,10 +76,16 @@ public abstract class ColorSchemeActions extends AbstractSchemeActions {
private static final Comparator REMOTE_BRANCH_COMPARATOR = new MyRemoteBranchComparator();
private static final String SEPARATOR = " : ";
private static final Color NEW_BRANCH_LABEL_FG = new JBColor(0x00b53d, 0x6ba65d);
- private static final Color NEW_BRANCH_SELECTION_LABEL_FG = UIUtil.getTreeSelectionForeground();
+ private static final Color NEW_BRANCH_LABEL_SELECTION_FG = UIUtil.getTreeSelectionForeground();
private static final Color NEW_BRANCH_LABEL_BG = new JBColor(0xebfcf1, 0x313b32);
- private static final Color NEW_BRANCH_SELECTION_LABEL__BG =
- new JBColor(ColorUtil.toAlpha(NEW_BRANCH_SELECTION_LABEL_FG, 20), ColorUtil.toAlpha(NEW_BRANCH_SELECTION_LABEL_FG, 30));
+ private static final Color NEW_BRANCH_LABEL_SELECTION_BG =
+ new JBColor(ColorUtil.toAlpha(NEW_BRANCH_LABEL_SELECTION_FG, 20), ColorUtil.toAlpha(NEW_BRANCH_LABEL_SELECTION_FG, 30));
private static final RelativeFont NEW_BRANCH_LABEL_FONT = RelativeFont.TINY.small();
private static final TextIcon NEW_BRANCH_LABEL = new TextIcon("New", NEW_BRANCH_LABEL_FG, NEW_BRANCH_LABEL_BG, 0);
@@ -282,8 +282,8 @@ public class GitPushTargetPanel extends PushTargetPanel {
NEW_BRANCH_LABEL.setInsets(JBUI.insets(2));
NEW_BRANCH_LABEL.setRound(JBUI.scale(4));
NEW_BRANCH_LABEL.setFont(NEW_BRANCH_LABEL_FONT.derive(renderer.getFont()));
- NEW_BRANCH_LABEL.setForeground(isSelected ? NEW_BRANCH_SELECTION_LABEL_FG : NEW_BRANCH_LABEL_FG);
- NEW_BRANCH_LABEL.setBackground(isSelected ? NEW_BRANCH_SELECTION_LABEL__BG : NEW_BRANCH_LABEL_BG);
+ NEW_BRANCH_LABEL.setForeground(isSelected ? NEW_BRANCH_LABEL_SELECTION_FG : NEW_BRANCH_LABEL_FG);
+ NEW_BRANCH_LABEL.setBackground(isSelected ? NEW_BRANCH_LABEL_SELECTION_BG : NEW_BRANCH_LABEL_BG);
renderer.setIcon(NEW_BRANCH_LABEL);
}
}
diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryImpl.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryImpl.java
index 120de4a54dee..08a41b25f19e 100644
--- a/plugins/git4idea/src/git4idea/repo/GitRepositoryImpl.java
+++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryImpl.java
@@ -15,6 +15,7 @@
*/
package git4idea.repo;
+import com.intellij.dvcs.DvcsUtil;
import com.intellij.dvcs.repo.RepositoryImpl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
@@ -22,6 +23,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.vcs.log.util.StopWatch;
import git4idea.GitLocalBranch;
import git4idea.GitUtil;
import git4idea.GitVcs;
@@ -32,6 +34,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.Collection;
+import static com.intellij.dvcs.DvcsUtil.getShortRepositoryName;
import static com.intellij.util.ObjectUtils.assertNotNull;
public class GitRepositoryImpl extends RepositoryImpl implements GitRepository {
@@ -202,12 +205,14 @@ public class GitRepositoryImpl extends RepositoryImpl implements GitRepository {
@NotNull
private GitRepoInfo readRepoInfo() {
+ StopWatch sw = StopWatch.start("Reading Git repo info in " + getShortRepositoryName(this));
File configFile = myRepositoryFiles.getConfigFile();
GitConfig config = GitConfig.read(configFile);
Collection remotes = config.parseRemotes();
GitBranchState state = myReader.readState(remotes);
Collection trackInfos = config.parseTrackInfos(state.getLocalBranches().keySet(), state.getRemoteBranches().keySet());
Collection submodules = new GitModulesFileReader().read(getSubmoduleFile());
+ sw.report();
return new GitRepoInfo(state.getCurrentBranch(), state.getCurrentRevision(), state.getState(), remotes,
state.getLocalBranches(), state.getRemoteBranches(), trackInfos, submodules);
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExtensionsSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExtensionsSettings.java
index 038c9e73e670..e09c0997b274 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExtensionsSettings.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExtensionsSettings.java
@@ -69,7 +69,7 @@ public class GradleExtensionsSettings implements PersistentStateComponent 0;
+ }
+
public static boolean isJUnit5(@Nullable Module module, @Nullable SourceScope sourceScope, Project project) {
return JUnitUtil.isJUnit5(getScopeForJUnit(module, sourceScope, project), project);
}
diff --git a/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnit5EngineDetector.java b/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnit5EngineDetector.java
new file mode 100644
index 000000000000..324204c52817
--- /dev/null
+++ b/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnit5EngineDetector.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2017 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.rt.execution.junit;
+
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+public class JUnit5EngineDetector {
+
+ public static boolean hasCustomEngine() {
+ try {
+ Iterator iterator = ServiceLoader.load(Class.forName("org.junit.platform.engine.TestEngine")).iterator();
+ while (iterator.hasNext()) {
+ Object engine = iterator.next();
+ String engineClassName = engine.getClass().getName();
+ if (!"org.junit.jupiter.engine.JupiterTestEngine".equals(engineClassName) &&
+ !"org.junit.vintage.engine.VintageTestEngine".equals(engineClassName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ catch (Throwable e) {
+ return false;
+ }
+ }
+}
diff --git a/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitStarter.java b/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitStarter.java
index 332f409872aa..240d1d6bcc33 100644
--- a/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitStarter.java
+++ b/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitStarter.java
@@ -177,8 +177,13 @@ public class JUnitStarter {
public static boolean isJUnit5Preferred() {
final String useJUnit5 = System.getProperty(JUNIT5_KEY);
- final Boolean boolValue = useJUnit5 == null ? null : Boolean.valueOf(useJUnit5);
- return boolValue != null && boolValue.booleanValue();
+ if (useJUnit5 == null) {
+ return JUnit5EngineDetector.hasCustomEngine();
+ }
+ else {
+ final Boolean boolValue = Boolean.valueOf(useJUnit5);
+ return boolValue != null && boolValue.booleanValue();
+ }
}
public static boolean checkVersion(String[] args, PrintStream printStream) {
diff --git a/python/educational-core/src/com/jetbrains/edu/coursecreator/stepik/CCStepicConnector.java b/python/educational-core/src/com/jetbrains/edu/coursecreator/stepik/CCStepicConnector.java
index c6305c1090e3..1b45fb108668 100644
--- a/python/educational-core/src/com/jetbrains/edu/coursecreator/stepik/CCStepicConnector.java
+++ b/python/educational-core/src/com/jetbrains/edu/coursecreator/stepik/CCStepicConnector.java
@@ -15,9 +15,15 @@ import com.intellij.openapi.vfs.VirtualFileFilter;
import com.jetbrains.edu.learning.StudySerializationUtils;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.core.EduUtils;
-import com.jetbrains.edu.learning.courseFormat.*;
+import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
+import com.jetbrains.edu.learning.courseFormat.Course;
+import com.jetbrains.edu.learning.courseFormat.CourseInfo;
+import com.jetbrains.edu.learning.courseFormat.Lesson;
import com.jetbrains.edu.learning.courseFormat.tasks.Task;
-import com.jetbrains.edu.learning.stepic.*;
+import com.jetbrains.edu.learning.stepic.EduStepicAuthorizedClient;
+import com.jetbrains.edu.learning.stepic.EduStepicNames;
+import com.jetbrains.edu.learning.stepic.StepicUser;
+import com.jetbrains.edu.learning.stepic.StepicWrappers;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
@@ -135,7 +141,6 @@ public class CCStepicConnector {
task.setLesson(lesson);
task.setName(EduNames.PYCHARM_ADDITIONAL);
task.setIndex(1);
- task.setText(EduNames.PYCHARM_ADDITIONAL);
for (VirtualFile file : files) {
try {
if (file != null) {
diff --git a/python/educational-core/src/com/jetbrains/edu/learning/StudySerializationUtils.java b/python/educational-core/src/com/jetbrains/edu/learning/StudySerializationUtils.java
index 3f528eb32d84..c782034265d9 100644
--- a/python/educational-core/src/com/jetbrains/edu/learning/StudySerializationUtils.java
+++ b/python/educational-core/src/com/jetbrains/edu/learning/StudySerializationUtils.java
@@ -8,6 +8,7 @@ import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
@@ -441,11 +442,15 @@ public class StudySerializationUtils {
public static final String TASK_LIST = "task_list";
public static final String TASK_FILES = "task_files";
public static final String FILES = "files";
+ public static final String TESTS = "test";
+ public static final String TEXTS = "text";
public static final String HINTS = "hints";
public static final String SUBTASK_INFOS = "subtask_infos";
public static final String FORMAT_VERSION = "format_version";
public static final String INDEX = "index";
public static final String TASK_TYPE = "task_type";
+ public static final String NAME = "name";
+ public static final String LAST_SUBTASK = "last_subtask_index";
private Json() {
}
@@ -518,9 +523,11 @@ public class StudySerializationUtils {
switch (version) {
case 1:
stepOptionsJson = convertToSecondVersion(stepOptionsJson);
- // uncomment for future versions
- //case 2:
- // stepOptionsJson = convertToThirdVersion(stepOptionsJson);
+ case 2:
+ stepOptionsJson = convertToThirdVersion(stepOptionsJson);
+ // uncomment for future versions
+ //case 3:
+ // stepOptionsJson = convertToFourthVersion(stepOptionsJson);
}
convertSubtaskInfosToMap(stepOptionsJson);
StepicWrappers.StepOptions stepOptions =
@@ -530,6 +537,37 @@ public class StudySerializationUtils {
return stepOptions;
}
+ private JsonObject convertToThirdVersion(JsonObject stepOptionsJson) {
+ if (!stepOptionsJson.has(LAST_SUBTASK)) return stepOptionsJson;
+ final int lastSubtaskIndex = stepOptionsJson.get(LAST_SUBTASK).getAsInt();
+ if (lastSubtaskIndex == 0) return stepOptionsJson;
+ final JsonArray tests = stepOptionsJson.getAsJsonArray(TESTS);
+ if (tests.size() > 0) {
+ final JsonObject fileWrapper = tests.get(0).getAsJsonObject();
+ if (fileWrapper.has(NAME)) {
+ replaceWithSubtask(fileWrapper);
+ }
+ }
+ final JsonArray descriptions = stepOptionsJson.getAsJsonArray(TEXTS);
+ if (descriptions.size() > 0) {
+ final JsonObject fileWrapper = descriptions.get(0).getAsJsonObject();
+ if (fileWrapper.has(NAME)) {
+ replaceWithSubtask(fileWrapper);
+ }
+ }
+ return stepOptionsJson;
+ }
+
+ private void replaceWithSubtask(JsonObject fileWrapper) {
+ final String file = fileWrapper.get(NAME).getAsString();
+ final String extension = FileUtilRt.getExtension(file);
+ final String name = FileUtil.getNameWithoutExtension(file);
+ if (!name.contains(EduNames.SUBTASK_MARKER)) {
+ fileWrapper.remove(NAME);
+ fileWrapper.add(NAME, new JsonPrimitive(name + "_subtask0." + extension));
+ }
+ }
+
private static JsonObject convertSubtaskInfosToMap(JsonObject stepOptionsJson) {
final JsonArray files = stepOptionsJson.getAsJsonArray(FILES);
if (files != null) {
diff --git a/python/educational-core/src/com/jetbrains/edu/learning/StudyUtils.java b/python/educational-core/src/com/jetbrains/edu/learning/StudyUtils.java
index 7266ee194759..e2e06e430d59 100644
--- a/python/educational-core/src/com/jetbrains/edu/learning/StudyUtils.java
+++ b/python/educational-core/src/com/jetbrains/edu/learning/StudyUtils.java
@@ -64,7 +64,10 @@ import com.jetbrains.edu.learning.core.EduAnswerPlaceholderDeleteHandler;
import com.jetbrains.edu.learning.core.EduAnswerPlaceholderPainter;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.core.EduUtils;
-import com.jetbrains.edu.learning.courseFormat.*;
+import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
+import com.jetbrains.edu.learning.courseFormat.Course;
+import com.jetbrains.edu.learning.courseFormat.Lesson;
+import com.jetbrains.edu.learning.courseFormat.TaskFile;
import com.jetbrains.edu.learning.courseFormat.tasks.ChoiceTask;
import com.jetbrains.edu.learning.courseFormat.tasks.Task;
import com.jetbrains.edu.learning.courseFormat.tasks.TaskWithSubtasks;
@@ -492,7 +495,7 @@ public class StudyUtils {
return null;
}
final Course course = task.getLesson().getCourse();
- String text = task.getText() != null ? task.getText() : getTaskTextByTaskName(task, taskDirectory);
+ String text = task.getTaskDescription() != null ? task.getTaskDescription() : getTaskTextByTaskName(task, taskDirectory);
if (text == null) return null;
text = convertToHtml(text);
diff --git a/python/educational-core/src/com/jetbrains/edu/learning/courseFormat/tasks/Task.java b/python/educational-core/src/com/jetbrains/edu/learning/courseFormat/tasks/Task.java
index ed7f0c414ab5..d5b56e06dd01 100644
--- a/python/educational-core/src/com/jetbrains/edu/learning/courseFormat/tasks/Task.java
+++ b/python/educational-core/src/com/jetbrains/edu/learning/courseFormat/tasks/Task.java
@@ -5,11 +5,9 @@ import com.google.gson.annotations.SerializedName;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.xmlb.XmlSerializer;
import com.intellij.util.xmlb.annotations.Transient;
-import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.*;
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
@@ -37,7 +35,6 @@ public class Task implements StudyItem {
@SerializedName("task_files")
@Expose public Map taskFiles = new HashMap<>();
- private String text;
protected Map testsText = new HashMap<>();
protected Map taskTexts = new HashMap<>();
@@ -73,14 +70,6 @@ public class Task implements StudyItem {
this.name = name;
}
- public String getText() {
- return text;
- }
-
- public void setText(final String text) {
- this.text = text;
- }
-
@Override
public int getIndex() {
return myIndex;
@@ -166,20 +155,11 @@ public class Task implements StudyItem {
return null;
}
- @NotNull
- public String getTaskText(@NotNull final Project project) {
- if (!StringUtil.isEmptyOrSpaces(text)) return text;
- final VirtualFile taskDir = getTaskDir(project);
- if (taskDir != null) {
- final VirtualFile file = StudyUtils.findTaskDescriptionVirtualFile(project, taskDir);
- if (file == null) return "";
- final Document document = FileDocumentManager.getInstance().getDocument(file);
- if (document != null) {
- return document.getImmutableCharSequence().toString();
- }
+ public String getTaskDescription() {
+ if (!taskTexts.isEmpty()) {
+ return taskTexts.get(EduNames.TASK_HTML);
}
-
- return "";
+ return null;
}
@NotNull
@@ -207,7 +187,7 @@ public class Task implements StudyItem {
if (myIndex != task.myIndex) return false;
if (name != null ? !name.equals(task.name) : task.name != null) return false;
if (taskFiles != null ? !taskFiles.equals(task.taskFiles) : task.taskFiles != null) return false;
- if (text != null ? !text.equals(task.text) : task.text != null) return false;
+ if (taskTexts != null ? !taskTexts.equals(task.taskTexts) : task.taskTexts != null) return false;
if (testsText != null ? !testsText.equals(task.testsText) : task.testsText != null) return false;
return true;
@@ -218,7 +198,7 @@ public class Task implements StudyItem {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + myIndex;
result = 31 * result + (taskFiles != null ? taskFiles.hashCode() : 0);
- result = 31 * result + (text != null ? text.hashCode() : 0);
+ result = 31 * result + (taskTexts != null ? taskTexts.hashCode() : 0);
result = 31 * result + (testsText != null ? testsText.hashCode() : 0);
return result;
}
@@ -273,7 +253,6 @@ public class Task implements StudyItem {
setStatus(task.getStatus());
setStepId(task.getStepId());
taskFiles = task.getTaskFiles();
- setText(task.getText());
testsText = task.getTestsText();
taskTexts = task.getTaskTexts();
setLesson(task.getLesson());
diff --git a/python/educational-core/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java b/python/educational-core/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java
index fa240e513afb..58c82ec9b24f 100644
--- a/python/educational-core/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java
+++ b/python/educational-core/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java
@@ -28,12 +28,12 @@ import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.core.EduUtils;
import com.jetbrains.edu.learning.courseFormat.Course;
+import com.jetbrains.edu.learning.courseFormat.CourseInfo;
import com.jetbrains.edu.learning.courseFormat.Lesson;
-import com.jetbrains.edu.learning.courseFormat.tasks.Task;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
+import com.jetbrains.edu.learning.courseFormat.tasks.Task;
import com.jetbrains.edu.learning.editor.StudyEditor;
import com.jetbrains.edu.learning.statistics.EduUsagesCollector;
-import com.jetbrains.edu.learning.courseFormat.CourseInfo;
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
import com.jetbrains.edu.learning.stepic.StepicUpdateSettings;
import com.jetbrains.edu.learning.stepic.StepicUser;
@@ -291,24 +291,7 @@ public class StudyProjectGenerator {
}
}
createFiles(taskDirectory, task.getTestsText());
- if (task.getTaskTexts().isEmpty()) {
- createTaskHtml(task, taskDirectory);
- return;
- }
- task.setText(null);
createFiles(taskDirectory, task.getTaskTexts());
-
- }
-
- private static void createTaskHtml(@NotNull Task task, @NotNull File taskDirectory) {
- final File taskText = new File(taskDirectory, EduNames.TASK_HTML);
- FileUtil.createIfDoesntExist(taskText);
- try {
- FileUtil.writeToFile(taskText, task.getText());
- }
- catch (IOException e) {
- LOG.error(e);
- }
}
private static void createFiles(@NotNull File taskDirectory, Map files) {
diff --git a/python/educational-core/src/com/jetbrains/edu/learning/stepic/EduAdaptiveStepicConnector.java b/python/educational-core/src/com/jetbrains/edu/learning/stepic/EduAdaptiveStepicConnector.java
index d675c983cb84..db1dc541e2ce 100644
--- a/python/educational-core/src/com/jetbrains/edu/learning/stepic/EduAdaptiveStepicConnector.java
+++ b/python/educational-core/src/com/jetbrains/edu/learning/stepic/EduAdaptiveStepicConnector.java
@@ -174,7 +174,8 @@ public class EduAdaptiveStepicConnector {
private static Task getTheoryTaskFromStep(@NotNull String lessonName, @NotNull StepicWrappers.Step block, int stepId) {
final Task task = new TheoryTask(lessonName);
task.setStepId(stepId);
- task.setText(block.text);
+
+ task.addTaskText(EduNames.TASK_HTML, block.text);
createMockTaskFile(task, "# this is a theory task. You can use this editor as a playground");
return task;
@@ -186,7 +187,7 @@ public class EduAdaptiveStepicConnector {
int stepId, int userId) {
final ChoiceTask task = new ChoiceTask(lessonName);
task.setStepId(stepId);
- task.setText(block.text);
+ task.addTaskText(EduNames.TASK_HTML, block.text);
final StepicWrappers.AdaptiveAttemptWrapper.Attempt attempt = getAttemptForStep(stepId, userId);
if (attempt != null) {
@@ -338,7 +339,7 @@ public class EduAdaptiveStepicConnector {
}
final StudyToolWindow window = StudyUtils.getStudyToolWindow(project);
if (window != null) {
- window.setTaskText(StudyUtils.wrapTextToDisplayLatex(unsolvedTask.getText()), unsolvedTask.getTaskDir(project), project);
+ window.setTaskText(StudyUtils.wrapTextToDisplayLatex(unsolvedTask.getTaskDescription()), unsolvedTask.getTaskDir(project), project);
}
StudyNavigator.navigateToTask(project, lessonName, taskName);
}
@@ -425,32 +426,28 @@ public class EduAdaptiveStepicConnector {
int lessonID) {
final Task task = new CodeTask(name);
task.setStepId(lessonID);
- task.setText(step.text);
+
task.setStatus(StudyStatus.Unchecked);
+ final StringBuilder taskDescription = new StringBuilder(step.text);
if (step.options.samples != null) {
- final StringBuilder builder = new StringBuilder();
+ taskDescription.append("
");
for (List sample : step.options.samples) {
if (sample.size() == 2) {
- builder.append("Sample Input:
");
- builder.append(StringUtil.replace(sample.get(0), "\n", "
"));
- builder.append("
");
- builder.append("Sample Output:
");
- builder.append(StringUtil.replace(sample.get(1), "\n", "
"));
- builder.append("
");
+ taskDescription.append("Sample Input:
");
+ taskDescription.append(StringUtil.replace(sample.get(0), "\n", "
"));
+ taskDescription.append("
");
+ taskDescription.append("Sample Output:
");
+ taskDescription.append(StringUtil.replace(sample.get(1), "\n", "
"));
+ taskDescription.append("
");
}
}
- task.setText(task.getText() + "
" + builder.toString());
}
if (step.options.executionMemoryLimit != null && step.options.executionTimeLimit != null) {
- String builder = "Memory limit: " +
- step.options.executionMemoryLimit + " Mb" +
- "
" +
- "Time limit: " +
- step.options.executionTimeLimit + "s" +
- "
";
- task.setText(task.getText() + builder);
+ taskDescription.append("
").append("Memory limit: ").append(step.options.executionMemoryLimit).append(" Mb").append("
")
+ .append("Time limit: ").append(step.options.executionTimeLimit).append("s").append("
");
}
+ task.addTaskText(EduNames.TASK_HTML, taskDescription.toString());
if (step.options.test != null) {
for (StepicWrappers.FileWrapper wrapper : step.options.test) {
diff --git a/python/educational-core/src/com/jetbrains/edu/learning/stepic/EduStepicConnector.java b/python/educational-core/src/com/jetbrains/edu/learning/stepic/EduStepicConnector.java
index c9d046918286..b4e2f8b4107e 100644
--- a/python/educational-core/src/com/jetbrains/edu/learning/stepic/EduStepicConnector.java
+++ b/python/educational-core/src/com/jetbrains/edu/learning/stepic/EduStepicConnector.java
@@ -9,7 +9,11 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
-import com.jetbrains.edu.learning.courseFormat.*;
+import com.jetbrains.edu.learning.core.EduNames;
+import com.jetbrains.edu.learning.courseFormat.Course;
+import com.jetbrains.edu.learning.courseFormat.CourseInfo;
+import com.jetbrains.edu.learning.courseFormat.Lesson;
+import com.jetbrains.edu.learning.courseFormat.TaskFile;
import com.jetbrains.edu.learning.courseFormat.tasks.Task;
import com.jetbrains.edu.learning.courseFormat.tasks.TaskWithSubtasks;
import org.apache.http.HttpEntity;
@@ -288,7 +292,7 @@ public class EduStepicConnector {
task.addTaskText(wrapper.name, wrapper.text);
}
} else {
- task.setText(block.text);
+ task.addTaskText(EduNames.TASK_HTML, block.text);
}
task.taskFiles = new HashMap<>(); // TODO: it looks like we don't need taskFiles as map anymore
diff --git a/python/educational-core/src/com/jetbrains/edu/learning/stepic/StepicWrappers.java b/python/educational-core/src/com/jetbrains/edu/learning/stepic/StepicWrappers.java
index b2285b1c7683..b5a2065c3135 100644
--- a/python/educational-core/src/com/jetbrains/edu/learning/stepic/StepicWrappers.java
+++ b/python/educational-core/src/com/jetbrains/edu/learning/stepic/StepicWrappers.java
@@ -12,7 +12,10 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.core.EduUtils;
-import com.jetbrains.edu.learning.courseFormat.*;
+import com.jetbrains.edu.learning.courseFormat.Course;
+import com.jetbrains.edu.learning.courseFormat.CourseInfo;
+import com.jetbrains.edu.learning.courseFormat.Lesson;
+import com.jetbrains.edu.learning.courseFormat.TaskFile;
import com.jetbrains.edu.learning.courseFormat.tasks.Task;
import com.jetbrains.edu.learning.courseFormat.tasks.TaskWithSubtasks;
import org.apache.commons.codec.binary.Base64;
@@ -39,7 +42,6 @@ public class StepicWrappers {
public static Step fromTask(Project project, @NotNull final Task task) {
final Step step = new Step();
- step.text = task.getTaskText(project);
step.source = StepOptions.fromTask(project, task);
return step;
}
@@ -55,7 +57,7 @@ public class StepicWrappers {
@Expose Integer executionTimeLimit;
@Expose CodeTemplatesWrapper codeTemplates;
@SerializedName("format_version")
- @Expose public int formatVersion = 2;
+ @Expose public int formatVersion = 3;
@SerializedName("last_subtask_index")
@Expose int lastSubtaskIndex = 0;
diff --git a/python/educational-python/Edu-Python/src/com/jetbrains/edu/learning/PyStudyTestRunner.java b/python/educational-python/Edu-Python/src/com/jetbrains/edu/learning/PyStudyTestRunner.java
index 6e666a39040b..a24db818717f 100644
--- a/python/educational-python/Edu-Python/src/com/jetbrains/edu/learning/PyStudyTestRunner.java
+++ b/python/educational-python/Edu-Python/src/com/jetbrains/edu/learning/PyStudyTestRunner.java
@@ -31,7 +31,7 @@ public class PyStudyTestRunner extends StudyTestRunner {
Course course = myTask.getLesson().getCourse();
PyEduPluginConfigurator configurator = new PyEduPluginConfigurator();
String testsFileName = configurator.getTestFileName();
- if (myTask instanceof TaskWithSubtasks && ((TaskWithSubtasks)myTask).getActiveSubtaskIndex() != 0) {
+ if (myTask instanceof TaskWithSubtasks) {
testsFileName = FileUtil.getNameWithoutExtension(testsFileName);
int index = ((TaskWithSubtasks)myTask).getActiveSubtaskIndex();
testsFileName += EduNames.SUBTASK_MARKER + index + "." + FileUtilRt.getExtension(configurator.getTestFileName());
diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py b/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py
index a57783612595..cc6fa53ca178 100644
--- a/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py
+++ b/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py
@@ -103,7 +103,7 @@ USE_LIB_COPY = SUPPORT_GEVENT and \
(IS_PY3K and sys.version_info[1] >= 3))
-INTERACTIVE_MODE_AVAILABLE = os.getenv('DISPLAY') is not None
+INTERACTIVE_MODE_AVAILABLE = sys.platform in ('darwin', 'win32') or os.getenv('DISPLAY') is not None
def protect_libraries_from_patching():
diff --git a/xml/tests/src/com/intellij/psi/formatter/HtmlFormatterTest.java b/xml/tests/src/com/intellij/psi/formatter/HtmlFormatterTest.java
index 86df13403101..23fa64bc1b30 100644
--- a/xml/tests/src/com/intellij/psi/formatter/HtmlFormatterTest.java
+++ b/xml/tests/src/com/intellij/psi/formatter/HtmlFormatterTest.java
@@ -17,7 +17,6 @@ package com.intellij.psi.formatter;
import com.intellij.lang.html.HTMLLanguage;
import com.intellij.lang.injection.InjectedLanguageManager;
-import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.vfs.VirtualFile;
@@ -37,7 +36,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
-public class HtmlFormatterTest extends FormatterTestCase {
+public class HtmlFormatterTest extends XmlFormatterTestBase {
@Override
protected String getBasePath() {
return "psi/formatter/html";
@@ -263,11 +262,6 @@ public class HtmlFormatterTest extends FormatterTestCase {
doTestPerformance("html reformat with range", 5000, null);
}
- @Override
- protected String getTestDataPath() {
- return PathManager.getHomePath() + "/community/xml/tests/testData";
- }
-
public void doTestPerformance(@NotNull String message, int expectedTime, OptionsSetup optionsSetup) throws Exception {
CodeStyleSettings settings = new CodeStyleSettings();
if (optionsSetup != null) optionsSetup.setupOptions(settings);