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);