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:
@@ -180,7 +180,7 @@ class RegExpEquivalenceChecker {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean areBranchesEquivalent(RegExpBranch branch1, RegExpBranch branch2) {
|
||||
private static boolean areBranchesEquivalent(RegExpBranch branch1, RegExpBranch branch2) {
|
||||
final RegExpAtom[] atoms1 = branch1.getAtoms();
|
||||
final RegExpAtom[] atoms2 = branch2.getAtoms();
|
||||
if (atoms1.length != atoms2.length) {
|
||||
@@ -194,7 +194,7 @@ class RegExpEquivalenceChecker {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean areCharsEquivalent(RegExpChar aChar1, RegExpChar aChar2) {
|
||||
private static boolean areCharsEquivalent(RegExpChar aChar1, RegExpChar aChar2) {
|
||||
return aChar1.getValue() == aChar2.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,6 +178,15 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
|
||||
}
|
||||
|
||||
PsiCallExpression methodCall = findCallAtOffset(context, context.getOffset(refStart));
|
||||
// make sure this is the method call we've just added, not the enclosing one
|
||||
if (methodCall != null) {
|
||||
PsiElement completedElement = methodCall instanceof PsiMethodCallExpression ?
|
||||
((PsiMethodCallExpression)methodCall).getMethodExpression().getReferenceNameElement() : null;
|
||||
TextRange completedElementRange = completedElement == null ? null : completedElement.getTextRange();
|
||||
if (completedElementRange == null || completedElementRange.getStartOffset() != context.getStartOffset()) {
|
||||
methodCall = null;
|
||||
}
|
||||
}
|
||||
if (methodCall != null) {
|
||||
CompletionMemory.registerChosenMethod(method, methodCall);
|
||||
handleNegation(context, document, method, methodCall);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -56,7 +56,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
@SuppressWarnings("UnusedDeclaration") // Upsource and Kotlin
|
||||
public class JavaCoreApplicationEnvironment extends CoreApplicationEnvironment {
|
||||
public JavaCoreApplicationEnvironment(@NotNull Disposable parentDisposable) {
|
||||
super(parentDisposable);
|
||||
this(parentDisposable, true);
|
||||
}
|
||||
|
||||
public JavaCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
super(parentDisposable, unitTestMode);
|
||||
|
||||
registerFileType(JavaClassFileType.INSTANCE, "class");
|
||||
registerFileType(JavaFileType.INSTANCE, "java");
|
||||
|
||||
@@ -106,6 +106,22 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase {
|
||||
myFixture.checkResult("class C { void m() { Character.toChars(123, <caret>, ) } }");
|
||||
}
|
||||
|
||||
public void testNoHintsForMethodReference() {
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, "class C {\n" +
|
||||
" interface I { void i(int p); }\n" +
|
||||
" void referenced(int a) {}\n" +
|
||||
" void m(I lambda) {}\n" +
|
||||
" void m2() { m(this::<caret>) }\n" +
|
||||
"}");
|
||||
complete("referenced");
|
||||
myFixture.checkResultWithInlays("class C {\n" +
|
||||
" interface I { void i(int p); }\n" +
|
||||
" void referenced(int a) {}\n" +
|
||||
" void m(I lambda) {}\n" +
|
||||
" void m2() { m(this::referenced) }\n" +
|
||||
"}");
|
||||
}
|
||||
|
||||
private void showParameterInfo() {
|
||||
myFixture.performEditorAction("ParameterInfo");
|
||||
UIUtil.dispatchAllInvocationEvents();
|
||||
|
||||
@@ -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.
|
||||
@@ -33,7 +33,6 @@ import com.intellij.openapi.application.impl.ApplicationInfoImpl;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.impl.CoreCommandProcessor;
|
||||
import com.intellij.openapi.components.ExtensionAreas;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
import com.intellij.openapi.extensions.ExtensionPoint;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
@@ -42,7 +41,6 @@ import com.intellij.openapi.extensions.ExtensionsArea;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeExtension;
|
||||
import com.intellij.openapi.fileTypes.FileTypeRegistry;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.impl.CoreProgressManager;
|
||||
@@ -67,7 +65,6 @@ import com.intellij.psi.meta.MetaDataRegistrar;
|
||||
import com.intellij.psi.stubs.CoreStubTreeLoader;
|
||||
import com.intellij.psi.stubs.StubTreeLoader;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.picocontainer.MutablePicoContainer;
|
||||
@@ -87,9 +84,15 @@ public class CoreApplicationEnvironment {
|
||||
private final CoreLocalFileSystem myLocalFileSystem;
|
||||
protected final VirtualFileSystem myJarFileSystem;
|
||||
@NotNull private final Disposable myParentDisposable;
|
||||
private final boolean myUnitTestMode;
|
||||
|
||||
public CoreApplicationEnvironment(@NotNull Disposable parentDisposable) {
|
||||
this(parentDisposable, true);
|
||||
}
|
||||
|
||||
public CoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
myParentDisposable = parentDisposable;
|
||||
myUnitTestMode = unitTestMode;
|
||||
|
||||
myFileTypeRegistry = new CoreFileTypeRegistry();
|
||||
|
||||
@@ -138,7 +141,12 @@ public class CoreApplicationEnvironment {
|
||||
|
||||
@NotNull
|
||||
protected MockApplication createApplication(@NotNull Disposable parentDisposable) {
|
||||
return new MockApplicationEx(parentDisposable);
|
||||
return new MockApplicationEx(parentDisposable) {
|
||||
@Override
|
||||
public boolean isUnitTestMode() {
|
||||
return myUnitTestMode;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
package com.intellij.psi.impl.smartPointers;
|
||||
|
||||
import com.intellij.lang.LanguageUtil;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.ProperTextRange;
|
||||
import com.intellij.openapi.util.Segment;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
@@ -88,7 +90,7 @@ class AnchorElementInfo extends SelfElementInfo {
|
||||
return packed1 == packed2;
|
||||
}
|
||||
if (packed1 != -1 || packed2 != -1) {
|
||||
return areRestoredElementsEqual(other);
|
||||
return ReadAction.compute(() -> Comparing.equal(restoreElement(), other.restoreElement()));
|
||||
}
|
||||
}
|
||||
return super.pointsToTheSameElementAs(other);
|
||||
|
||||
@@ -55,10 +55,7 @@ class DirElementInfo extends SmartPointerElementInfo {
|
||||
|
||||
@Override
|
||||
public boolean pointsToTheSameElementAs(@NotNull SmartPointerElementInfo other) {
|
||||
if (other instanceof DirElementInfo) {
|
||||
return Comparing.equal(myVirtualFile, ((DirElementInfo)other).myVirtualFile);
|
||||
}
|
||||
return Comparing.equal(restoreElement(), other.restoreElement());
|
||||
return other instanceof DirElementInfo && Comparing.equal(myVirtualFile, ((DirElementInfo)other).myVirtualFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -66,14 +66,7 @@ class FileElementInfo extends SmartPointerElementInfo {
|
||||
|
||||
@Override
|
||||
public boolean pointsToTheSameElementAs(@NotNull SmartPointerElementInfo other) {
|
||||
if (other instanceof FileElementInfo) {
|
||||
return Comparing.equal(myVirtualFile, ((FileElementInfo)other).myVirtualFile);
|
||||
}
|
||||
if (other instanceof SelfElementInfo || other instanceof ClsElementInfo) {
|
||||
// optimisation: SelfElementInfo need psi (parsing) for element restoration and apriori could not reference psi file
|
||||
return false;
|
||||
}
|
||||
return Comparing.equal(restoreElement(), other.restoreElement());
|
||||
return other instanceof FileElementInfo && Comparing.equal(myVirtualFile, ((FileElementInfo)other).myVirtualFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.smartPointers;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Segment;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -57,12 +54,7 @@ class HardElementInfo extends SmartPointerElementInfo {
|
||||
|
||||
@Override
|
||||
public boolean pointsToTheSameElementAs(@NotNull final SmartPointerElementInfo other) {
|
||||
return Comparing.equal(myElement, ApplicationManager.getApplication().runReadAction(new Computable<PsiElement>() {
|
||||
@Override
|
||||
public PsiElement compute() {
|
||||
return other.restoreElement();
|
||||
}
|
||||
}));
|
||||
return other instanceof HardElementInfo && myElement.equals(((HardElementInfo)other).myElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -192,13 +192,7 @@ public class SelfElementInfo extends SmartPointerElementInfo {
|
||||
&& range1.getEndOffset() == range2.getEndOffset();
|
||||
});
|
||||
}
|
||||
return areRestoredElementsEqual(other);
|
||||
}
|
||||
|
||||
boolean areRestoredElementsEqual(@NotNull final SmartPointerElementInfo other) {
|
||||
return ApplicationManager.getApplication().runReadAction(
|
||||
(Computable<Boolean>)() -> Comparing.equal(getVirtualFile(), other.getVirtualFile())
|
||||
&& Comparing.equal(restoreElement(), other.restoreElement()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -31,10 +31,12 @@ import static org.jetbrains.concurrency.Promises.rejectedPromise;
|
||||
*/
|
||||
public abstract class RunProfileStarter {
|
||||
@Nullable
|
||||
public abstract RunContentDescriptor execute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException;
|
||||
@Deprecated
|
||||
public RunContentDescriptor execute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Async version of {@link #execute(RunProfileState, ExecutionEnvironment)}.
|
||||
* You must NOT throw exceptions in this method.
|
||||
* Instead return {@link org.jetbrains.concurrency.Promises#rejectedPromise(Throwable)} or call {@link org.jetbrains.concurrency.AsyncPromise#setError(Throwable)}
|
||||
*/
|
||||
|
||||
+5
-24
@@ -16,23 +16,24 @@
|
||||
package com.intellij.execution.runners;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.ExecutionManager;
|
||||
import com.intellij.execution.Executor;
|
||||
import com.intellij.execution.RunProfileStarter;
|
||||
import com.intellij.execution.configurations.RunProfileState;
|
||||
import com.intellij.execution.configurations.RunnerSettings;
|
||||
import com.intellij.execution.ui.RunContentDescriptor;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.concurrency.Promise;
|
||||
|
||||
import static com.intellij.execution.runners.GenericProgramRunnerKt.startRunProfile;
|
||||
|
||||
/**
|
||||
* Allows to postpone actual {@link RunProfileState} execution until all the needed preparations are done.
|
||||
* @deprecated Use AsyncProgramRunner
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AsyncGenericProgramRunner<Settings extends RunnerSettings> extends BaseProgramRunner<Settings> {
|
||||
@Override
|
||||
protected void execute(@NotNull ExecutionEnvironment environment,
|
||||
protected final void execute(@NotNull ExecutionEnvironment environment,
|
||||
@Nullable Callback callback,
|
||||
@NotNull RunProfileState state) throws ExecutionException {
|
||||
prepare(environment, state)
|
||||
@@ -57,24 +58,4 @@ public abstract class AsyncGenericProgramRunner<Settings extends RunnerSettings>
|
||||
*/
|
||||
@NotNull
|
||||
protected abstract Promise<RunProfileStarter> prepare(@NotNull ExecutionEnvironment environment, @NotNull RunProfileState state) throws ExecutionException;
|
||||
|
||||
private static void startRunProfile(@NotNull ExecutionEnvironment environment,
|
||||
@NotNull RunProfileState state,
|
||||
@Nullable final Callback callback,
|
||||
@Nullable final RunProfileStarter starter) {
|
||||
ExecutionManager.getInstance(environment.getProject()).startRunProfile(new RunProfileStarter() {
|
||||
@Override
|
||||
public Promise<RunContentDescriptor> executeAsync(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) {
|
||||
if (starter == null) {
|
||||
return Promise.resolve(postProcess(environment, null, callback));
|
||||
}
|
||||
return starter.executeAsync(state, environment).then(descriptor -> postProcess(environment, descriptor, callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public RunContentDescriptor execute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException {
|
||||
return postProcess(environment, starter == null ? null : starter.execute(state, environment), callback);
|
||||
}
|
||||
}, state, environment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* 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.execution.runners;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.ExecutionManager;
|
||||
import com.intellij.execution.RunProfileStarter;
|
||||
import com.intellij.execution.configurations.RunProfileState;
|
||||
import com.intellij.execution.configurations.RunnerSettings;
|
||||
import com.intellij.execution.ui.RunContentDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class GenericProgramRunner<Settings extends RunnerSettings> extends BaseProgramRunner<Settings> {
|
||||
@Override
|
||||
protected void execute(@NotNull ExecutionEnvironment environment, @Nullable final Callback callback, @NotNull RunProfileState state)
|
||||
throws ExecutionException {
|
||||
ExecutionManager.getInstance(environment.getProject()).startRunProfile(new RunProfileStarter() {
|
||||
@Override
|
||||
public RunContentDescriptor execute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException {
|
||||
return postProcess(environment, doExecute(state, environment), callback);
|
||||
}
|
||||
}, state, environment);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected RunContentDescriptor doExecute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException {
|
||||
//noinspection deprecation
|
||||
return doExecute(environment.getProject(), state, environment.getContentToReuse(), environment);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@SuppressWarnings({"unused", "DeprecatedIsStillUsed"})
|
||||
@Deprecated
|
||||
@Nullable
|
||||
protected RunContentDescriptor doExecute(@NotNull Project project,
|
||||
@NotNull RunProfileState state,
|
||||
@Nullable RunContentDescriptor contentToReuse,
|
||||
@NotNull ExecutionEnvironment environment) throws ExecutionException {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.execution.runners
|
||||
|
||||
import com.intellij.execution.ExecutionException
|
||||
import com.intellij.execution.ExecutionManager
|
||||
import com.intellij.execution.RunProfileStarter
|
||||
import com.intellij.execution.configurations.RunProfileState
|
||||
import com.intellij.execution.configurations.RunnerSettings
|
||||
import com.intellij.execution.ui.RunContentDescriptor
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.concurrency.Promise
|
||||
import org.jetbrains.concurrency.resolvedPromise
|
||||
|
||||
abstract class GenericProgramRunner<Settings : RunnerSettings> : BaseProgramRunner<Settings>() {
|
||||
@Throws(ExecutionException::class)
|
||||
override fun execute(environment: ExecutionEnvironment, callback: ProgramRunner.Callback?, state: RunProfileState) {
|
||||
startRunProfile(environment, state, callback, runProfileStarter { resolvedPromise(doExecute(state, environment)) })
|
||||
}
|
||||
|
||||
@Throws(ExecutionException::class)
|
||||
protected open fun doExecute(state: RunProfileState, environment: ExecutionEnvironment): RunContentDescriptor? {
|
||||
@Suppress("DEPRECATION")
|
||||
return doExecute(environment.project, state, environment.contentToReuse, environment)
|
||||
}
|
||||
|
||||
@Deprecated("")
|
||||
@Throws(ExecutionException::class)
|
||||
protected open fun doExecute(project: Project,
|
||||
state: RunProfileState,
|
||||
contentToReuse: RunContentDescriptor?,
|
||||
environment: ExecutionEnvironment): RunContentDescriptor? {
|
||||
throw AbstractMethodError()
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AsyncProgramRunner<Settings : RunnerSettings> : BaseProgramRunner<Settings>() {
|
||||
override final fun execute(environment: ExecutionEnvironment, callback: ProgramRunner.Callback?, state: RunProfileState) {
|
||||
startRunProfile(environment, state, callback, runProfileStarter { execute(environment, state) })
|
||||
}
|
||||
|
||||
@Throws(ExecutionException::class)
|
||||
protected abstract fun execute(environment: ExecutionEnvironment, state: RunProfileState): Promise<RunContentDescriptor?>
|
||||
}
|
||||
|
||||
internal inline fun runProfileStarter(crossinline starter: () -> Promise<RunContentDescriptor?>) = object : RunProfileStarter() {
|
||||
override fun executeAsync(state: RunProfileState, environment: ExecutionEnvironment) = starter()
|
||||
}
|
||||
|
||||
internal fun startRunProfile(environment: ExecutionEnvironment, state: RunProfileState, callback: ProgramRunner.Callback?, starter: RunProfileStarter?) {
|
||||
ExecutionManager.getInstance(environment.project).startRunProfile(runProfileStarter {
|
||||
(starter?.executeAsync(state, environment) ?: resolvedPromise())
|
||||
.then { BaseProgramRunner.postProcess(environment, it, callback) }
|
||||
}, state, environment)
|
||||
}
|
||||
@@ -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.
|
||||
@@ -387,57 +387,58 @@ public class ExecutionManagerImpl extends ExecutionManager implements Disposable
|
||||
RunProfile profile = environment.getRunProfile();
|
||||
project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processStarting(executor.getId(), environment);
|
||||
|
||||
starter.executeAsync(state, environment).done(descriptor -> {
|
||||
AppUIUtil.invokeOnEdt(() -> {
|
||||
if (descriptor != null) {
|
||||
final Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor> trinity =
|
||||
Trinity.create(descriptor, environment.getRunnerAndConfigurationSettings(), executor);
|
||||
myRunningConfigurations.add(trinity);
|
||||
Disposer.register(descriptor, () -> myRunningConfigurations.remove(trinity));
|
||||
getContentManager().showRunContent(executor, descriptor, environment.getContentToReuse());
|
||||
final ProcessHandler processHandler = descriptor.getProcessHandler();
|
||||
if (processHandler != null) {
|
||||
if (!processHandler.isStartNotified()) {
|
||||
processHandler.startNotify();
|
||||
}
|
||||
project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processStarted(executor.getId(), environment, processHandler);
|
||||
starter.executeAsync(state, environment)
|
||||
.done(descriptor -> AppUIUtil.invokeLaterIfProjectAlive(project, () -> {
|
||||
if (descriptor == null) {
|
||||
project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processNotStarted(executor.getId(), environment);
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessExecutionListener listener = new ProcessExecutionListener(project, executor.getId(), environment, processHandler, descriptor);
|
||||
processHandler.addProcessListener(listener);
|
||||
final Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor> trinity =
|
||||
Trinity.create(descriptor, environment.getRunnerAndConfigurationSettings(), executor);
|
||||
myRunningConfigurations.add(trinity);
|
||||
Disposer.register(descriptor, () -> myRunningConfigurations.remove(trinity));
|
||||
getContentManager().showRunContent(executor, descriptor, environment.getContentToReuse());
|
||||
final ProcessHandler processHandler = descriptor.getProcessHandler();
|
||||
if (processHandler != null) {
|
||||
if (!processHandler.isStartNotified()) {
|
||||
processHandler.startNotify();
|
||||
}
|
||||
project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processStarted(executor.getId(), environment, processHandler);
|
||||
|
||||
// Since we cannot guarantee that the listener is added before process handled is start notified,
|
||||
// we have to make sure the process termination events are delivered to the clients.
|
||||
// Here we check the current process state and manually deliver events, while
|
||||
// the ProcessExecutionListener guarantees each such event is only delivered once
|
||||
// either by this code, or by the ProcessHandler.
|
||||
ProcessExecutionListener
|
||||
listener = new ProcessExecutionListener(project, executor.getId(), environment, processHandler, descriptor);
|
||||
processHandler.addProcessListener(listener);
|
||||
|
||||
boolean terminating = processHandler.isProcessTerminating();
|
||||
boolean terminated = processHandler.isProcessTerminated();
|
||||
if (terminating || terminated) {
|
||||
listener.processWillTerminate(new ProcessEvent(processHandler), false /*doesn't matter*/);
|
||||
// Since we cannot guarantee that the listener is added before process handled is start notified,
|
||||
// we have to make sure the process termination events are delivered to the clients.
|
||||
// Here we check the current process state and manually deliver events, while
|
||||
// the ProcessExecutionListener guarantees each such event is only delivered once
|
||||
// either by this code, or by the ProcessHandler.
|
||||
|
||||
if (terminated) {
|
||||
//noinspection ConstantConditions
|
||||
int exitCode = processHandler.isStartNotified() ? processHandler.getExitCode() : -1;
|
||||
listener.processTerminated(new ProcessEvent(processHandler, exitCode));
|
||||
}
|
||||
boolean terminating = processHandler.isProcessTerminating();
|
||||
boolean terminated = processHandler.isProcessTerminated();
|
||||
if (terminating || terminated) {
|
||||
listener.processWillTerminate(new ProcessEvent(processHandler), false /*doesn't matter*/);
|
||||
|
||||
if (terminated) {
|
||||
//noinspection ConstantConditions
|
||||
int exitCode = processHandler.isStartNotified() ? processHandler.getExitCode() : -1;
|
||||
listener.processTerminated(new ProcessEvent(processHandler, exitCode));
|
||||
}
|
||||
}
|
||||
environment.setContentToReuse(descriptor);
|
||||
}
|
||||
else {
|
||||
project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processNotStarted(executor.getId(), environment);
|
||||
environment.setContentToReuse(descriptor);
|
||||
}))
|
||||
.rejected(e -> {
|
||||
if (!(e instanceof ProcessCanceledException)) {
|
||||
ExecutionException error = e instanceof ExecutionException ? (ExecutionException)e : new ExecutionException(e);
|
||||
ExecutionUtil.handleExecutionError(project, ExecutionManager.getInstance(project).getContentManager().getToolWindowIdByEnvironment(environment),
|
||||
profile, error);
|
||||
}
|
||||
}, o -> project.isDisposed());
|
||||
}).rejected(e -> {
|
||||
if (!(e instanceof ProcessCanceledException)) {
|
||||
ExecutionException error = e instanceof ExecutionException ? (ExecutionException)e : new ExecutionException(e);
|
||||
ExecutionUtil.handleExecutionError(project, ExecutionManager.getInstance(project).getContentManager().getToolWindowIdByEnvironment(environment),
|
||||
profile, error);
|
||||
}
|
||||
LOG.info(e);
|
||||
project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processNotStarted(executor.getId(), environment);
|
||||
});
|
||||
LOG.info(e);
|
||||
project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processNotStarted(executor.getId(), environment);
|
||||
});
|
||||
};
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode() && !myForceCompilationInTests) {
|
||||
|
||||
@@ -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.
|
||||
@@ -17,7 +17,6 @@ package com.intellij.execution.runners
|
||||
|
||||
import com.intellij.execution.ExecutionException
|
||||
import com.intellij.execution.ExecutionResult
|
||||
import com.intellij.execution.RunProfileStarter
|
||||
import com.intellij.execution.configurations.RunProfileState
|
||||
import com.intellij.execution.configurations.RunnerSettings
|
||||
import com.intellij.execution.ui.RunContentDescriptor
|
||||
@@ -25,15 +24,11 @@ import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
|
||||
abstract class DefaultProgramRunner : GenericProgramRunner<RunnerSettings>() {
|
||||
@Throws(ExecutionException::class)
|
||||
override fun doExecute(state: RunProfileState, env: ExecutionEnvironment): RunContentDescriptor? {
|
||||
return executeState(state, env, this)
|
||||
override fun doExecute(state: RunProfileState, environment: ExecutionEnvironment): RunContentDescriptor? {
|
||||
return executeState(state, environment, this)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun runProfileStarter(crossinline starter: (state: RunProfileState, environment: ExecutionEnvironment) -> RunContentDescriptor?) = object : RunProfileStarter() {
|
||||
override fun execute(state: RunProfileState, env: ExecutionEnvironment) = starter(state, env)
|
||||
}
|
||||
|
||||
internal fun executeState(state: RunProfileState, env: ExecutionEnvironment, runner: ProgramRunner<*>): RunContentDescriptor? {
|
||||
FileDocumentManager.getInstance().saveAllDocuments()
|
||||
return showRunContent(state.execute(env.executor, runner), env)
|
||||
|
||||
@@ -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,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.execution.runners
|
||||
|
||||
import com.intellij.execution.RunProfileStarter
|
||||
import com.intellij.execution.configurations.RunProfile
|
||||
import com.intellij.execution.configurations.RunProfileState
|
||||
import com.intellij.execution.configurations.RunnerSettings
|
||||
@@ -25,29 +24,23 @@ import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import org.jetbrains.concurrency.Promise
|
||||
import org.jetbrains.concurrency.resolvedPromise
|
||||
|
||||
private class DefaultRunProgramRunner : AsyncGenericProgramRunner<RunnerSettings>() {
|
||||
private class DefaultRunProgramRunner : AsyncProgramRunner<RunnerSettings>() {
|
||||
override fun getRunnerId() = "defaultRunRunner"
|
||||
|
||||
override fun prepare(environment: ExecutionEnvironment, state: RunProfileState): Promise<RunProfileStarter> {
|
||||
return resolvedPromise(object : RunProfileStarter() {
|
||||
override fun execute(state: RunProfileState, environment: ExecutionEnvironment): RunContentDescriptor? {
|
||||
FileDocumentManager.getInstance().saveAllDocuments()
|
||||
return showRunContent(state.execute(environment.executor, this@DefaultRunProgramRunner), environment)
|
||||
}
|
||||
|
||||
override fun executeAsync(state: RunProfileState, environment: ExecutionEnvironment): Promise<RunContentDescriptor?> {
|
||||
if (state is DebuggableRunProfileState) {
|
||||
FileDocumentManager.getInstance().saveAllDocuments()
|
||||
return state.execute(-1)
|
||||
.then {
|
||||
it?.let {
|
||||
RunContentBuilder(it, environment).showRunContent(environment.contentToReuse)
|
||||
}
|
||||
}
|
||||
override fun execute(environment: ExecutionEnvironment, state: RunProfileState): Promise<RunContentDescriptor?> {
|
||||
FileDocumentManager.getInstance().saveAllDocuments()
|
||||
@Suppress("IfThenToElvis")
|
||||
if (state is DebuggableRunProfileState) {
|
||||
return state.execute(-1)
|
||||
.then {
|
||||
it?.let {
|
||||
RunContentBuilder(it, environment).showRunContent(environment.contentToReuse)
|
||||
}
|
||||
}
|
||||
return super.executeAsync(state, environment)
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
return resolvedPromise(showRunContent(state.execute(environment.executor, this@DefaultRunProgramRunner), environment))
|
||||
}
|
||||
}
|
||||
|
||||
override fun canRun(executorId: String, profile: RunProfile): Boolean {
|
||||
|
||||
@@ -213,7 +213,9 @@ public class TreeState implements JDOMExternalizable {
|
||||
//nodeDescriptor.update();
|
||||
result.add(new PathElement(getDescriptorKey(nodeDescriptor), getDescriptorType(nodeDescriptor), childIndex, nodeDescriptor));
|
||||
}
|
||||
result.add(new PathElement("", "", childIndex, userObject));
|
||||
else {
|
||||
result.add(new PathElement("", "", childIndex, userObject));
|
||||
}
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
|
||||
@@ -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.
|
||||
@@ -349,36 +349,9 @@ open class KeymapImpl @JvmOverloads constructor(private var dataHolder: SchemeDa
|
||||
}
|
||||
return sortInRegistrationOrder(list)
|
||||
}
|
||||
|
||||
override fun getActionIds(firstKeyStroke: KeyStroke): Array<String> {
|
||||
// first, get keystrokes from own map
|
||||
var list = keystrokeToIds.get(firstKeyStroke)
|
||||
val ids = parent?.getActionIds(convertKeyStroke(firstKeyStroke))
|
||||
if (ids != null && ids.isNotEmpty()) {
|
||||
var isOriginalListInstance = list != null
|
||||
for (id in ids) {
|
||||
// add actions from parent keymap only if they are absent in this keymap
|
||||
// do not add parent bind actions, if bind-on action is overwritten in the child
|
||||
if (actionIdToShortcuts.containsKey(id) || actionIdToShortcuts.containsKey(keymapManager.getActionBinding(id))) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (list == null) {
|
||||
list = SmartList<String>()
|
||||
}
|
||||
else if (isOriginalListInstance) {
|
||||
list = SmartList(list)
|
||||
isOriginalListInstance = false
|
||||
}
|
||||
|
||||
if (!list.contains(id)) {
|
||||
list.add(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
return sortInRegistrationOrder(list)
|
||||
}
|
||||
|
||||
|
||||
override fun getActionIds(firstKeyStroke: KeyStroke) = getActionIds(firstKeyStroke, { keystrokeToIds }, { convertKeyStroke(it) })
|
||||
|
||||
override fun getActionIds(firstKeyStroke: KeyStroke, secondKeyStroke: KeyStroke?): Array<String> {
|
||||
val ids = getActionIds(firstKeyStroke)
|
||||
var actualBindings: MutableList<String>? = null
|
||||
@@ -428,17 +401,19 @@ open class KeymapImpl @JvmOverloads constructor(private var dataHolder: SchemeDa
|
||||
}
|
||||
while (true)
|
||||
}
|
||||
|
||||
override fun getActionIds(shortcut: MouseShortcut): Array<String> {
|
||||
var list = mouseShortcutToActionIds.get(shortcut)
|
||||
|
||||
override fun getActionIds(shortcut: MouseShortcut) = getActionIds(shortcut, { mouseShortcutToActionIds }, { convertMouseShortcut(it) })
|
||||
|
||||
private inline fun <T> getActionIds(shortcut: T, shortcutToActionsIds: KeymapImpl.() -> Map<T, MutableList<String>>, convertShortcut: KeymapImpl.(shortcut: T) -> T): Array<String> {
|
||||
var list = shortcutToActionsIds().get(shortcut)
|
||||
var parent = parent ?: return sortInRegistrationOrder(list)
|
||||
|
||||
|
||||
var originalListInstance = list != null
|
||||
var child = this
|
||||
var convertedShortcut = convertMouseShortcut(shortcut)
|
||||
var convertedShortcut = convertShortcut(shortcut)
|
||||
do {
|
||||
for (id in (parent.mouseShortcutToActionIds.get(convertedShortcut) ?: emptyList<String>())) {
|
||||
if (child.actionIdToShortcuts.containsKey(id)) {
|
||||
for (id in (parent.shortcutToActionsIds().get(convertedShortcut)?.sortInRegistrationOrder() ?: emptyList<String>())) {
|
||||
if (child.actionIdToShortcuts.containsKey(id) || actionIdToShortcuts.containsKey(keymapManager.getActionBinding(id))) {
|
||||
// on remove shortcut we put empty list to actionIdToShortcuts, our mouseShortcutToActionIds doesn't contain mapping
|
||||
// so, we add actions from parent keymap only if they are absent in this keymap
|
||||
continue
|
||||
@@ -452,14 +427,15 @@ open class KeymapImpl @JvmOverloads constructor(private var dataHolder: SchemeDa
|
||||
}
|
||||
else if (originalListInstance) {
|
||||
list = SmartList(list)
|
||||
list.sortWith(ActionManagerEx.getInstanceEx().registrationOrderComparator)
|
||||
originalListInstance = false
|
||||
}
|
||||
list.add(id)
|
||||
}
|
||||
|
||||
child = parent
|
||||
parent = child.parent ?: return sortInRegistrationOrder(list)
|
||||
convertedShortcut = child.convertMouseShortcut(shortcut)
|
||||
parent = child.parent ?: return ArrayUtilRt.toStringArray(list)
|
||||
convertedShortcut = child.convertShortcut(shortcut)
|
||||
}
|
||||
while (true)
|
||||
}
|
||||
@@ -733,6 +709,13 @@ private fun sortInRegistrationOrder(ids: List<String>?): Array<String> {
|
||||
return array
|
||||
}
|
||||
|
||||
private fun List<String>.sortInRegistrationOrder(): List<String> {
|
||||
if (size > 1) {
|
||||
return sortedWith(ActionManagerEx.getInstanceEx().registrationOrderComparator)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
// compare two lists in any order
|
||||
private fun areShortcutsEqual(shortcuts1: List<Shortcut>, shortcuts2: List<Shortcut>): Boolean {
|
||||
if (shortcuts1.size != shortcuts2.size) {
|
||||
|
||||
@@ -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.
|
||||
@@ -163,6 +163,18 @@ public class KeymapTest extends PlatformTestCase {
|
||||
myChild.removeShortcut(ACTION_2, mouseShortcut);
|
||||
assertThat(myChild.getActionIds(mouseShortcut)).isEmpty();
|
||||
}
|
||||
|
||||
public void testChangeMouseShortcut() throws Exception {
|
||||
myParent.clearOwnActionsIds();
|
||||
myChild.clearOwnActionsIds();
|
||||
|
||||
MouseShortcut mouseShortcut = new MouseShortcut(1, InputEvent.BUTTON2_MASK, 1);
|
||||
myParent.addShortcut(ACTION_1, mouseShortcut);
|
||||
assertThat(myChild.getActionIds(mouseShortcut)).containsExactly(ACTION_1);
|
||||
|
||||
myChild.addShortcut(ACTION_2, mouseShortcut);
|
||||
assertThat(myChild.getActionIds(mouseShortcut)).containsExactly(ACTION_2, ACTION_1);
|
||||
}
|
||||
|
||||
public void testRemovingShortcutLast() throws Exception {
|
||||
myParent.clearOwnActionsIds();
|
||||
|
||||
@@ -20,9 +20,9 @@ import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.BackgroundTaskQueue;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
@@ -30,7 +30,6 @@ import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ThrowableConsumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.vcs.log.*;
|
||||
import com.intellij.vcs.log.data.index.VcsLogIndex;
|
||||
@@ -59,7 +58,6 @@ public class VcsLogData implements Disposable, VcsLogDataProvider {
|
||||
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final Map<VirtualFile, VcsLogProvider> myLogProviders;
|
||||
@NotNull private final BackgroundTaskQueue myDataLoaderQueue;
|
||||
@NotNull private final MiniDetailsGetter myMiniDetailsGetter;
|
||||
@NotNull private final CommitDetailsGetter myDetailsGetter;
|
||||
|
||||
@@ -90,7 +88,6 @@ public class VcsLogData implements Disposable, VcsLogDataProvider {
|
||||
@NotNull FatalErrorHandler fatalErrorsConsumer) {
|
||||
myProject = project;
|
||||
myLogProviders = logProviders;
|
||||
myDataLoaderQueue = new BackgroundTaskQueue(project, "Loading history...");
|
||||
myUserRegistry = (VcsUserRegistryImpl)ServiceManager.getService(project, VcsUserRegistry.class);
|
||||
myFatalErrorsConsumer = fatalErrorsConsumer;
|
||||
|
||||
@@ -137,6 +134,42 @@ public class VcsLogData implements Disposable, VcsLogDataProvider {
|
||||
return hashMap;
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
StopWatch stopWatch = StopWatch.start("initialize");
|
||||
Task.Backgroundable backgroundable = new Task.Backgroundable(myProject, "Loading History...", false) {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
indicator.setIndeterminate(true);
|
||||
resetState();
|
||||
readCurrentUser();
|
||||
DataPack dataPack = myRefresher.readFirstBlock();
|
||||
fireDataPackChangeEvent(dataPack);
|
||||
stopWatch.report();
|
||||
}
|
||||
};
|
||||
ProgressManager.getInstance().runProcessWithProgressAsynchronously(backgroundable, myRefresher.getProgress().createProgressIndicator());
|
||||
}
|
||||
|
||||
private void readCurrentUser() {
|
||||
StopWatch sw = StopWatch.start("readCurrentUser");
|
||||
for (Map.Entry<VirtualFile, VcsLogProvider> entry : myLogProviders.entrySet()) {
|
||||
VirtualFile root = entry.getKey();
|
||||
try {
|
||||
VcsUser me = entry.getValue().getCurrentUser(root);
|
||||
if (me != null) {
|
||||
myCurrentUser.put(root, me);
|
||||
}
|
||||
else {
|
||||
LOG.info("Username not configured for root " + root);
|
||||
}
|
||||
}
|
||||
catch (VcsException e) {
|
||||
LOG.warn("Couldn't read the username from root " + root, e);
|
||||
}
|
||||
}
|
||||
sw.report();
|
||||
}
|
||||
|
||||
private void fireDataPackChangeEvent(@NotNull final DataPack dataPack) {
|
||||
ApplicationManager.getApplication().invokeLater(() -> {
|
||||
for (DataPackChangeListener listener : myDataPackChangeListeners) {
|
||||
@@ -174,39 +207,6 @@ public class VcsLogData implements Disposable, VcsLogDataProvider {
|
||||
return myStorage;
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
final StopWatch initSw = StopWatch.start("initialize");
|
||||
myDataLoaderQueue.clear();
|
||||
|
||||
runInBackground(indicator -> {
|
||||
resetState();
|
||||
readCurrentUser();
|
||||
DataPack dataPack = myRefresher.readFirstBlock();
|
||||
fireDataPackChangeEvent(dataPack);
|
||||
initSw.report();
|
||||
});
|
||||
}
|
||||
|
||||
private void readCurrentUser() {
|
||||
StopWatch sw = StopWatch.start("readCurrentUser");
|
||||
for (Map.Entry<VirtualFile, VcsLogProvider> entry : myLogProviders.entrySet()) {
|
||||
VirtualFile root = entry.getKey();
|
||||
try {
|
||||
VcsUser me = entry.getValue().getCurrentUser(root);
|
||||
if (me != null) {
|
||||
myCurrentUser.put(root, me);
|
||||
}
|
||||
else {
|
||||
LOG.info("Username not configured for root " + root);
|
||||
}
|
||||
}
|
||||
catch (VcsException e) {
|
||||
LOG.warn("Couldn't read the username from root " + root, e);
|
||||
}
|
||||
}
|
||||
sw.report();
|
||||
}
|
||||
|
||||
private void resetState() {
|
||||
myTopCommitsDetailsCache.clear();
|
||||
}
|
||||
@@ -241,22 +241,6 @@ public class VcsLogData implements Disposable, VcsLogDataProvider {
|
||||
return myContainingBranchesGetter;
|
||||
}
|
||||
|
||||
private void runInBackground(@NotNull ThrowableConsumer<ProgressIndicator, VcsException> task) {
|
||||
Task.Backgroundable backgroundable = new Task.Backgroundable(myProject, "Loading History...", false) {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
indicator.setIndeterminate(true);
|
||||
try {
|
||||
task.consume(indicator);
|
||||
}
|
||||
catch (VcsException e) {
|
||||
throw new RuntimeException(e); // TODO
|
||||
}
|
||||
}
|
||||
};
|
||||
myDataLoaderQueue.run(backgroundable, null, myRefresher.getProgress().createProgressIndicator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes specified roots.
|
||||
* Does not re-read all log but rather the most recent commits.
|
||||
@@ -286,7 +270,6 @@ public class VcsLogData implements Disposable, VcsLogDataProvider {
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
myDataLoaderQueue.clear();
|
||||
resetState();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ public class VcsLogProgress implements Disposable {
|
||||
return createProgressIndicator(true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ProgressIndicator createProgressIndicator(boolean visible) {
|
||||
if (ApplicationManager.getApplication().isHeadlessEnvironment()) {
|
||||
return new EmptyProgressIndicator();
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
@@ -166,13 +165,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
|
||||
@NotNull
|
||||
private List<GraphCommit<Integer>> compactCommits(@NotNull List<? extends TimedVcsCommit> commits, @NotNull final VirtualFile root) {
|
||||
StopWatch sw = StopWatch.start("compacting commits");
|
||||
List<GraphCommit<Integer>> map = ContainerUtil.map(commits, new Function<TimedVcsCommit, GraphCommit<Integer>>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public GraphCommit<Integer> fun(@NotNull TimedVcsCommit commit) {
|
||||
return compactCommit(commit, root);
|
||||
}
|
||||
});
|
||||
List<GraphCommit<Integer>> map = ContainerUtil.map(commits, commit -> compactCommit(commit, root));
|
||||
myStorage.flush();
|
||||
sw.report();
|
||||
return map;
|
||||
|
||||
+17
-10
@@ -21,31 +21,38 @@ import com.intellij.psi.*;
|
||||
* @author Tagir Valeev
|
||||
*/
|
||||
public class BlockUtils {
|
||||
|
||||
/**
|
||||
* Add new statement before given anchor statement creating code block, if necessary
|
||||
* Adds new statements before given anchor statement creating a new code block, if necessary
|
||||
*
|
||||
* @param anchor existing statement
|
||||
* @param newStatement a new statement which should be added before an existing one
|
||||
* @return added physical statement
|
||||
* @param anchor existing statement
|
||||
* @param newStatements the new statements which should be added before the existing one
|
||||
* @return last added physical statement
|
||||
*/
|
||||
public static PsiStatement addBefore(PsiStatement anchor, PsiStatement newStatement) {
|
||||
public static PsiStatement addBefore(PsiStatement anchor, PsiStatement... newStatements) {
|
||||
if (newStatements.length == 0) throw new IllegalArgumentException();
|
||||
PsiElement oldStatement = anchor;
|
||||
PsiElement parent = oldStatement.getParent();
|
||||
while (parent instanceof PsiLabeledStatement) {
|
||||
oldStatement = parent;
|
||||
parent = oldStatement.getParent();
|
||||
}
|
||||
final PsiElement result;
|
||||
PsiElement result = null;
|
||||
if (parent instanceof PsiCodeBlock) {
|
||||
result = parent.addBefore(newStatement, oldStatement);
|
||||
for (PsiStatement statement : newStatements) {
|
||||
result = parent.addBefore(statement, oldStatement);
|
||||
}
|
||||
}
|
||||
else {
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(anchor.getProject());
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(anchor.getProject());
|
||||
final PsiBlockStatement newBlockStatement = (PsiBlockStatement)factory.createStatementFromText("{}", oldStatement);
|
||||
final PsiElement codeBlock = newBlockStatement.getCodeBlock();
|
||||
codeBlock.add(newStatement);
|
||||
for (PsiStatement newStatement : newStatements) {
|
||||
codeBlock.add(newStatement);
|
||||
}
|
||||
codeBlock.add(oldStatement);
|
||||
result = ((PsiBlockStatement)oldStatement.replace(newBlockStatement)).getCodeBlock().getStatements()[0];
|
||||
final PsiStatement[] statements = ((PsiBlockStatement)oldStatement.replace(newBlockStatement)).getCodeBlock().getStatements();
|
||||
result = statements[statements.length - 2];
|
||||
}
|
||||
return (PsiStatement)result;
|
||||
}
|
||||
|
||||
+24
-45
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2016 Bas Leijdekkers
|
||||
* Copyright 2006-2017 Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,11 +16,14 @@
|
||||
package com.siyeh.ipp.forloop;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.siyeh.ig.psiutils.BlockUtils;
|
||||
import com.siyeh.ipp.base.Intention;
|
||||
import com.siyeh.ipp.base.PsiElementPredicate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class ReplaceForLoopWithWhileLoopIntention extends Intention {
|
||||
|
||||
@Override
|
||||
@@ -40,7 +43,6 @@ public class ReplaceForLoopWithWhileLoopIntention extends Intention {
|
||||
final PsiWhileStatement whileStatement = (PsiWhileStatement)factory.createStatementFromText("while(true) {}", element);
|
||||
final PsiExpression forCondition = forStatement.getCondition();
|
||||
final PsiExpression whileCondition = whileStatement.getCondition();
|
||||
final PsiStatement body = forStatement.getBody();
|
||||
if (forCondition != null) {
|
||||
assert whileCondition != null;
|
||||
whileCondition.replace(forCondition);
|
||||
@@ -49,17 +51,18 @@ public class ReplaceForLoopWithWhileLoopIntention extends Intention {
|
||||
if (blockStatement == null) {
|
||||
return;
|
||||
}
|
||||
final PsiElement newBody;
|
||||
if (body instanceof PsiBlockStatement) {
|
||||
final PsiBlockStatement newWhileBody = (PsiBlockStatement)blockStatement.replace(body);
|
||||
newBody = newWhileBody.getCodeBlock();
|
||||
final PsiStatement forStatementBody = forStatement.getBody();
|
||||
final PsiElement loopBody;
|
||||
if (forStatementBody instanceof PsiBlockStatement) {
|
||||
final PsiBlockStatement newWhileBody = (PsiBlockStatement)blockStatement.replace(forStatementBody);
|
||||
loopBody = newWhileBody.getCodeBlock();
|
||||
}
|
||||
else {
|
||||
final PsiCodeBlock codeBlock = blockStatement.getCodeBlock();
|
||||
if (body != null && !(body instanceof PsiEmptyStatement)) {
|
||||
codeBlock.addAfter(body, codeBlock.getFirstChild());
|
||||
if (forStatementBody != null && !(forStatementBody instanceof PsiEmptyStatement)) {
|
||||
codeBlock.add(forStatementBody);
|
||||
}
|
||||
newBody = codeBlock;
|
||||
loopBody = codeBlock;
|
||||
}
|
||||
final PsiStatement update = forStatement.getUpdate();
|
||||
if (update != null) {
|
||||
@@ -69,53 +72,29 @@ public class ReplaceForLoopWithWhileLoopIntention extends Intention {
|
||||
final PsiExpressionList expressionList = expressionListStatement.getExpressionList();
|
||||
final PsiExpression[] expressions = expressionList.getExpressions();
|
||||
updateStatements = new PsiStatement[expressions.length];
|
||||
for (int i = 0, expressionsLength = expressions.length; i < expressionsLength; i++) {
|
||||
final PsiExpression expression = expressions[i];
|
||||
final PsiStatement updateStatement = factory.createStatementFromText(expression.getText() + ';', element);
|
||||
updateStatements[i] = updateStatement;
|
||||
for (int i = 0; i < expressions.length; i++) {
|
||||
updateStatements[i] = factory.createStatementFromText(expressions[i].getText() + ';', element);
|
||||
}
|
||||
}
|
||||
else {
|
||||
final PsiStatement updateStatement = factory.createStatementFromText(update.getText() + ';', element);
|
||||
updateStatements = new PsiStatement[]{updateStatement};
|
||||
}
|
||||
newBody.accept(new UpdateInserter(whileStatement, updateStatements));
|
||||
final Collection<PsiContinueStatement> continueStatements = PsiTreeUtil.findChildrenOfType(loopBody, PsiContinueStatement.class);
|
||||
for (PsiContinueStatement continueStatement : continueStatements) {
|
||||
BlockUtils.addBefore(continueStatement, updateStatements);
|
||||
}
|
||||
for (PsiStatement updateStatement : updateStatements) {
|
||||
newBody.addBefore(updateStatement, newBody.getLastChild());
|
||||
loopBody.addBefore(updateStatement, loopBody.getLastChild());
|
||||
}
|
||||
}
|
||||
if (initialization == null || initialization instanceof PsiEmptyStatement) {
|
||||
return;
|
||||
forStatement.replace(whileStatement);
|
||||
}
|
||||
initialization = (PsiStatement)initialization.copy();
|
||||
PsiElement newElement = forStatement.replace(whileStatement);
|
||||
BlockUtils.addBefore((PsiStatement)newElement, initialization);
|
||||
}
|
||||
|
||||
private static class UpdateInserter extends JavaRecursiveElementWalkingVisitor {
|
||||
|
||||
private final PsiWhileStatement whileStatement;
|
||||
private final PsiStatement[] updateStatements;
|
||||
|
||||
private UpdateInserter(PsiWhileStatement whileStatement, PsiStatement[] updateStatements) {
|
||||
this.whileStatement = whileStatement;
|
||||
this.updateStatements = updateStatements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitContinueStatement(PsiContinueStatement statement) {
|
||||
final PsiStatement continuedStatement = statement.findContinuedStatement();
|
||||
if (!whileStatement.equals(continuedStatement)) {
|
||||
return;
|
||||
}
|
||||
final PsiElement parent = statement.getParent();
|
||||
if (parent == null) {
|
||||
return;
|
||||
}
|
||||
for (PsiStatement updateStatement : updateStatements) {
|
||||
parent.addBefore(updateStatement, statement);
|
||||
}
|
||||
super.visitContinueStatement(statement);
|
||||
else {
|
||||
initialization = (PsiStatement)initialization.copy();
|
||||
final PsiStatement newStatement = (PsiStatement)forStatement.replace(whileStatement);
|
||||
BlockUtils.addBefore(newStatement, initialization);
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2007 Bas Leijdekkers
|
||||
* Copyright 2007-2017 Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,22 +17,21 @@ package com.siyeh.ipp.whileloop;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.ipp.base.Intention;
|
||||
import com.siyeh.ipp.base.PsiElementPredicate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ExtractWhileLoopConditionToIfStatementIntention extends Intention {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected PsiElementPredicate getElementPredicate() {
|
||||
return new WhileLoopPredicate();
|
||||
}
|
||||
|
||||
protected void processIntention(@NotNull PsiElement element)
|
||||
throws IncorrectOperationException {
|
||||
final PsiWhileStatement whileStatement =
|
||||
(PsiWhileStatement)element.getParent();
|
||||
@Override
|
||||
protected void processIntention(@NotNull PsiElement element) {
|
||||
final PsiWhileStatement whileStatement = (PsiWhileStatement)element.getParent();
|
||||
if (whileStatement == null) {
|
||||
return;
|
||||
}
|
||||
@@ -43,14 +42,9 @@ public class ExtractWhileLoopConditionToIfStatementIntention extends Intention {
|
||||
final String conditionText = condition.getText();
|
||||
final PsiManager manager = whileStatement.getManager();
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
|
||||
final PsiExpression newCondition =
|
||||
factory.createExpressionFromText("true", whileStatement);
|
||||
condition.replace(newCondition);
|
||||
condition.replace(factory.createExpressionFromText("true", whileStatement));
|
||||
final PsiStatement body = whileStatement.getBody();
|
||||
final String ifStatementText = "if (!(" + conditionText + ")) break;";
|
||||
final PsiStatement ifStatement =
|
||||
factory.createStatementFromText(ifStatementText,
|
||||
whileStatement);
|
||||
final PsiStatement ifStatement = factory.createStatementFromText("if (!(" + conditionText + ")) break;", whileStatement);
|
||||
final PsiElement newElement;
|
||||
if (body instanceof PsiBlockStatement) {
|
||||
final PsiBlockStatement blockStatement = (PsiBlockStatement)body;
|
||||
@@ -59,9 +53,7 @@ public class ExtractWhileLoopConditionToIfStatementIntention extends Intention {
|
||||
newElement = codeBlock.addBefore(ifStatement, bodyElement);
|
||||
}
|
||||
else if (body != null) {
|
||||
final PsiBlockStatement blockStatement =
|
||||
(PsiBlockStatement)factory.createStatementFromText("{}",
|
||||
whileStatement);
|
||||
final PsiBlockStatement blockStatement = (PsiBlockStatement)factory.createStatementFromText("{}", whileStatement);
|
||||
final PsiCodeBlock codeBlock = blockStatement.getCodeBlock();
|
||||
codeBlock.add(ifStatement);
|
||||
if (!(body instanceof PsiEmptyStatement)) {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
class Continuing {
|
||||
void testFor() {
|
||||
<caret>for (int i=0; i<10; i++) {
|
||||
if(i == 5) continue;
|
||||
System.out.println(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class Continuing {
|
||||
void testFor() {
|
||||
int i=0;
|
||||
while (i<10) {
|
||||
if(i == 5) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
System.out.println(i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class NoInit{
|
||||
void m(int i) {
|
||||
<caret>for (; i < 100; i++) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class NoInit{
|
||||
void m(int i) {
|
||||
while (i < 100) {
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -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.
|
||||
@@ -27,6 +27,8 @@ public class ReplaceForLoopWithWhileLoopIntentionTest extends IPPTestCase {
|
||||
public void testNotInBlock() { doTest(); }
|
||||
public void testDoubleLabelNoBraces() { doTest(); }
|
||||
public void testUpdatingMuch() { doTest(); }
|
||||
public void testContinuing() { doTest(); }
|
||||
public void testNoInit() { doTest(); }
|
||||
|
||||
@Override
|
||||
protected String getIntentionName() {
|
||||
|
||||
@@ -1222,6 +1222,8 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
|
||||
.map(PyWithItem::getTarget)
|
||||
.select(PyTargetExpression.class)
|
||||
.forEach(result::add);
|
||||
|
||||
super.visitPyWithStatement(node);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class Foo(object):
|
||||
def __init__(self):
|
||||
with open('b.py'):
|
||||
self.scope = "a"
|
||||
pass
|
||||
|
||||
def get_scope(self):
|
||||
return self.scope
|
||||
+5
@@ -758,6 +758,11 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase {
|
||||
assertNotParsed((PyFile)fooPsiFile);
|
||||
}
|
||||
|
||||
// PY-23164
|
||||
public void testInstanceAttributeCreatedInsideWithStatement() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Class<? extends PyInspection> getInspectionClass() {
|
||||
|
||||
@@ -34,12 +34,14 @@ public class XmlEditorTest extends LightCodeInsightTestCase {
|
||||
|
||||
public void testEnterPerformance() throws Exception {
|
||||
configureByFile(getTestFilePath(true));
|
||||
EditorTestUtil.performTypingAction(myEditor, '\n');
|
||||
for (int i = 0; i < 3; i++) {
|
||||
EditorTestUtil.performTypingAction(myEditor, '\n');
|
||||
}
|
||||
PlatformTestUtil.startPerformanceTest("Xml editor enter", 7500, () -> {
|
||||
for (int i = 0; i < 3; i ++) {
|
||||
EditorTestUtil.performTypingAction(myEditor, '\n');
|
||||
}
|
||||
}).cpuBound().assertTiming();
|
||||
}).cpuBound().attempts(1).assertTiming();
|
||||
checkResultByFile(getTestFilePath(false));
|
||||
}
|
||||
|
||||
|
||||
@@ -19829,6 +19829,8 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<caret>
|
||||
<string name="script" value=""/>
|
||||
<int name="flags" value="0"/>
|
||||
|
||||
Reference in New Issue
Block a user