mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -193,8 +193,14 @@ public class DebugProcessEvents extends DebugProcessImpl {
|
||||
// check if there is already one request with policy SUSPEND_ALL
|
||||
for (SuspendContextImpl context : getSuspendManager().getEventContexts()) {
|
||||
if (context.getSuspendPolicy() == EventRequest.SUSPEND_ALL) {
|
||||
eventSet.resume();
|
||||
return;
|
||||
for (Event event : eventSet) {
|
||||
if (event instanceof LocatableEvent && SuspendManagerUtil.isEvaluating(getSuspendManager(),
|
||||
getVirtualMachineProxy().getThreadReferenceProxy(
|
||||
((LocatableEvent)event).thread()))) {
|
||||
eventSet.resume();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.ToolWindowId;
|
||||
import com.intellij.openapi.wm.impl.status.StatusBarUtil;
|
||||
@@ -406,7 +407,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
// suspend policy to match the suspend policy of the context:
|
||||
// if all threads were suspended, then during stepping all the threads must be suspended
|
||||
// if only event thread were suspended, then only this particular thread must be suspended during stepping
|
||||
stepRequest.setSuspendPolicy(suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD? EventRequest.SUSPEND_EVENT_THREAD : EventRequest.SUSPEND_ALL);
|
||||
stepRequest.setSuspendPolicy(Registry.is("debugger.step.resumes.one.thread") ? EventRequest.SUSPEND_EVENT_THREAD
|
||||
: suspendContext.getSuspendPolicy());
|
||||
|
||||
if (hint != null) {
|
||||
//noinspection HardCodedStringLiteral
|
||||
@@ -1464,7 +1466,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
}
|
||||
}
|
||||
|
||||
private class StepOutCommand extends ResumeCommand {
|
||||
private class StepOutCommand extends StepCommand {
|
||||
private final int myStepSize;
|
||||
|
||||
public StepOutCommand(SuspendContextImpl suspendContext, int stepSize) {
|
||||
@@ -1489,7 +1491,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
}
|
||||
}
|
||||
|
||||
private class StepIntoCommand extends ResumeCommand {
|
||||
private class StepIntoCommand extends StepCommand {
|
||||
private final boolean myForcedIgnoreFilters;
|
||||
private final MethodFilter mySmartStepFilter;
|
||||
@Nullable
|
||||
@@ -1536,7 +1538,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
}
|
||||
}
|
||||
|
||||
private class StepOverCommand extends ResumeCommand {
|
||||
private class StepOverCommand extends StepCommand {
|
||||
private final boolean myIsIgnoreBreakpoints;
|
||||
private final int myStepSize;
|
||||
|
||||
@@ -1574,7 +1576,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
}
|
||||
}
|
||||
|
||||
private class RunToCursorCommand extends ResumeCommand {
|
||||
private class RunToCursorCommand extends StepCommand {
|
||||
private final RunToCursorBreakpoint myRunToCursorBreakpoint;
|
||||
private final boolean myIgnoreBreakpoints;
|
||||
|
||||
@@ -1622,9 +1624,27 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ResumeCommand extends SuspendContextCommandImpl {
|
||||
private abstract class StepCommand extends ResumeCommand {
|
||||
public StepCommand(SuspendContextImpl suspendContext) {
|
||||
super(suspendContext);
|
||||
}
|
||||
|
||||
private final ThreadReferenceProxyImpl myContextThread;
|
||||
@Override
|
||||
protected void resumeAction() {
|
||||
SuspendContextImpl context = getSuspendContext();
|
||||
if (context != null
|
||||
&& Registry.is("debugger.step.resumes.one.thread")
|
||||
&& context.getSuspendPolicy() == EventRequest.SUSPEND_ALL) {
|
||||
getSuspendManager().resumeThread(context, myContextThread);
|
||||
}
|
||||
else {
|
||||
super.resumeAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ResumeCommand extends SuspendContextCommandImpl {
|
||||
protected final ThreadReferenceProxyImpl myContextThread;
|
||||
|
||||
public ResumeCommand(SuspendContextImpl suspendContext) {
|
||||
super(suspendContext);
|
||||
@@ -1640,10 +1660,14 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
@Override
|
||||
public void contextAction() {
|
||||
showStatusText(DebuggerBundle.message("status.process.resumed"));
|
||||
getSuspendManager().resume(getSuspendContext());
|
||||
resumeAction();
|
||||
myDebugProcessDispatcher.getMulticaster().resumed(getSuspendContext());
|
||||
}
|
||||
|
||||
protected void resumeAction() {
|
||||
getSuspendManager().resume(getSuspendContext());
|
||||
}
|
||||
|
||||
public ThreadReferenceProxyImpl getContextThread() {
|
||||
return myContextThread;
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ public class SuspendManagerImpl implements SuspendManager {
|
||||
|
||||
@Override
|
||||
public void resumeThread(SuspendContextImpl context, ThreadReferenceProxyImpl thread) {
|
||||
LOG.assertTrue(thread != context.getThread(), "Use resume() instead of resuming breakpoint thread");
|
||||
//LOG.assertTrue(thread != context.getThread(), "Use resume() instead of resuming breakpoint thread");
|
||||
LOG.assertTrue(!context.isExplicitlyResumed(thread));
|
||||
|
||||
if(context.myResumedThreads == null) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.jetbrains.ide
|
||||
|
||||
import com.intellij.openapi.application.invokeAndWaitIfNeed
|
||||
import com.intellij.openapi.application.writeAction
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||
import com.intellij.openapi.util.io.FileUtilRt
|
||||
@@ -68,7 +68,7 @@ class TestManager(val projectFixture: IdeaProjectTestFixture) : TestWatcher() {
|
||||
val normalizedFilePath = FileUtilRt.toSystemIndependentName(filePath!!)
|
||||
if (annotation!!.relativeToProject) {
|
||||
val root = projectFixture.getProject().getBaseDir()
|
||||
writeAction {
|
||||
runWriteAction {
|
||||
fileToDelete = root.findOrCreateChildData(this@TestManager, normalizedFilePath)
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,7 @@ class TestManager(val projectFixture: IdeaProjectTestFixture) : TestWatcher() {
|
||||
ModuleRootModificationUtil.updateModel(projectFixture.getModule()) { model ->
|
||||
val contentEntry = model.getContentEntries()[0]
|
||||
val contentRoot = contentEntry.getFile()!!
|
||||
writeAction {
|
||||
runWriteAction {
|
||||
contentRoot.findChild(EXCLUDED_DIR_NAME)?.delete(this@TestManager)
|
||||
fileToDelete = contentRoot.createChildDirectory(this@TestManager, EXCLUDED_DIR_NAME)
|
||||
fileToDelete!!.createChildData(this@TestManager, normalizedFilePath)
|
||||
@@ -89,7 +89,7 @@ class TestManager(val projectFixture: IdeaProjectTestFixture) : TestWatcher() {
|
||||
}
|
||||
else {
|
||||
val root = ModuleRootManager.getInstance(projectFixture.getModule()).getSourceRoots()[0]
|
||||
writeAction {
|
||||
runWriteAction {
|
||||
fileToDelete = root.findOrCreateChildData(this@TestManager, normalizedFilePath)
|
||||
}
|
||||
}
|
||||
@@ -103,7 +103,7 @@ class TestManager(val projectFixture: IdeaProjectTestFixture) : TestWatcher() {
|
||||
}
|
||||
|
||||
if (fileToDelete != null) {
|
||||
invokeAndWaitIfNeed { writeAction { fileToDelete?.delete(this@TestManager) } }
|
||||
invokeAndWaitIfNeed { runWriteAction { fileToDelete?.delete(this@TestManager) } }
|
||||
fileToDelete = null
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,10 @@ package com.intellij.openapi.application
|
||||
|
||||
import javax.swing.SwingUtilities
|
||||
|
||||
public inline fun writeAction(runnable: () -> Unit) {
|
||||
/**
|
||||
* @exclude Internal use only
|
||||
*/
|
||||
public inline fun runWriteAction(runnable: () -> Unit) {
|
||||
val token = WriteAction.start()
|
||||
try {
|
||||
runnable()
|
||||
@@ -27,6 +30,9 @@ public inline fun writeAction(runnable: () -> Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @exclude Internal use only
|
||||
*/
|
||||
public fun invokeAndWaitIfNeed(runnable: () -> Unit) {
|
||||
val app = ApplicationManager.getApplication()
|
||||
if (app == null) {
|
||||
|
||||
@@ -19,7 +19,7 @@ import com.intellij.openapi.application.AccessToken
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.WriteAction
|
||||
import com.intellij.openapi.application.ex.DecodeDefaultsUtil
|
||||
import com.intellij.openapi.application.writeAction
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.components.RoamingType
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.components.impl.stores.DirectoryBasedStorage
|
||||
@@ -527,7 +527,8 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
|
||||
if (renamed) {
|
||||
file = dir.findChild(externalInfo!!.fileName)
|
||||
if (file != null) {
|
||||
writeAction {
|
||||
runWriteAction { }
|
||||
runWriteAction {
|
||||
file!!.rename(this, fileName)
|
||||
}
|
||||
}
|
||||
@@ -537,7 +538,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
|
||||
file = DirectoryBasedStorage.getFile(fileName, dir, this)
|
||||
}
|
||||
|
||||
writeAction {
|
||||
runWriteAction {
|
||||
file!!.getOutputStream(this).use {
|
||||
byteOut.writeTo(it)
|
||||
}
|
||||
|
||||
@@ -194,6 +194,7 @@ debugger.batch.evaluation=false
|
||||
debugger.compiling.evaluator=true
|
||||
debugger.watches.in.variables=false
|
||||
debugger.auto.fetch.icons=true
|
||||
debugger.step.resumes.one.thread=false
|
||||
|
||||
analyze.exceptions.on.the.fly=false
|
||||
analyze.exceptions.on.the.fly.description=Automatically analyze clipboard on frame activation,\
|
||||
|
||||
@@ -85,7 +85,7 @@ public abstract class RecursionGuard {
|
||||
*
|
||||
* @param since the id of a computation whose result is safe to cache whilst for more nested ones it's not.
|
||||
*/
|
||||
public abstract void prohibitResultCaching(Object since);
|
||||
public abstract void prohibitResultCaching(@NotNull Object since);
|
||||
|
||||
public interface StackStamp {
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ public class RecursionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prohibitResultCaching(Object since) {
|
||||
public void prohibitResultCaching(@NotNull Object since) {
|
||||
MyKey realKey = new MyKey(id, since, false);
|
||||
final CalculationStack stack = ourStack.get();
|
||||
stack.enableMemoization(realKey, stack.prohibitResultCaching(realKey));
|
||||
|
||||
@@ -27,26 +27,16 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class MessageBusFactory {
|
||||
|
||||
private static final AtomicReference<Impl> ourImpl = new AtomicReference<Impl>(new Impl() {
|
||||
@NotNull
|
||||
@Override
|
||||
public MessageBus newMessageBus(@NotNull Object owner) {
|
||||
return new MessageBusImpl.RootBus(owner);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public MessageBus newMessageBus(@NotNull Object owner, @Nullable MessageBus parentBus) {
|
||||
return parentBus == null ? newMessageBus(owner) : new MessageBusImpl(owner, parentBus);
|
||||
}
|
||||
});
|
||||
private static final AtomicReference<Impl> ourImpl = new AtomicReference<Impl>(Impl.DEFAULT);
|
||||
|
||||
private MessageBusFactory() {}
|
||||
|
||||
@NotNull
|
||||
public static MessageBus newMessageBus(@NotNull Object owner) {
|
||||
return ourImpl.get().newMessageBus(owner);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static MessageBus newMessageBus(@NotNull Object owner, @Nullable MessageBus parentBus) {
|
||||
return ourImpl.get().newMessageBus(owner, parentBus);
|
||||
}
|
||||
@@ -57,6 +47,20 @@ public class MessageBusFactory {
|
||||
|
||||
public interface Impl {
|
||||
|
||||
Impl DEFAULT = new Impl() {
|
||||
@NotNull
|
||||
@Override
|
||||
public MessageBus newMessageBus(@NotNull Object owner) {
|
||||
return new MessageBusImpl.RootBus(owner);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public MessageBus newMessageBus(@NotNull Object owner, @Nullable MessageBus parentBus) {
|
||||
return parentBus == null ? newMessageBus(owner) : new MessageBusImpl(owner, parentBus);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
MessageBus newMessageBus(@NotNull Object owner);
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ import java.util.List;
|
||||
* @author yole
|
||||
*/
|
||||
public class PyImportOptimizer implements ImportOptimizer {
|
||||
private static final boolean SORT_IMPORTS = true;
|
||||
|
||||
@Override
|
||||
public boolean supports(PsiFile file) {
|
||||
return true;
|
||||
@@ -148,9 +150,11 @@ public class PyImportOptimizer implements ImportOptimizer {
|
||||
}
|
||||
|
||||
private void applyResults() {
|
||||
Collections.sort(myBuiltinImports, AddImportHelper.IMPORT_BY_NAME_COMPARATOR);
|
||||
Collections.sort(myThirdPartyImports, AddImportHelper.IMPORT_BY_NAME_COMPARATOR);
|
||||
Collections.sort(myProjectImports, AddImportHelper.IMPORT_BY_NAME_COMPARATOR);
|
||||
if (SORT_IMPORTS) {
|
||||
Collections.sort(myBuiltinImports, AddImportHelper.IMPORT_BY_NAME_COMPARATOR);
|
||||
Collections.sort(myThirdPartyImports, AddImportHelper.IMPORT_BY_NAME_COMPARATOR);
|
||||
Collections.sort(myProjectImports, AddImportHelper.IMPORT_BY_NAME_COMPARATOR);
|
||||
}
|
||||
|
||||
markGroupBegin(myThirdPartyImports);
|
||||
markGroupBegin(myProjectImports);
|
||||
|
||||
@@ -32,13 +32,11 @@ import com.jetbrains.python.PyElementTypes;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonDialectsTokenSetProvider;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static com.jetbrains.python.formatter.PyCodeStyleSettings.DICT_ALIGNMENT_ON_COLON;
|
||||
import static com.jetbrains.python.formatter.PyCodeStyleSettings.DICT_ALIGNMENT_ON_VALUE;
|
||||
@@ -88,6 +86,7 @@ public class PyBlock implements ASTBlock {
|
||||
private final Wrap myWrap;
|
||||
private final PyBlockContext myContext;
|
||||
private List<PyBlock> mySubBlocks = null;
|
||||
private Map<ASTNode, PyBlock> mySubBlockByNode = null;
|
||||
private Alignment myChildAlignment;
|
||||
private final Alignment myDictAlignment;
|
||||
private final Wrap myDictWrapping;
|
||||
@@ -137,16 +136,28 @@ public class PyBlock implements ASTBlock {
|
||||
@NotNull
|
||||
public List<Block> getSubBlocks() {
|
||||
if (mySubBlocks == null) {
|
||||
mySubBlocks = buildSubBlocks();
|
||||
mySubBlockByNode = buildSubBlocks();
|
||||
mySubBlocks = new ArrayList<PyBlock>(mySubBlockByNode.values());
|
||||
if (DUMP_FORMATTING_BLOCKS) {
|
||||
dumpSubBlocks();
|
||||
}
|
||||
}
|
||||
return new ArrayList<Block>(mySubBlocks);
|
||||
return Collections.<Block>unmodifiableList(mySubBlocks);
|
||||
}
|
||||
|
||||
private List<PyBlock> buildSubBlocks() {
|
||||
final List<PyBlock> blocks = new ArrayList<PyBlock>();
|
||||
@Nullable
|
||||
private PyBlock getSubBlockByNode(@NotNull ASTNode node) {
|
||||
return mySubBlockByNode.get(node);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PyBlock getSubBlockByIndex(int index) {
|
||||
return mySubBlocks.get(index);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Map<ASTNode, PyBlock> buildSubBlocks() {
|
||||
final Map<ASTNode, PyBlock> blocks = new LinkedHashMap<ASTNode, PyBlock>();
|
||||
for (ASTNode child = myNode.getFirstChildNode(); child != null; child = child.getTreeNext()) {
|
||||
|
||||
final IElementType childType = child.getElementType();
|
||||
@@ -157,9 +168,9 @@ public class PyBlock implements ASTBlock {
|
||||
continue;
|
||||
}
|
||||
|
||||
blocks.add(buildSubBlock(child));
|
||||
blocks.put(child, buildSubBlock(child));
|
||||
}
|
||||
return Collections.unmodifiableList(blocks);
|
||||
return Collections.unmodifiableMap(blocks);
|
||||
}
|
||||
|
||||
private PyBlock buildSubBlock(ASTNode child) {
|
||||
@@ -685,9 +696,22 @@ public class PyBlock implements ASTBlock {
|
||||
public Spacing getSpacing(Block child1, @NotNull Block child2) {
|
||||
if (child1 instanceof ASTBlock && child2 instanceof ASTBlock) {
|
||||
final ASTNode node1 = ((ASTBlock)child1).getNode();
|
||||
final PsiElement psi1 = node1.getPsi();
|
||||
final PsiElement psi2 = ((ASTBlock)child2).getNode().getPsi();
|
||||
ASTNode node2 = ((ASTBlock)child2).getNode();
|
||||
final IElementType childType1 = node1.getElementType();
|
||||
final PsiElement psi1 = node1.getPsi();
|
||||
|
||||
PsiElement psi2 = node2.getPsi();
|
||||
// skip not inline comments to handles blank lines between various declarations
|
||||
if (psi2 instanceof PsiComment && hasLineBreaksBefore(node2, 1)) {
|
||||
final PsiElement nonCommentAfter = PyPsiUtils.getNextNonCommentSibling(psi2, true);
|
||||
if (nonCommentAfter != null) {
|
||||
psi2 = nonCommentAfter;
|
||||
}
|
||||
}
|
||||
node2 = psi2.getNode();
|
||||
final IElementType childType2 = psi2.getNode().getElementType();
|
||||
//noinspection ConstantConditions
|
||||
child2 = getSubBlockByNode(node2);
|
||||
|
||||
final CommonCodeStyleSettings settings = myContext.getSettings();
|
||||
if (childType1 == PyTokenTypes.COLON && psi2 instanceof PyStatementList) {
|
||||
@@ -696,8 +720,8 @@ public class PyBlock implements ASTBlock {
|
||||
}
|
||||
}
|
||||
|
||||
if ((PyElementTypes.CLASS_OR_FUNCTION.contains(childType1) && hasTypeIgnoringPrecedingComments(psi2, STATEMENT_OR_DECLARATION)) ||
|
||||
STATEMENT_OR_DECLARATION.contains(childType1) && hasTypeIgnoringPrecedingComments(psi2, PyElementTypes.CLASS_OR_FUNCTION)) {
|
||||
if ((PyElementTypes.CLASS_OR_FUNCTION.contains(childType1) && STATEMENT_OR_DECLARATION.contains(childType2)) ||
|
||||
STATEMENT_OR_DECLARATION.contains(childType1) && PyElementTypes.CLASS_OR_FUNCTION.contains(childType2)) {
|
||||
if (PyUtil.isTopLevel(psi1)) {
|
||||
return getBlankLinesForOption(myContext.getPySettings().BLANK_LINES_AROUND_TOP_LEVEL_CLASSES_FUNCTIONS);
|
||||
}
|
||||
@@ -725,17 +749,6 @@ public class PyBlock implements ASTBlock {
|
||||
return myContext.getSpacingBuilder().getSpacing(this, child1, child2);
|
||||
}
|
||||
|
||||
private static boolean hasTypeIgnoringPrecedingComments(@NotNull PsiElement element, @NotNull TokenSet types) {
|
||||
if (element instanceof PsiComment) {
|
||||
final PsiElement psi3 = PsiTreeUtil.getNextSiblingOfType(element, PyElement.class);
|
||||
if (psi3 != null) {
|
||||
final IElementType type3 = psi3.getNode().getElementType();
|
||||
return types.contains(type3);
|
||||
}
|
||||
}
|
||||
return types.contains(element.getNode().getElementType());
|
||||
}
|
||||
|
||||
private Spacing getBlankLinesForOption(final int option) {
|
||||
final int blankLines = option + 1;
|
||||
return Spacing.createSpacing(0, 0, blankLines,
|
||||
@@ -762,7 +775,7 @@ public class PyBlock implements ASTBlock {
|
||||
return ChildAttributes.DELEGATE_TO_PREV_CHILD;
|
||||
}
|
||||
|
||||
final PyBlock insertAfterBlock = mySubBlocks.get(newChildIndex - 1);
|
||||
final PyBlock insertAfterBlock = getSubBlockByIndex(newChildIndex - 1);
|
||||
|
||||
final ASTNode prevNode = insertAfterBlock.getNode();
|
||||
final PsiElement prevElt = prevNode.getPsi();
|
||||
@@ -950,11 +963,10 @@ public class PyBlock implements ASTBlock {
|
||||
return null;
|
||||
}
|
||||
int prevIndex = newChildIndex - 1;
|
||||
while (prevIndex > 0 && mySubBlocks.get(prevIndex).getNode().getElementType() == PyTokenTypes.END_OF_LINE_COMMENT) {
|
||||
while (prevIndex > 0 && getSubBlockByIndex(prevIndex).getNode().getElementType() == PyTokenTypes.END_OF_LINE_COMMENT) {
|
||||
prevIndex--;
|
||||
}
|
||||
final PyBlock insertAfterBlock = mySubBlocks.get(prevIndex);
|
||||
return insertAfterBlock.getNode();
|
||||
return getSubBlockByIndex(prevIndex).getNode();
|
||||
}
|
||||
|
||||
private static ASTNode getLastNonSpaceChild(ASTNode node, boolean acceptError) {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
class MyClass:
|
||||
pass
|
||||
@@ -0,0 +1,7 @@
|
||||
from collections import OrderedDict
|
||||
import sys
|
||||
|
||||
from m1 import MyClass
|
||||
|
||||
# comment
|
||||
print(sys, OrderedDict, MyClass)
|
||||
@@ -0,0 +1,7 @@
|
||||
from collections import OrderedDict
|
||||
import sys
|
||||
|
||||
from m1 import MyClass
|
||||
|
||||
# comment
|
||||
print(sys, OrderedDict, MyClass)
|
||||
@@ -72,9 +72,23 @@ public class PyOptimizeImportsTest extends PyTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
myFixture.configureByFile("optimizeImports/" + getTestName(true) + ".py");
|
||||
// PY-16351
|
||||
public void testNoExtraBlankLineAfterImportBlock() {
|
||||
final String testName = getTestName(true);
|
||||
myFixture.copyDirectoryToProject(testName, "");
|
||||
myFixture.configureByFile("main.py");
|
||||
OptimizeImportsAction.actionPerformedImpl(DataManager.getInstance().getDataContext(myFixture.getEditor().getContentComponent()));
|
||||
myFixture.checkResultByFile("optimizeImports/" + getTestName(true) + ".after.py");
|
||||
myFixture.checkResultByFile(testName + "/main.after.py");
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
myFixture.configureByFile(getTestName(true) + ".py");
|
||||
OptimizeImportsAction.actionPerformedImpl(DataManager.getInstance().getDataContext(myFixture.getEditor().getContentComponent()));
|
||||
myFixture.checkResultByFile(getTestName(true) + ".after.py");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return super.getTestDataPath() + "/optimizeImports";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user