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:
+3
@@ -1521,6 +1521,9 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
else {
|
||||
aClass = PsiTreeUtil.getParentOfType(expr, PsiClass.class);
|
||||
if (aClass instanceof PsiAnonymousClass && PsiTreeUtil.isAncestor(((PsiAnonymousClass)aClass).getArgumentList(), expr, false)) {
|
||||
aClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class, true);
|
||||
}
|
||||
}
|
||||
if (aClass == null) return null;
|
||||
|
||||
|
||||
+9
-2
@@ -19,10 +19,14 @@ import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
|
||||
import com.intellij.refactoring.changeSignature.JavaChangeInfo;
|
||||
import com.intellij.refactoring.changeSignature.JavaChangeInfoImpl;
|
||||
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
|
||||
import com.intellij.refactoring.util.CanonicalTypes;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import com.intellij.util.VisibilityUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -66,8 +70,11 @@ public class ParameterCanBeLocalInspection extends ParameterCanBeLocalInspection
|
||||
}
|
||||
final ParameterInfoImpl[] newParams = info.toArray(new ParameterInfoImpl[info.size()]);
|
||||
final String visibilityModifier = VisibilityUtil.getVisibilityModifier(method.getModifierList());
|
||||
final ChangeSignatureProcessor cp = new ChangeSignatureProcessor(project, method, false, visibilityModifier,
|
||||
method.getName(), method.getReturnType(), newParams) {
|
||||
final PsiType returnType = method.getReturnType();
|
||||
final JavaChangeInfo changeInfo = new JavaChangeInfoImpl(visibilityModifier, method, method.getName(),
|
||||
returnType != null ? CanonicalTypes.createTypeWrapper(returnType) : null,
|
||||
newParams, null, false, ContainerUtil.newHashSet(), ContainerUtil.newHashSet());
|
||||
final ChangeSignatureProcessor cp = new ChangeSignatureProcessor(project, changeInfo) {
|
||||
@Override
|
||||
protected void performRefactoring(@NotNull UsageInfo[] usages) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
|
||||
@@ -19,8 +19,6 @@ import com.intellij.formatting.*;
|
||||
import com.intellij.formatting.alignment.AlignmentStrategy;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
@@ -1282,37 +1280,4 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
|
||||
result.setChildAttributes(new ChildAttributes(getCodeBlockInternalIndent(childrenIndent), null));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ExtraReformatRanges getExtraRangesToFormat(FormatTextRanges ranges) {
|
||||
if (ranges.isInsertedBlock(this) && myNode.textContains('\n')) {
|
||||
List<TextRange> extra = calculateExtraRanges(myNode);
|
||||
return new ExtraReformatRanges(extra);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<TextRange> calculateExtraRanges(@NotNull ASTNode node) {
|
||||
Document document = retrieveDocument(node, getProject(node));
|
||||
if (document != null) {
|
||||
TextRange ranges = node.getTextRange();
|
||||
return new IndentRangesCalculator(document, ranges).calcIndentRanges();
|
||||
}
|
||||
|
||||
return ContainerUtil.newArrayList(myNode.getTextRange());
|
||||
}
|
||||
|
||||
|
||||
private static Document retrieveDocument(@NotNull ASTNode node, @NotNull Project project) {
|
||||
PsiFile file = node.getPsi().getContainingFile();
|
||||
return PsiDocumentManager.getInstance(project).getDocument(file);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Project getProject(@NotNull ASTNode node) {
|
||||
return node.getPsi().getProject();
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ public class ChangeSignatureProcessor extends ChangeSignatureProcessorBase {
|
||||
final JavaChangeInfoImpl javaChangeInfo =
|
||||
new JavaChangeInfoImpl(newVisibility, method, newName, newType, parameterInfo, thrownExceptions, generateDelegate,
|
||||
propagateParametersMethods, propagateExceptionsMethods);
|
||||
javaChangeInfo.setRefactoringId(REFACTORING_ID);
|
||||
javaChangeInfo.setCheckUnusedParameter();
|
||||
return javaChangeInfo;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,4 +68,9 @@ public interface JavaChangeInfo extends ChangeInfo {
|
||||
void updateMethod(PsiMethod psiMethod);
|
||||
|
||||
Collection<PsiMethod> getMethodsToPropagateParameters();
|
||||
|
||||
default boolean checkUnusedParameter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class JavaChangeInfoImpl extends UserDataHolderBase implements JavaChange
|
||||
final Set<PsiMethod> propagateParametersMethods;
|
||||
final Set<PsiMethod> propagateExceptionsMethods;
|
||||
|
||||
private String myRefactoringId = null;
|
||||
private boolean myCheckUnusedParameter = false;
|
||||
|
||||
/**
|
||||
* @param newExceptions null if not changed
|
||||
@@ -203,12 +203,13 @@ public class JavaChangeInfoImpl extends UserDataHolderBase implements JavaChange
|
||||
}
|
||||
}
|
||||
|
||||
public String getRefactoringId() {
|
||||
return myRefactoringId;
|
||||
@Override
|
||||
public boolean checkUnusedParameter() {
|
||||
return myCheckUnusedParameter;
|
||||
}
|
||||
|
||||
public void setRefactoringId(String refactoringId) {
|
||||
myRefactoringId = refactoringId;
|
||||
public void setCheckUnusedParameter() {
|
||||
myCheckUnusedParameter = true;
|
||||
}
|
||||
|
||||
protected void fillOldParams(PsiMethod method) {
|
||||
|
||||
+3
-4
@@ -1004,10 +1004,9 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
}
|
||||
|
||||
final boolean[] toRemove = myChangeInfo.toRemoveParm();
|
||||
final String refactoringId = ((JavaChangeInfoImpl)myChangeInfo).getRefactoringId();
|
||||
//introduce parameter object deletes parameters but replaces their usages with generated code
|
||||
final boolean simpleChangeSignature = ChangeSignatureProcessorBase.REFACTORING_ID.equals(refactoringId);
|
||||
if (simpleChangeSignature) {
|
||||
final boolean checkUnusedParameter = myChangeInfo.checkUnusedParameter();
|
||||
if (checkUnusedParameter) {
|
||||
checkParametersToDelete(myChangeInfo.getMethod(), toRemove, conflictDescriptions);
|
||||
}
|
||||
checkContract(conflictDescriptions, myChangeInfo.getMethod());
|
||||
@@ -1025,7 +1024,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
}
|
||||
else if (prototype != null && baseMethod == myChangeInfo.getMethod()) {
|
||||
ConflictsUtil.checkMethodConflicts(method.getContainingClass(), method, prototype, conflictDescriptions);
|
||||
if (simpleChangeSignature) {
|
||||
if (checkUnusedParameter) {
|
||||
checkParametersToDelete(method, toRemove, conflictDescriptions);
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -32,7 +32,6 @@ import com.intellij.util.QueryExecutor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class FunctionalExpressionSearch extends ExtensibleQueryFactory<PsiFunctionalExpression, FunctionalExpressionSearch.SearchParameters> {
|
||||
public static final ExtensionPointName<QueryExecutor> EP_NAME = ExtensionPointName.create("com.intellij.functionalInterfaceSearch");
|
||||
public static final FunctionalExpressionSearch INSTANCE = new FunctionalExpressionSearch();
|
||||
|
||||
public static class SearchParameters {
|
||||
|
||||
+7
@@ -74,6 +74,10 @@ public class JavaGenericsUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type instanceof PsiCapturedWildcardType) {
|
||||
return isReifiableType(((PsiCapturedWildcardType)type).getUpperBound());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -127,6 +131,9 @@ public class JavaGenericsUtil {
|
||||
if (castType instanceof PsiClassType) {
|
||||
final PsiClassType castClassType = (PsiClassType)castType;
|
||||
operandType = operandType.getDeepComponentType();
|
||||
if (operandType instanceof PsiCapturedWildcardType) {
|
||||
operandType = ((PsiCapturedWildcardType)operandType).getUpperBound();
|
||||
}
|
||||
|
||||
if (!(operandType instanceof PsiClassType)) return false;
|
||||
final PsiClassType operandClassType = (PsiClassType)operandType;
|
||||
|
||||
+1
-1
@@ -5,6 +5,6 @@ public class Main {
|
||||
protected Object obj = null;
|
||||
private long e = 4;
|
||||
|
||||
public static void main(String[] args) {
|
||||
public static void main(String[] args) {
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -4,7 +4,7 @@ class C implements A {
|
||||
|
||||
interface A {
|
||||
A a = new C(<error descr="'A.this' cannot be referenced from a static context">this</error>);
|
||||
A a1 = new C(<error descr="Cannot find symbol variable this">this</error>){};
|
||||
A a1 = new C(<error descr="'A.this' cannot be referenced from a static context">this</error>){};
|
||||
|
||||
class B {
|
||||
A foo() {
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class A {
|
||||
public A(Object o) {
|
||||
}
|
||||
}
|
||||
|
||||
class B {}
|
||||
|
||||
class C extends B {
|
||||
static {
|
||||
A a = new A(<error descr="'C.this' cannot be referenced from a static context">this</error>) {};
|
||||
A a1 = new A(<error descr="'C.super' cannot be referenced from a static context">super</error>.clone()) {};
|
||||
}
|
||||
|
||||
{
|
||||
A a = new A(this);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import java.util.List;
|
||||
|
||||
class Test {
|
||||
public void bar(List<?> list) {
|
||||
foo(list.get(0));
|
||||
}
|
||||
|
||||
private final <K>void foo(K... <warning descr="Parameter 'k' is never used">k</warning>) {}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import java.util.List;
|
||||
|
||||
class Test {
|
||||
public <A> void foo(List<?> list, List<? extends Object> list2) {
|
||||
Comparable<A> <warning descr="Variable 'c1' is never used">c1</warning> = <warning descr="Unchecked cast: 'capture<?>' to 'java.lang.Comparable<A>'">(Comparable<A>)list.get(0)</warning>;
|
||||
Comparable<A> <warning descr="Variable 'c2' is never used">c2</warning> = <warning descr="Unchecked cast: 'capture<? extends java.lang.Object>' to 'java.lang.Comparable<A>'">(Comparable<A>)list2.get(0)</warning>;
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -31,8 +31,12 @@ public class ReformatCodeActionInEditorTest extends LightPlatformCodeInsightFixt
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
myFixture.getFile().putUserData(FormatChangedTextUtil.TEST_REVISION_CONTENT, null);
|
||||
super.tearDown();
|
||||
try {
|
||||
myFixture.getFile().putUserData(FormatChangedTextUtil.TEST_REVISION_CONTENT, null);
|
||||
}
|
||||
finally {
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
public void doTest(LayoutCodeOptions options) {
|
||||
|
||||
+3
@@ -75,4 +75,7 @@ public class LightAdvHighlightingJdk6Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testVariableUsedBeforeAssignmentWithParenthesis() {
|
||||
doTest(false, false);
|
||||
}
|
||||
public void testThisInArgListOfAnonymous() {
|
||||
doTest(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -998,4 +998,12 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testErasureOfReturnTypeOfNonGenericMethod() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testUncheckedCastWithCapturedWildcards() throws Exception {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
public void testReifiableCapturedWildcards() throws Exception {
|
||||
doTest(true);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -152,7 +152,7 @@ public class OfflineInspectionResultViewTest extends TestSourceBasedTestCase {
|
||||
" -<default>\n" +
|
||||
" -Test\n" +
|
||||
" -m()\n" +
|
||||
" Identical qualifier and argument to 'equals()' call\n" +
|
||||
" 'equals()' called on itself\n" +
|
||||
" -null\n" +
|
||||
" Identical qualifier and argument to <code>equals()</code> call\n"
|
||||
+ " -" + myUnusedToolWrapper + "\n"
|
||||
@@ -190,10 +190,10 @@ public class OfflineInspectionResultViewTest extends TestSourceBasedTestCase {
|
||||
" -<default>\n" +
|
||||
" -Test\n" +
|
||||
" -m()\n" +
|
||||
" Identical qualifier and argument to 'equals()' call\n" +
|
||||
" 'equals()' called on itself\n" +
|
||||
" -Test2\n" +
|
||||
" -m123()\n" +
|
||||
" Identical qualifier and argument to 'equals()' call\n"
|
||||
" 'equals()' called on itself\n"
|
||||
+ " -" + myUnusedToolWrapper + "\n"
|
||||
+ " -" + getModule().toString() + "\n"
|
||||
+ " -<default>\n"
|
||||
@@ -218,9 +218,9 @@ public class OfflineInspectionResultViewTest extends TestSourceBasedTestCase {
|
||||
+ " -Probable bugs\n"
|
||||
+ " -" + myDataFlowToolWrapper + "\n" +
|
||||
" -Test\n" +
|
||||
" Identical qualifier and argument to 'equals()' call\n" +
|
||||
" 'equals()' called on itself\n" +
|
||||
" -Test2\n" +
|
||||
" Identical qualifier and argument to 'equals()' call\n"
|
||||
" 'equals()' called on itself\n"
|
||||
+ " -" + myUnusedToolWrapper + "\n"
|
||||
+ " -Test\n"
|
||||
+ " " + varMessage("j") + "\n"
|
||||
@@ -248,9 +248,9 @@ public class OfflineInspectionResultViewTest extends TestSourceBasedTestCase {
|
||||
+ " -Probable bugs\n"
|
||||
+ " -" + myDataFlowToolWrapper + "\n" +
|
||||
" -Test\n" +
|
||||
" Identical qualifier and argument to 'equals()' call\n" +
|
||||
" 'equals()' called on itself\n" +
|
||||
" -Test2\n" +
|
||||
" Identical qualifier and argument to 'equals()' call\n"
|
||||
" 'equals()' called on itself\n"
|
||||
+ " -" + myUnusedToolWrapper + "\n"
|
||||
+ " -Test\n"
|
||||
+ " " + varMessage("j") + "\n"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.psi.formatter.java
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.formatter.IndentRangesCalculator
|
||||
import com.intellij.testFramework.LightPlatformCodeInsightTestCase
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
|
||||
|
||||
@@ -1,363 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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 org.jetbrains.concurrency;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AsyncPromise<T> extends Promise<T> implements Getter<T> {
|
||||
private static final Logger LOG = Logger.getInstance(AsyncPromise.class);
|
||||
|
||||
public static final RuntimeException OBSOLETE_ERROR = Promise.createError("Obsolete");
|
||||
|
||||
private volatile Consumer<? super T> done;
|
||||
private volatile Consumer<? super Throwable> rejected;
|
||||
|
||||
protected volatile State state = State.PENDING;
|
||||
// result object or error message
|
||||
private volatile Object result;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Promise<T> done(@NotNull Consumer<? super T> done) {
|
||||
if (isObsolete(done)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case PENDING:
|
||||
break;
|
||||
case FULFILLED:
|
||||
//noinspection unchecked
|
||||
done.consume((T)result);
|
||||
return this;
|
||||
case REJECTED:
|
||||
return this;
|
||||
}
|
||||
|
||||
this.done = setHandler(this.done, done);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Promise<T> rejected(@NotNull Consumer<Throwable> rejected) {
|
||||
if (isObsolete(rejected)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case PENDING:
|
||||
break;
|
||||
case FULFILLED:
|
||||
return this;
|
||||
case REJECTED:
|
||||
rejected.consume((Throwable)result);
|
||||
return this;
|
||||
}
|
||||
|
||||
this.rejected = setHandler(this.rejected, rejected);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
//noinspection unchecked
|
||||
return state == State.FULFILLED ? (T)result : null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SynchronizeOnThis")
|
||||
private static final class CompoundConsumer<T> implements Consumer<T> {
|
||||
private List<Consumer<? super T>> consumers = new ArrayList<Consumer<? super T>>();
|
||||
|
||||
public CompoundConsumer(@NotNull Consumer<? super T> c1, @NotNull Consumer<? super T> c2) {
|
||||
synchronized (this) {
|
||||
consumers.add(c1);
|
||||
consumers.add(c2);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume(T t) {
|
||||
List<Consumer<? super T>> list;
|
||||
synchronized (this) {
|
||||
list = consumers;
|
||||
consumers = null;
|
||||
}
|
||||
|
||||
if (list != null) {
|
||||
for (Consumer<? super T> consumer : list) {
|
||||
if (!isObsolete(consumer)) {
|
||||
consumer.consume(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void add(@NotNull Consumer<? super T> consumer) {
|
||||
synchronized (this) {
|
||||
if (consumers != null) {
|
||||
consumers.add(consumer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public <SUB_RESULT> Promise<SUB_RESULT> then(@NotNull final Function<? super T, ? extends SUB_RESULT> fulfilled) {
|
||||
switch (state) {
|
||||
case PENDING:
|
||||
break;
|
||||
case FULFILLED:
|
||||
//noinspection unchecked
|
||||
return new DonePromise<SUB_RESULT>(fulfilled.fun((T)result));
|
||||
case REJECTED:
|
||||
return new RejectedPromise<SUB_RESULT>((Throwable)result);
|
||||
}
|
||||
|
||||
final AsyncPromise<SUB_RESULT> promise = new AsyncPromise<SUB_RESULT>();
|
||||
addHandlers(new Consumer<T>() {
|
||||
@Override
|
||||
public void consume(T result) {
|
||||
try {
|
||||
if (fulfilled instanceof Obsolescent && ((Obsolescent)fulfilled).isObsolete()) {
|
||||
promise.setError(OBSOLETE_ERROR);
|
||||
}
|
||||
else {
|
||||
promise.setResult(fulfilled.fun(result));
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
promise.setError(e);
|
||||
}
|
||||
}
|
||||
}, new Consumer<Throwable>() {
|
||||
@Override
|
||||
public void consume(Throwable error) {
|
||||
promise.setError(error);
|
||||
}
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(@NotNull final AsyncPromise<? super T> child) {
|
||||
LOG.assertTrue(child != this);
|
||||
|
||||
switch (state) {
|
||||
case PENDING:
|
||||
break;
|
||||
case FULFILLED:
|
||||
//noinspection unchecked
|
||||
child.setResult((T)result);
|
||||
return;
|
||||
case REJECTED:
|
||||
child.setError((Throwable)result);
|
||||
return;
|
||||
}
|
||||
|
||||
addHandlers(new Consumer<T>() {
|
||||
@Override
|
||||
public void consume(T result) {
|
||||
try {
|
||||
child.setResult(result);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
child.setError(e);
|
||||
}
|
||||
}
|
||||
}, new Consumer<Throwable>() {
|
||||
@Override
|
||||
public void consume(Throwable error) {
|
||||
child.setError(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public <SUB_RESULT> Promise<SUB_RESULT> thenAsync(@NotNull final Function<? super T, Promise<SUB_RESULT>> fulfilled) {
|
||||
switch (state) {
|
||||
case PENDING:
|
||||
break;
|
||||
case FULFILLED:
|
||||
//noinspection unchecked
|
||||
return fulfilled.fun((T)result);
|
||||
case REJECTED:
|
||||
return Promise.reject((Throwable)result);
|
||||
}
|
||||
|
||||
final AsyncPromise<SUB_RESULT> promise = new AsyncPromise<SUB_RESULT>();
|
||||
final Consumer<Throwable> rejectedHandler = new Consumer<Throwable>() {
|
||||
@Override
|
||||
public void consume(Throwable error) {
|
||||
promise.setError(error);
|
||||
}
|
||||
};
|
||||
addHandlers(new Consumer<T>() {
|
||||
@Override
|
||||
public void consume(T result) {
|
||||
try {
|
||||
fulfilled.fun(result)
|
||||
.done(new Consumer<SUB_RESULT>() {
|
||||
@Override
|
||||
public void consume(SUB_RESULT result) {
|
||||
try {
|
||||
promise.setResult(result);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
promise.setError(e);
|
||||
}
|
||||
}
|
||||
})
|
||||
.rejected(rejectedHandler);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
promise.setError(e);
|
||||
}
|
||||
}
|
||||
}, rejectedHandler);
|
||||
return promise;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Promise<T> processed(@NotNull final AsyncPromise<? super T> fulfilled) {
|
||||
switch (state) {
|
||||
case PENDING:
|
||||
break;
|
||||
case FULFILLED:
|
||||
//noinspection unchecked
|
||||
fulfilled.setResult((T)result);
|
||||
return this;
|
||||
case REJECTED:
|
||||
fulfilled.setError((Throwable)result);
|
||||
return this;
|
||||
}
|
||||
|
||||
addHandlers(new Consumer<T>() {
|
||||
@Override
|
||||
public void consume(T result) {
|
||||
try {
|
||||
fulfilled.setResult(result);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
fulfilled.setError(e);
|
||||
}
|
||||
}
|
||||
}, new Consumer<Throwable>() {
|
||||
@Override
|
||||
public void consume(Throwable error) {
|
||||
fulfilled.setError(error);
|
||||
}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
private void addHandlers(@NotNull Consumer<T> done, @NotNull Consumer<Throwable> rejected) {
|
||||
this.done = setHandler(this.done, done);
|
||||
this.rejected = setHandler(this.rejected, rejected);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static <T> Consumer<? super T> setHandler(@Nullable Consumer<? super T> oldConsumer, @NotNull Consumer<? super T> newConsumer) {
|
||||
if (oldConsumer == null) {
|
||||
return newConsumer;
|
||||
}
|
||||
else if (oldConsumer instanceof CompoundConsumer) {
|
||||
((CompoundConsumer<T>)oldConsumer).add(newConsumer);
|
||||
return oldConsumer;
|
||||
}
|
||||
else {
|
||||
return new CompoundConsumer<T>(oldConsumer, newConsumer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setResult(T result) {
|
||||
if (state != State.PENDING) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.result = result;
|
||||
state = State.FULFILLED;
|
||||
|
||||
Consumer<? super T> done = this.done;
|
||||
clearHandlers();
|
||||
if (done != null && !isObsolete(done)) {
|
||||
done.consume(result);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isObsolete(@Nullable Consumer<?> consumer) {
|
||||
return consumer instanceof Obsolescent && ((Obsolescent)consumer).isObsolete();
|
||||
}
|
||||
|
||||
public boolean setError(@NotNull String error) {
|
||||
return setError(Promise.createError(error));
|
||||
}
|
||||
|
||||
public boolean setError(@NotNull Throwable error) {
|
||||
if (state != State.PENDING) {
|
||||
return false;
|
||||
}
|
||||
|
||||
result = error;
|
||||
state = State.REJECTED;
|
||||
|
||||
Consumer<? super Throwable> rejected = this.rejected;
|
||||
clearHandlers();
|
||||
if (rejected != null) {
|
||||
if (!isObsolete(rejected)) {
|
||||
rejected.consume(error);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Promise.logError(LOG, error);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void clearHandlers() {
|
||||
done = null;
|
||||
rejected = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<T> processed(@NotNull final Consumer<? super T> processed) {
|
||||
done(processed);
|
||||
rejected(new Consumer<Throwable>() {
|
||||
@Override
|
||||
public void consume(Throwable error) {
|
||||
processed.consume(null);
|
||||
}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.concurrency;
|
||||
|
||||
import com.intellij.util.Consumer;
|
||||
|
||||
public abstract class ConsumerRunnable implements Consumer<Void>, Runnable {
|
||||
@Override
|
||||
public final void consume(Void aVoid) {
|
||||
run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract void run();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.openapi.vfs.impl.http;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.concurrency.Promise;
|
||||
|
||||
public interface RemoteFileInfo {
|
||||
void addDownloadingListener(@NotNull FileDownloadingListener listener);
|
||||
@@ -35,7 +34,4 @@ public interface RemoteFileInfo {
|
||||
RemoteFileState getState();
|
||||
|
||||
void cancelDownloading();
|
||||
|
||||
@NotNull
|
||||
Promise<VirtualFile> download();
|
||||
}
|
||||
|
||||
+25
-4
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.intellij.codeInsight.intention.impl;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.ShowIntentionsPass;
|
||||
import com.intellij.codeInsight.hint.HintManager;
|
||||
@@ -195,10 +196,20 @@ public class IntentionListStep implements ListPopupStep<IntentionActionWithTextC
|
||||
final List<IntentionAction> options = descriptor.getOptions(element, containingEditor);
|
||||
if (options == null) return cachedAction;
|
||||
for (IntentionAction option : options) {
|
||||
if (!option.isAvailable(myProject, containingEditor, containingFile)) {
|
||||
// if option is not applicable in injected fragment, check in host file context
|
||||
if (containingEditor == myEditor || !option.isAvailable(myProject, myEditor, myFile)) {
|
||||
continue;
|
||||
if (containingFile != null && containingEditor != null && myEditor != null) {
|
||||
if (!ShowIntentionActionsHandler.availableFor(containingFile, containingEditor, option)) {
|
||||
//if option is not applicable in injected fragment, check in host file context
|
||||
if (containingEditor == myEditor || !ShowIntentionActionsHandler.availableFor(myFile, myEditor, option)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!option.isAvailable(myProject, containingEditor, containingFile)) {
|
||||
// if option is not applicable in injected fragment, check in host file context
|
||||
if (containingEditor == myEditor || !option.isAvailable(myProject, myEditor, myFile)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
IntentionActionWithTextCaching textCaching = new IntentionActionWithTextCaching(option);
|
||||
@@ -291,6 +302,16 @@ public class IntentionListStep implements ListPopupStep<IntentionActionWithTextC
|
||||
return optionIntention instanceof Iconable ? ((Iconable)optionIntention).getIcon(0) : null;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public Map<IntentionAction, List<IntentionAction>> getActionsWithSubActions() {
|
||||
Map<IntentionAction, List<IntentionAction>> result = ContainerUtil.newLinkedHashMap();
|
||||
for (IntentionActionWithTextCaching action : getValues()) {
|
||||
List<IntentionActionWithTextCaching> subActions = getSubStep(action, action.getToolName()).getValues();
|
||||
result.put(action.getAction(), ContainerUtil.map(subActions, IntentionActionWithTextCaching::getAction));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSubstep(final IntentionActionWithTextCaching action) {
|
||||
return action.getOptionIntentions().size() + action.getOptionErrorFixes().size() > 0;
|
||||
|
||||
+14
-74
@@ -40,26 +40,18 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.LabeledComponent;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.profile.Profile;
|
||||
import com.intellij.profile.codeInspection.InspectionProfileManager;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.profile.codeInspection.ui.header.ProfilesComboBox;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.ui.TitledSeparator;
|
||||
import com.intellij.util.containers.FactoryMap;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -148,7 +140,7 @@ public class RunInspectionAction extends GotoActionBase {
|
||||
project, analysisScope, module != null ? module.getName() : null,
|
||||
true, options, psiElement) {
|
||||
|
||||
private InheritOptionsForToolPanel myToolOptionsPanel;
|
||||
private InspectionToolWrapper myUpdatedSettingsToolWrapper;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@@ -158,8 +150,9 @@ public class RunInspectionAction extends GotoActionBase {
|
||||
JPanel additionPanel = new JPanel();
|
||||
additionPanel.setLayout(new BoxLayout(additionPanel, BoxLayout.Y_AXIS));
|
||||
additionPanel.add(fileFilter);
|
||||
myToolOptionsPanel = new InheritOptionsForToolPanel((InspectionProfileImpl)currentProfile, toolWrapper.getShortName(), project);
|
||||
additionPanel.add(myToolOptionsPanel);
|
||||
myUpdatedSettingsToolWrapper = copyToolWithSettings(toolWrapper);//new InheritOptionsForToolPanel(toolWrapper.getShortName(), project);
|
||||
additionPanel.add(new TitledSeparator(IdeBundle.message("goto.inspection.action.choose.inherit.settings.from")));
|
||||
additionPanel.add(myUpdatedSettingsToolWrapper.getTool().createOptionsPanel());
|
||||
return additionPanel;
|
||||
} else {
|
||||
return fileFilter;
|
||||
@@ -186,7 +179,7 @@ public class RunInspectionAction extends GotoActionBase {
|
||||
}
|
||||
|
||||
private InspectionToolWrapper getToolWrapper() {
|
||||
return myToolOptionsPanel == null ? toolWrapper : myToolOptionsPanel.getSelectedWrapper();
|
||||
return myUpdatedSettingsToolWrapper == null ? toolWrapper : myUpdatedSettingsToolWrapper;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -228,69 +221,16 @@ public class RunInspectionAction extends GotoActionBase {
|
||||
dialog.showAndGet();
|
||||
}
|
||||
|
||||
private static class InheritOptionsForToolPanel extends JPanel {
|
||||
private final ProfilesComboBox myProfilesComboBox;
|
||||
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
|
||||
private final FactoryMap<InspectionProfile, Pair<InspectionToolWrapper, JComponent>> myProfile2ModifiedWrapper;
|
||||
|
||||
public InheritOptionsForToolPanel(final InspectionProfileImpl initial, final String toolShortName, final Project project) {
|
||||
myProfile2ModifiedWrapper = new FactoryMap<InspectionProfile, Pair<InspectionToolWrapper, JComponent>>() {
|
||||
@Nullable
|
||||
@Override
|
||||
protected Pair<InspectionToolWrapper, JComponent> create(InspectionProfile profile) {
|
||||
InspectionToolWrapper tool = profile.getInspectionTool(toolShortName, project);
|
||||
LOGGER.assertTrue(tool != null);
|
||||
final Element options = new Element("copy");
|
||||
tool.getTool().writeSettings(options);
|
||||
tool = tool.createCopy();
|
||||
try {
|
||||
tool.getTool().readSettings(options);
|
||||
}
|
||||
catch (InvalidDataException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return Pair.create(tool, tool.getTool().createOptionsPanel());
|
||||
}
|
||||
};
|
||||
JPanel settingsAnchor = new JPanel(new BorderLayout());
|
||||
myProfilesComboBox = new ProfilesComboBox() {
|
||||
@Override
|
||||
protected void onProfileChosen(InspectionProfileImpl inspectionProfile) {
|
||||
settingsAnchor.removeAll();
|
||||
settingsAnchor.add(myProfile2ModifiedWrapper.get(inspectionProfile).getSecond(), BorderLayout.CENTER);
|
||||
settingsAnchor.invalidate();
|
||||
settingsAnchor.validate();
|
||||
settingsAnchor.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isProjectLevel(InspectionProfileImpl p) {
|
||||
return p.isProjectLevel();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getProfileName(InspectionProfileImpl p) {
|
||||
return p.getName();
|
||||
}
|
||||
};
|
||||
|
||||
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
||||
add(new TitledSeparator(IdeBundle.message("goto.inspection.action.choose.inherit.settings.from")));
|
||||
add(LabeledComponent.create(myProfilesComboBox, "Profile:", BorderLayout.WEST));
|
||||
add(Box.createVerticalStrut(JBUI.scale(10)));
|
||||
add(settingsAnchor);
|
||||
|
||||
final List<Profile> profiles = new ArrayList<>();
|
||||
profiles.addAll(InspectionProfileManager.getInstance().getProfiles());
|
||||
profiles.addAll(InspectionProjectProfileManager.getInstance(project).getProfiles());
|
||||
myProfilesComboBox.reset(profiles);
|
||||
myProfilesComboBox.selectProfile(initial);
|
||||
private static InspectionToolWrapper copyToolWithSettings(@NotNull final InspectionToolWrapper tool) {
|
||||
final Element options = new Element("copy");
|
||||
tool.getTool().writeSettings(options);
|
||||
final InspectionToolWrapper copiedTool = tool.createCopy();
|
||||
try {
|
||||
copiedTool.getTool().readSettings(options);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public InspectionToolWrapper getSelectedWrapper() {
|
||||
return myProfile2ModifiedWrapper.get((InspectionProfileImpl)myProfilesComboBox.getSelectedItem()).getFirst();
|
||||
catch (InvalidDataException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return copiedTool;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,6 +163,11 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren
|
||||
});
|
||||
add(mySplitter, BorderLayout.CENTER);
|
||||
myExclusionHandler = new ExclusionHandler<InspectionTreeNode>() {
|
||||
@Override
|
||||
public boolean isNodeExclusionAvailable(@NotNull InspectionTreeNode node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNodeExcluded(@NotNull InspectionTreeNode node) {
|
||||
return node.isExcluded(myExcludedInspectionTreeNodesManager);
|
||||
|
||||
+2
-2
@@ -13,13 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.formatter.java
|
||||
package com.intellij.psi.formatter
|
||||
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.util.text.CharArrayUtil
|
||||
|
||||
class IndentRangesCalculator(private val document: Document,
|
||||
class IndentRangesCalculator(private val document: Document,
|
||||
private val textRange: TextRange)
|
||||
{
|
||||
private val startOffset = textRange.startOffset
|
||||
@@ -19,12 +19,16 @@ package com.intellij.psi.formatter.common;
|
||||
import com.intellij.formatting.*;
|
||||
import com.intellij.injected.editor.DocumentWindow;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.formatter.FormatterUtil;
|
||||
import com.intellij.psi.formatter.IndentRangesCalculator;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -184,7 +188,34 @@ public abstract class AbstractBlock implements ASTBlock {
|
||||
*/
|
||||
@Nullable
|
||||
public ExtraReformatRanges getExtraRangesToFormat(FormatTextRanges ranges) {
|
||||
if (ranges.isInsertedBlock(this) && myNode.textContains('\n')) {
|
||||
List<TextRange> extra = calculateExtraRanges(myNode);
|
||||
return new ExtraReformatRanges(extra);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<TextRange> calculateExtraRanges(@NotNull ASTNode node) {
|
||||
Document document = retrieveDocument(node, getProject(node));
|
||||
if (document != null) {
|
||||
TextRange ranges = node.getTextRange();
|
||||
return new IndentRangesCalculator(document, ranges).calcIndentRanges();
|
||||
}
|
||||
|
||||
return ContainerUtil.newArrayList(myNode.getTextRange());
|
||||
}
|
||||
|
||||
|
||||
private static Document retrieveDocument(@NotNull ASTNode node, @NotNull Project project) {
|
||||
PsiFile file = node.getPsi().getContainingFile();
|
||||
return PsiDocumentManager.getInstance(project).getDocument(file);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Project getProject(@NotNull ASTNode node) {
|
||||
return node.getPsi().getProject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1174,6 +1174,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
|
||||
}
|
||||
|
||||
void clearIndicesIfNecessary() {
|
||||
waitUntilIndicesAreInitialized();
|
||||
for (ID<?, ?> indexId : getState().getIndexIDs()) {
|
||||
try {
|
||||
RebuildStatus.clearIndexIfNecessary(indexId, getIndex(indexId)::clear);
|
||||
|
||||
@@ -26,6 +26,8 @@ import javax.swing.tree.MutableTreeNode;
|
||||
public interface ExclusionHandler<T extends MutableTreeNode> {
|
||||
DataKey<ExclusionHandler> EXCLUSION_HANDLER = DataKey.create("tree.exclusion.handler");
|
||||
|
||||
boolean isNodeExclusionAvailable(@NotNull T node);
|
||||
|
||||
boolean isNodeExcluded(@NotNull T node);
|
||||
|
||||
void excludeNode(@NotNull T node);
|
||||
|
||||
+1
@@ -63,6 +63,7 @@ abstract class TreeNodeExclusionAction<T extends MutableTreeNode> extends AnActi
|
||||
for (TreePath path : selection) {
|
||||
final T node = (T)path.getLastPathComponent();
|
||||
TreeUtil.traverse(node, n -> {
|
||||
if (!exclusionProcessor.isNodeExclusionAvailable((T)n)) return true;
|
||||
final Boolean isNodeExcluded = exclusionProcessor.isNodeExcluded((T)n);
|
||||
if (myIsExclude != isNodeExcluded) {
|
||||
isEnabled[0] = true;
|
||||
|
||||
@@ -356,7 +356,9 @@ public final class HttpRequests {
|
||||
}
|
||||
|
||||
private static <T> T process(RequestBuilderImpl builder, RequestProcessor<T> processor) throws IOException {
|
||||
LOG.assertTrue(ApplicationManager.getApplication() == null || !ApplicationManager.getApplication().isReadAccessAllowed(),
|
||||
LOG.assertTrue(ApplicationManager.getApplication() == null ||
|
||||
ApplicationManager.getApplication().isUnitTestMode() ||
|
||||
!ApplicationManager.getApplication().isReadAccessAllowed(),
|
||||
"Network shouldn't be accessed in EDT or inside read action");
|
||||
|
||||
ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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 org.jetbrains.concurrency
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.util.Getter
|
||||
import com.intellij.util.Consumer
|
||||
import com.intellij.util.Function
|
||||
import java.util.*
|
||||
|
||||
private val LOG = Logger.getInstance(AsyncPromise::class.java)
|
||||
|
||||
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
|
||||
private val OBSOLETE_ERROR = Promise.createError("Obsolete")
|
||||
|
||||
open class AsyncPromise<T> : Promise<T>(), Getter<T> {
|
||||
@Volatile private var done: Consumer<in T>? = null
|
||||
@Volatile private var rejected: Consumer<in Throwable>? = null
|
||||
|
||||
@Volatile private var state: Promise.State = Promise.State.PENDING
|
||||
|
||||
// result object or error message
|
||||
@Volatile private var result: Any? = null
|
||||
|
||||
override fun getState() = state
|
||||
|
||||
override fun done(done: Consumer<in T>): Promise<T> {
|
||||
if (isObsolete(done)) {
|
||||
return this
|
||||
}
|
||||
|
||||
when (state) {
|
||||
Promise.State.PENDING -> {
|
||||
}
|
||||
Promise.State.FULFILLED -> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
done.consume(result as T?)
|
||||
return this
|
||||
}
|
||||
Promise.State.REJECTED -> return this
|
||||
}
|
||||
|
||||
this.done = setHandler(this.done, done)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun rejected(rejected: Consumer<Throwable>): Promise<T> {
|
||||
if (isObsolete(rejected)) {
|
||||
return this
|
||||
}
|
||||
|
||||
when (state) {
|
||||
Promise.State.PENDING -> {
|
||||
}
|
||||
Promise.State.FULFILLED -> return this
|
||||
Promise.State.REJECTED -> {
|
||||
rejected.consume(result as Throwable?)
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
this.rejected = setHandler(this.rejected, rejected)
|
||||
return this
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun get() = if (state == Promise.State.FULFILLED) result as T? else null
|
||||
|
||||
override fun <SUB_RESULT> then(fulfilled: Function<in T, out SUB_RESULT>): Promise<SUB_RESULT> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
when (state) {
|
||||
Promise.State.PENDING -> {
|
||||
}
|
||||
Promise.State.FULFILLED -> return DonePromise<SUB_RESULT>(fulfilled.`fun`(result as T?))
|
||||
Promise.State.REJECTED -> return rejectedPromise(result as Throwable)
|
||||
}
|
||||
|
||||
val promise = AsyncPromise<SUB_RESULT>()
|
||||
addHandlers(Consumer({ result ->
|
||||
promise.catchError {
|
||||
if (fulfilled is Obsolescent && fulfilled.isObsolete) {
|
||||
promise.cancel()
|
||||
}
|
||||
else {
|
||||
promise.setResult(fulfilled.`fun`(result))
|
||||
}
|
||||
}
|
||||
}), Consumer({ promise.setError(it) }))
|
||||
return promise
|
||||
}
|
||||
|
||||
override fun notify(child: AsyncPromise<in T>) {
|
||||
LOG.assertTrue(child !== this)
|
||||
|
||||
when (state) {
|
||||
Promise.State.PENDING -> {
|
||||
}
|
||||
Promise.State.FULFILLED -> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
child.setResult(result as T)
|
||||
return
|
||||
}
|
||||
Promise.State.REJECTED -> {
|
||||
child.setError((result as Throwable?)!!)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
addHandlers(Consumer({ child.catchError { child.setResult(it) } }), Consumer({ child.setError(it) }))
|
||||
}
|
||||
|
||||
override fun <SUB_RESULT> thenAsync(fulfilled: Function<in T, Promise<SUB_RESULT>>): Promise<SUB_RESULT> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
when (state) {
|
||||
Promise.State.PENDING -> {
|
||||
}
|
||||
Promise.State.FULFILLED -> return fulfilled.`fun`(result as T?)
|
||||
Promise.State.REJECTED -> return rejectedPromise(result as Throwable)
|
||||
}
|
||||
|
||||
val promise = AsyncPromise<SUB_RESULT>()
|
||||
val rejectedHandler = Consumer<Throwable>({ promise.setError(it) })
|
||||
addHandlers(Consumer({
|
||||
promise.catchError {
|
||||
fulfilled.`fun`(it)
|
||||
.done { promise.catchError { promise.setResult(it) } }
|
||||
.rejected(rejectedHandler)
|
||||
}
|
||||
}), rejectedHandler)
|
||||
return promise
|
||||
}
|
||||
|
||||
override fun processed(fulfilled: AsyncPromise<in T>): Promise<T> {
|
||||
when (state) {
|
||||
Promise.State.PENDING -> {
|
||||
}
|
||||
Promise.State.FULFILLED -> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fulfilled.setResult(result as T)
|
||||
return this
|
||||
}
|
||||
Promise.State.REJECTED -> {
|
||||
fulfilled.setError((result as Throwable?)!!)
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
addHandlers(Consumer({ result -> fulfilled.catchError { fulfilled.setResult(result) } }), Consumer({ fulfilled.setError(it) }))
|
||||
return this
|
||||
}
|
||||
|
||||
private fun addHandlers(done: Consumer<T>, rejected: Consumer<Throwable>) {
|
||||
this.done = setHandler(this.done, done)
|
||||
this.rejected = setHandler(this.rejected, rejected)
|
||||
}
|
||||
|
||||
fun setResult(result: T?) {
|
||||
if (state != Promise.State.PENDING) {
|
||||
return
|
||||
}
|
||||
|
||||
this.result = result
|
||||
state = Promise.State.FULFILLED
|
||||
|
||||
val done = this.done
|
||||
clearHandlers()
|
||||
if (done != null && !isObsolete(done)) {
|
||||
done.consume(result)
|
||||
}
|
||||
}
|
||||
|
||||
fun setError(error: String): Boolean {
|
||||
return setError(Promise.createError(error))
|
||||
}
|
||||
|
||||
fun cancel() {
|
||||
setError(OBSOLETE_ERROR)
|
||||
}
|
||||
|
||||
open fun setError(error: Throwable): Boolean {
|
||||
if (state != Promise.State.PENDING) {
|
||||
return false
|
||||
}
|
||||
|
||||
result = error
|
||||
state = Promise.State.REJECTED
|
||||
|
||||
val rejected = this.rejected
|
||||
clearHandlers()
|
||||
if (rejected == null) {
|
||||
Promise.logError(LOG, error)
|
||||
}
|
||||
else if (!isObsolete(rejected)) {
|
||||
rejected.consume(error)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun clearHandlers() {
|
||||
done = null
|
||||
rejected = null
|
||||
}
|
||||
|
||||
override fun processed(processed: Consumer<in T>): Promise<T> {
|
||||
done(processed)
|
||||
rejected({ error -> processed.consume(null) })
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
private class CompoundConsumer<T>(c1: Consumer<in T>, c2: Consumer<in T>) : Consumer<T> {
|
||||
private var consumers: MutableList<Consumer<in T>>? = ArrayList()
|
||||
|
||||
init {
|
||||
synchronized(this) {
|
||||
consumers!!.add(c1)
|
||||
consumers!!.add(c2)
|
||||
}
|
||||
}
|
||||
|
||||
override fun consume(t: T) {
|
||||
val list = synchronized(this) {
|
||||
val list = consumers
|
||||
consumers = null
|
||||
list
|
||||
} ?: return
|
||||
|
||||
for (consumer in list) {
|
||||
if (!isObsolete(consumer)) {
|
||||
consumer.consume(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun add(consumer: Consumer<in T>) {
|
||||
synchronized(this) {
|
||||
if (consumers != null) {
|
||||
consumers!!.add(consumer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T> setHandler(oldConsumer: Consumer<in T>?, newConsumer: Consumer<in T>) = when (oldConsumer) {
|
||||
null -> newConsumer
|
||||
is CompoundConsumer<*> -> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(oldConsumer as CompoundConsumer<T>).add(newConsumer)
|
||||
oldConsumer
|
||||
}
|
||||
else -> CompoundConsumer(oldConsumer, newConsumer)
|
||||
}
|
||||
|
||||
internal fun isObsolete(consumer: Consumer<*>?) = consumer is Obsolescent && consumer.isObsolete
|
||||
|
||||
inline fun <T> AsyncPromise<*>.catchError(runnable: () -> T): T? {
|
||||
try {
|
||||
return runnable()
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
setError(e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private val cancelledPromise = RejectedPromise<Any?>(OBSOLETE_ERROR)
|
||||
|
||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||
fun <T> cancelledPromise(): Promise<T> = cancelledPromise as Promise<T>
|
||||
|
||||
fun <T> rejectedPromise(error: Throwable): Promise<T> = Promise.reject(error)
|
||||
+1
-1
@@ -30,7 +30,7 @@ class DonePromise<T> extends Promise<T> implements Getter<T> {
|
||||
@NotNull
|
||||
@Override
|
||||
public Promise<T> done(@NotNull Consumer<? super T> done) {
|
||||
if (!AsyncPromise.isObsolete(done)) {
|
||||
if (!AsyncPromiseKt.isObsolete(done)) {
|
||||
done.consume(result);
|
||||
}
|
||||
return this;
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
+8
-55
@@ -23,12 +23,9 @@ import com.intellij.openapi.util.AsyncResult;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.ThreeState;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public abstract class Promise<T> {
|
||||
public static final Promise<Void> DONE = new DonePromise<Void>(null);
|
||||
public static final Promise<Void> REJECTED = new RejectedPromise<Void>(createError("rejected"));
|
||||
@@ -69,54 +66,11 @@ public abstract class Promise<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> Promise<T> any(@NotNull final Collection<Promise<T>> promises, @NotNull final String totalError) {
|
||||
if (promises.isEmpty()) {
|
||||
//noinspection unchecked
|
||||
return (Promise<T>)DONE;
|
||||
}
|
||||
else if (promises.size() == 1) {
|
||||
return ContainerUtil.getFirstItem(promises);
|
||||
}
|
||||
|
||||
final AsyncPromise<T> totalPromise = new AsyncPromise<T>();
|
||||
Consumer<T> done = new Consumer<T>() {
|
||||
@Override
|
||||
public void consume(T result) {
|
||||
totalPromise.setResult(result);
|
||||
}
|
||||
};
|
||||
Consumer<Throwable> rejected = new Consumer<Throwable>() {
|
||||
private volatile int toConsume = promises.size();
|
||||
|
||||
@Override
|
||||
public void consume(Throwable throwable) {
|
||||
if (--toConsume <= 0) {
|
||||
totalPromise.setError(totalError);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (Promise<? extends T> promise : promises) {
|
||||
promise.done(done);
|
||||
promise.rejected(rejected);
|
||||
}
|
||||
return totalPromise;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Promise<Void> wrapAsVoid(@NotNull ActionCallback asyncResult) {
|
||||
final AsyncPromise<Void> promise = new AsyncPromise<Void>();
|
||||
asyncResult.doWhenDone(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
promise.setResult(null);
|
||||
}
|
||||
}).doWhenRejected(new Consumer<String>() {
|
||||
@Override
|
||||
public void consume(String error) {
|
||||
promise.setError(createError(error == null ? "Internal error" : error));
|
||||
}
|
||||
});
|
||||
asyncResult.doWhenDone(() -> promise.setResult(null)).doWhenRejected(
|
||||
error -> promise.setError(createError(error == null ? "Internal error" : error)));
|
||||
return promise;
|
||||
}
|
||||
|
||||
@@ -128,12 +82,7 @@ public abstract class Promise<T> {
|
||||
public void consume(T result) {
|
||||
promise.setResult(result);
|
||||
}
|
||||
}).doWhenRejected(new Consumer<String>() {
|
||||
@Override
|
||||
public void consume(String error) {
|
||||
promise.setError(error);
|
||||
}
|
||||
});
|
||||
}).doWhenRejected(promise::setError);
|
||||
return promise;
|
||||
}
|
||||
|
||||
@@ -183,16 +132,20 @@ public abstract class Promise<T> {
|
||||
/**
|
||||
* Log error if not message error
|
||||
*/
|
||||
public static void logError(@NotNull Logger logger, @NotNull Throwable e) {
|
||||
public static boolean logError(@NotNull Logger logger, @NotNull Throwable e) {
|
||||
if (e instanceof MessageError) {
|
||||
ThreeState log = ((MessageError)e).log;
|
||||
if (log == ThreeState.YES || (log == ThreeState.UNSURE && ApplicationManager.getApplication().isUnitTestMode())) {
|
||||
logger.error(e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (!(e instanceof ProcessCanceledException)) {
|
||||
logger.error(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract void notify(@NotNull AsyncPromise<? super T> child);
|
||||
+1
-1
@@ -42,7 +42,7 @@ class RejectedPromise<T> extends Promise<T> {
|
||||
@NotNull
|
||||
@Override
|
||||
public Promise<T> rejected(@NotNull Consumer<Throwable> rejected) {
|
||||
if (!AsyncPromise.isObsolete(rejected)) {
|
||||
if (!AsyncPromiseKt.isObsolete(rejected)) {
|
||||
rejected.consume(error);
|
||||
}
|
||||
return this;
|
||||
+27
@@ -46,4 +46,31 @@ private class CountDownConsumer<T>(@Volatile private var countDown: Int, private
|
||||
promise.setResult(totalResult)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> any(promises: Collection<Promise<T>>, totalError: String): Promise<T> {
|
||||
if (promises.isEmpty()) {
|
||||
return resolvedPromise(null)
|
||||
}
|
||||
else if (promises.size == 1) {
|
||||
return promises.first()
|
||||
}
|
||||
|
||||
val totalPromise = AsyncPromise<T>()
|
||||
val done = Consumer<T> { result -> totalPromise.setResult(result) }
|
||||
val rejected = object : Consumer<Throwable> {
|
||||
@Volatile private var toConsume = promises.size
|
||||
|
||||
override fun consume(throwable: Throwable) {
|
||||
if (--toConsume <= 0) {
|
||||
totalPromise.setError(totalError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (promise in promises) {
|
||||
promise.done(done)
|
||||
promise.rejected(rejected)
|
||||
}
|
||||
return totalPromise
|
||||
}
|
||||
+3
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -19,10 +19,8 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.fileEditor.TextEditor;
|
||||
import com.intellij.openapi.fileEditor.impl.BaseRemoteFileEditor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.impl.http.HttpVirtualFile;
|
||||
import com.intellij.openapi.vfs.impl.http.RemoteFileInfo;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.openapi.vfs.impl.http.RemoteFileInfoImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -38,7 +36,7 @@ class HttpFileEditor extends BaseRemoteFileEditor {
|
||||
super(project);
|
||||
|
||||
myPanel = new RemoteFilePanel(project, virtualFile, this);
|
||||
RemoteFileInfo fileInfo = virtualFile.getFileInfo();
|
||||
RemoteFileInfoImpl fileInfo = (RemoteFileInfoImpl)virtualFile.getFileInfo();
|
||||
assert fileInfo != null;
|
||||
fileInfo.download()
|
||||
.done(file -> ApplicationManager.getApplication().invokeLater(() -> contentLoaded(), myProject.getDisposed()))
|
||||
|
||||
+1
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -292,7 +292,6 @@ public class RemoteFileInfoImpl implements RemoteContentProvider.DownloadingCall
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Promise<VirtualFile> download() {
|
||||
synchronized (myLock) {
|
||||
switch (getState()) {
|
||||
|
||||
@@ -82,8 +82,6 @@ inline fun Promise<*>.rejected(node: Obsolescent, crossinline handler: (Throwabl
|
||||
|
||||
fun <T> rejectedPromise(error: String): Promise<T> = Promise.reject(error)
|
||||
|
||||
fun <T> rejectedPromise(error: Throwable): Promise<T> = Promise.reject(error)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> rejectedPromise(): Promise<T> = rejectedPromise as Promise<T>
|
||||
|
||||
@@ -96,16 +94,6 @@ val Promise<*>.isPending: Boolean
|
||||
val Promise<*>.isFulfilled: Boolean
|
||||
get() = state == Promise.State.FULFILLED
|
||||
|
||||
inline fun <T> AsyncPromise<*>.catchError(runnable: () -> T): T? {
|
||||
try {
|
||||
return runnable()
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
setError(e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> collectResults(promises: List<Promise<T>>): Promise<List<T>> {
|
||||
if (promises.isEmpty()) {
|
||||
return resolvedPromise(emptyList())
|
||||
|
||||
@@ -1136,7 +1136,7 @@ low.disk.space.message=Low disk space on a {0} system directory partition
|
||||
|
||||
prompt.goto.inspection.enter.name=Enter inspection name:
|
||||
goto.inspection.action.text=&Run Inspection by Name...
|
||||
goto.inspection.action.choose.inherit.settings.from=Inherit inspection options from
|
||||
goto.inspection.action.choose.inherit.settings.from=Inspection options
|
||||
label.no.inspections.found=No inspections found
|
||||
|
||||
#Scripting library management
|
||||
|
||||
+15
-17
@@ -18,7 +18,10 @@ package com.intellij.util.containers;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Conditions;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.Functions;
|
||||
import com.intellij.util.PairFunction;
|
||||
import com.intellij.util.Processor;
|
||||
import junit.framework.TestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -425,21 +428,16 @@ public class TreeTraverserTest extends TestCase {
|
||||
// GuidedTraversal ----------------------------------------------
|
||||
|
||||
@NotNull
|
||||
private static Function.Mono<TreeTraversal.GuidedIt<Integer>> initGuide(@NotNull final TreeTraversal traversal) {
|
||||
return new Function.Mono<TreeTraversal.GuidedIt<Integer>>() {
|
||||
@Override
|
||||
public TreeTraversal.GuidedIt<Integer> fun(TreeTraversal.GuidedIt<Integer> it) {
|
||||
return it.setGuide(it1 -> {
|
||||
if (traversal == TreeTraversal.PRE_ORDER_DFS) {
|
||||
it1.queueNext(it1.curChild).result(it1.curChild);
|
||||
}
|
||||
else if (traversal == TreeTraversal.POST_ORDER_DFS) {
|
||||
it1.queueNext(it1.curChild).result(it1.curChild == null ? it1.curParent : null);
|
||||
}
|
||||
else if (traversal == TreeTraversal.PLAIN_BFS) {
|
||||
it1.queueLast(it1.curChild).result(it1.curChild);
|
||||
}
|
||||
});
|
||||
private static TreeTraversal.GuidedIt.Guide<Integer> newGuide(@NotNull final TreeTraversal traversal) {
|
||||
return it -> {
|
||||
if (traversal == TreeTraversal.PRE_ORDER_DFS) {
|
||||
it.queueNext(it.curChild).result(it.curChild);
|
||||
}
|
||||
else if (traversal == TreeTraversal.POST_ORDER_DFS) {
|
||||
it.queueNext(it.curChild).result(it.curChild == null ? it.curParent : null);
|
||||
}
|
||||
else if (traversal == TreeTraversal.PLAIN_BFS) {
|
||||
it.queueLast(it.curChild).result(it.curChild);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -451,7 +449,7 @@ public class TreeTraverserTest extends TestCase {
|
||||
}
|
||||
|
||||
private static void verifyGuidedTraversal(TreeTraversal traversal) {
|
||||
assertEquals(numTraverser2(TreeTraversal.GUIDED_TRAVERSAL).fun(1).intercept(initGuide(traversal)).toList(),
|
||||
assertEquals(numTraverser2(TreeTraversal.GUIDED_TRAVERSAL(newGuide(traversal))).fun(1).toList(),
|
||||
numTraverser2(traversal).fun(1).toList());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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,8 +15,8 @@
|
||||
*/
|
||||
package org.jetbrains.debugger
|
||||
|
||||
import com.intellij.util.Consumer
|
||||
import org.jetbrains.concurrency.Promise
|
||||
import org.jetbrains.concurrency.cancelledPromise
|
||||
import org.jetbrains.debugger.values.ObjectValue
|
||||
import org.jetbrains.debugger.values.ValueManager
|
||||
|
||||
@@ -25,14 +25,10 @@ abstract class DeclarativeScope<VALUE_MANAGER : ValueManager>(type: Scope.Type,
|
||||
|
||||
protected fun loadScopeObjectProperties(value: ObjectValue): Promise<List<Variable>> {
|
||||
if (childrenManager.valueManager.isObsolete) {
|
||||
return ValueManager.reject()
|
||||
return cancelledPromise()
|
||||
}
|
||||
|
||||
return value.properties.done(object : Consumer<List<Variable>> {
|
||||
override fun consume(variables: List<Variable>) {
|
||||
childrenManager.updateCacheStamp()
|
||||
}
|
||||
})
|
||||
return value.properties.done { childrenManager.updateCacheStamp() }
|
||||
}
|
||||
|
||||
override fun getVariablesHost() = childrenManager
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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,6 +17,7 @@ package org.jetbrains.debugger;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.concurrency.AsyncPromiseKt;
|
||||
import org.jetbrains.concurrency.Promise;
|
||||
import org.jetbrains.concurrency.PromiseManager;
|
||||
import org.jetbrains.debugger.values.ValueManager;
|
||||
@@ -35,7 +36,7 @@ public abstract class VariablesHost<VALUE_MANAGER extends ValueManager> {
|
||||
@NotNull
|
||||
@Override
|
||||
public Promise load(@NotNull VariablesHost host) {
|
||||
return host.valueManager.isObsolete() ? ValueManager.Companion.reject() : host.load();
|
||||
return host.valueManager.isObsolete() ? AsyncPromiseKt.cancelledPromise() : host.load();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.debugger.values
|
||||
|
||||
import org.jetbrains.concurrency.AsyncPromise
|
||||
import org.jetbrains.concurrency.Obsolescent
|
||||
import org.jetbrains.concurrency.Promise
|
||||
import org.jetbrains.concurrency.rejectedPromise
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
/**
|
||||
@@ -43,11 +40,4 @@ abstract class ValueManager() : Obsolescent {
|
||||
fun markObsolete() {
|
||||
obsolete = true
|
||||
}
|
||||
|
||||
companion object {
|
||||
val OBSOLETE_CONTEXT_PROMISE = rejectedPromise<Any?>(AsyncPromise.OBSOLETE_ERROR)
|
||||
|
||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||
fun <T> reject() = OBSOLETE_CONTEXT_PROMISE as Promise<T>
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -54,7 +54,7 @@ fun requestToByteBuf(message: Request<*>, isDebugEnabled: Boolean = LOG.isDebugE
|
||||
return content
|
||||
}
|
||||
|
||||
interface ResultReader<RESPONSE> {
|
||||
interface ResultReader<in RESPONSE> {
|
||||
fun <RESULT> readResult(readMethodName: String, successResponse: RESPONSE): RESULT?
|
||||
}
|
||||
|
||||
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.debugger;
|
||||
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.xdebugger.XDebugSession;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.concurrency.AsyncPromise;
|
||||
import org.jetbrains.concurrency.Promise;
|
||||
import org.jetbrains.rpc.CommandProcessorKt;
|
||||
|
||||
public final class RejectErrorReporter implements Consumer<Throwable> {
|
||||
private final XDebugSession session;
|
||||
private final String description;
|
||||
|
||||
public RejectErrorReporter(@NotNull XDebugSession session) {
|
||||
this(session, null);
|
||||
}
|
||||
|
||||
public RejectErrorReporter(@NotNull XDebugSession session, @Nullable String description) {
|
||||
this.session = session;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume(Throwable error) {
|
||||
Promise.logError(CommandProcessorKt.getLOG(), error);
|
||||
if (error != AsyncPromise.OBSOLETE_ERROR) {
|
||||
session.reportError((description == null ? "" : description + ": ") + error.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -13,17 +13,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.xdebugger.util
|
||||
package org.jetbrains.debugger
|
||||
|
||||
import com.intellij.util.Consumer
|
||||
import com.intellij.xdebugger.XDebugSession
|
||||
import org.jetbrains.concurrency.AsyncPromise
|
||||
import org.jetbrains.concurrency.Promise
|
||||
import org.jetbrains.rpc.LOG
|
||||
|
||||
// have to use package "com.intellij.xdebugger.util" to avoid package clash
|
||||
fun XDebugSession.rejectedErrorReporter(description: String? = null): (Throwable) -> Unit = {
|
||||
Promise.logError(LOG, it)
|
||||
if (it != AsyncPromise.OBSOLETE_ERROR) {
|
||||
reportError("${if (description == null) "" else description + ": "}${it.message}")
|
||||
class RejectErrorReporter @JvmOverloads constructor(private val session: XDebugSession, private val description: String? = null) : Consumer<Throwable> {
|
||||
override fun consume(error: Throwable) {
|
||||
if (Promise.logError(LOG, error)) {
|
||||
session.reportError("${if (description == null) "" else "$description: "}${error.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -201,7 +201,7 @@ open class OutMessage() {
|
||||
|
||||
fun writeNullableString(name: String, value: CharSequence?) {
|
||||
beginArguments()
|
||||
writer.name(name).value(value!!.toString())
|
||||
writer.name(name).value(value?.toString() ?: null)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -708,12 +708,8 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isRunInEdt() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void runBareRunnable(ThrowableRunnable<Throwable> runnable) throws Throwable {
|
||||
if (isRunInEdt()) {
|
||||
if (runInDispatchThread()) {
|
||||
EdtTestUtil.runInEdtAndWait(runnable);
|
||||
}
|
||||
else {
|
||||
|
||||
+15
-44
@@ -27,6 +27,7 @@ import com.intellij.codeInsight.daemon.impl.*;
|
||||
import com.intellij.codeInsight.folding.CodeFoldingManager;
|
||||
import com.intellij.codeInsight.highlighting.actions.HighlightUsagesAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.impl.IntentionListStep;
|
||||
import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
|
||||
import com.intellij.codeInsight.lookup.Lookup;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
@@ -296,56 +297,26 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
|
||||
private static List<IntentionAction> doGetAvailableIntentions(@NotNull Editor editor, @NotNull PsiFile file) {
|
||||
ShowIntentionsPass.IntentionsInfo intentions = new ShowIntentionsPass.IntentionsInfo();
|
||||
ShowIntentionsPass.getActionsToShow(editor, file, intentions, -1);
|
||||
List<HighlightInfo.IntentionActionDescriptor> descriptors = new ArrayList<HighlightInfo.IntentionActionDescriptor>();
|
||||
descriptors.addAll(intentions.intentionsToShow);
|
||||
descriptors.addAll(intentions.errorFixesToShow);
|
||||
descriptors.addAll(intentions.inspectionFixesToShow);
|
||||
descriptors.addAll(intentions.guttersToShow);
|
||||
|
||||
final int fileOffset = editor.getCaretModel().getOffset();
|
||||
PsiElement hostElement = file.getViewProvider().findElementAt(fileOffset, file.getLanguage());
|
||||
PsiElement injectedElement = InjectedLanguageUtil.findElementAtNoCommit(file, fileOffset);
|
||||
|
||||
PsiFile injectedFile = injectedElement != null ? injectedElement.getContainingFile() : null;
|
||||
Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile);
|
||||
|
||||
List<IntentionAction> result = new ArrayList<IntentionAction>();
|
||||
IntentionListStep intentionListStep = new IntentionListStep(null, intentions, editor, file, file.getProject());
|
||||
for (Map.Entry<IntentionAction, List<IntentionAction>> entry : intentionListStep.getActionsWithSubActions().entrySet()) {
|
||||
result.add(entry.getKey());
|
||||
result.addAll(entry.getValue());
|
||||
}
|
||||
|
||||
List<HighlightInfo> infos = DaemonCodeAnalyzerEx.getInstanceEx(file.getProject()).getFileLevelHighlights(file.getProject(), file);
|
||||
for (HighlightInfo info : infos) {
|
||||
for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
|
||||
HighlightInfo.IntentionActionDescriptor actionInGroup = pair.first;
|
||||
final IntentionAction action = actionInGroup.getAction();
|
||||
|
||||
if (ShowIntentionActionsHandler.availableFor(file, editor, action)
|
||||
||
|
||||
injectedElement != null && hostElement != injectedElement && ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, action)) {
|
||||
descriptors.add(actionInGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add all intention options for simplicity
|
||||
for (HighlightInfo.IntentionActionDescriptor descriptor : descriptors) {
|
||||
result.add(descriptor.getAction());
|
||||
|
||||
if (injectedElement != null && injectedElement != hostElement) {
|
||||
List<IntentionAction> options = descriptor.getOptions(injectedElement, injectedEditor);
|
||||
if (options != null) {
|
||||
for (IntentionAction option : options) {
|
||||
if (ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, option)) {
|
||||
result.add(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hostElement != null) {
|
||||
List<IntentionAction> options = descriptor.getOptions(hostElement, editor);
|
||||
if (options != null) {
|
||||
for (IntentionAction option : options) {
|
||||
if (ShowIntentionActionsHandler.availableFor(file, editor, option)) {
|
||||
result.add(option);
|
||||
if (actionInGroup.getAction().isAvailable(file.getProject(), editor, file)) {
|
||||
result.add(actionInGroup.getAction());
|
||||
List<IntentionAction> options = actionInGroup.getOptions(file, editor);
|
||||
if (options != null) {
|
||||
for (IntentionAction subAction : options) {
|
||||
if (subAction.isAvailable(file.getProject(), editor, file)) {
|
||||
result.add(subAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1315,7 +1286,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
|
||||
PlatformTestCase.synchronizeTempDirVfs(tempDir);
|
||||
|
||||
myPsiManager = (PsiManagerImpl)PsiManager.getInstance(getProject());
|
||||
configureInspections(LocalInspectionTool.EMPTY_ARRAY, getProject(), Collections.<String>emptyList(), getTestRootDisposable());
|
||||
configureInspections(LocalInspectionTool.EMPTY_ARRAY, getProject(), Collections.emptyList(), getTestRootDisposable());
|
||||
|
||||
DaemonCodeAnalyzerImpl daemonCodeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject());
|
||||
daemonCodeAnalyzer.prepareForTest();
|
||||
|
||||
@@ -106,7 +106,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
private final ExporterToTextFile myTextFileExporter = new ExporterToTextFile(this);
|
||||
private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
|
||||
private final ExclusionHandler<Node> myExclusionHandler;
|
||||
private final ExclusionHandler<DefaultMutableTreeNode> myExclusionHandler;
|
||||
private final UsageModelTracker myModelTracker;
|
||||
private final Map<Usage, UsageNode> myUsageNodes = new ConcurrentHashMap<Usage, UsageNode>();
|
||||
public static final UsageNode NULL_NODE = new UsageNode(NullUsage.INSTANCE, new UsageViewTreeModelBuilder(new UsageViewPresentation(), UsageTarget.EMPTY_ARRAY));
|
||||
@@ -253,21 +253,26 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
runnable.run();
|
||||
return true;
|
||||
}, o -> isDisposed || project.isDisposed(), 200);
|
||||
myExclusionHandler = new ExclusionHandler<Node>() {
|
||||
myExclusionHandler = new ExclusionHandler<DefaultMutableTreeNode>() {
|
||||
@Override
|
||||
public boolean isNodeExcluded(@NotNull Node node) {
|
||||
return node.isDataExcluded();
|
||||
public boolean isNodeExclusionAvailable(@NotNull DefaultMutableTreeNode node) {
|
||||
return node instanceof UsageNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void excludeNode(@NotNull Node node) {
|
||||
public boolean isNodeExcluded(@NotNull DefaultMutableTreeNode node) {
|
||||
return ((UsageNode)node).isDataExcluded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void excludeNode(@NotNull DefaultMutableTreeNode node) {
|
||||
final HashSet<Usage> usages = new HashSet<>();
|
||||
collectUsages(node, usages);
|
||||
excludeUsages(usages.toArray(new Usage[usages.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void includeNode(@NotNull Node node) {
|
||||
public void includeNode(@NotNull DefaultMutableTreeNode node) {
|
||||
final HashSet<Usage> usages = new HashSet<>();
|
||||
collectUsages(node, usages);
|
||||
includeUsages(usages.toArray(new Usage[usages.size()]));
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.intellij.util.containers;
|
||||
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Conditions;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -63,7 +62,7 @@ public abstract class FilteredTraverserBase<T, Self extends FilteredTraverserBas
|
||||
return children(t);
|
||||
}
|
||||
};
|
||||
return traversal.traversal(getRoots(), adjusted).filter(meta.filter.AND());
|
||||
return traversal.traversal(getRoots(), adjusted).filter(meta.filter.AND);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -157,11 +156,11 @@ public abstract class FilteredTraverserBase<T, Self extends FilteredTraverserBas
|
||||
return JBIterable.empty();
|
||||
}
|
||||
else if (meta.regard.next == null && meta.forceDisregard.next == null) {
|
||||
return JBIterable.from(tree.fun(node)).filter(not(meta.forceIgnore.OR()));
|
||||
return JBIterable.from(tree.fun(node)).filter(not(meta.forceIgnore.OR));
|
||||
}
|
||||
else {
|
||||
// traverse subtree to select accepted children
|
||||
return TreeTraversal.GUIDED_TRAVERSAL.traversal(node, tree).intercept(meta.createChildrenGuide(node));
|
||||
return TreeTraversal.GUIDED_TRAVERSAL(meta.createChildrenGuide(node)).traversal(node, tree);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,21 +245,14 @@ public abstract class FilteredTraverserBase<T, Self extends FilteredTraverserBas
|
||||
return new Meta<T>(roots, traversal, expand, regard, this.filter, forceIgnore, forceDisregard.append(c));
|
||||
}
|
||||
|
||||
Function.Mono<TreeTraversal.GuidedIt<T>> createChildrenGuide(final T parent) {
|
||||
final Condition<? super T> expand = buildExpandConditionForChildren(parent);
|
||||
class G implements Consumer<TreeTraversal.GuidedIt<T>>, Function.Mono<TreeTraversal.GuidedIt<T>> {
|
||||
|
||||
TreeTraversal.GuidedIt.Guide<T> createChildrenGuide(final T parent) {
|
||||
return new TreeTraversal.GuidedIt.Guide<T>() {
|
||||
final Condition<? super T> expand = buildExpandConditionForChildren(parent);
|
||||
@Override
|
||||
public TreeTraversal.GuidedIt<T> fun(TreeTraversal.GuidedIt<T> it) {
|
||||
return it.setGuide(this);
|
||||
public void guide(TreeTraversal.GuidedIt<T> guidedIt) {
|
||||
doPerformChildrenGuidance(guidedIt, expand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume(TreeTraversal.GuidedIt<T> it) {
|
||||
doPerformChildrenGuidance(it, expand);
|
||||
}
|
||||
}
|
||||
return new G();
|
||||
};
|
||||
}
|
||||
|
||||
private void doPerformChildrenGuidance(TreeTraversal.GuidedIt<T> it, Condition<? super T> expand) {
|
||||
@@ -296,7 +288,7 @@ public abstract class FilteredTraverserBase<T, Self extends FilteredTraverserBas
|
||||
c = c.next;
|
||||
}
|
||||
}
|
||||
return copy == null ? Condition.FALSE : copy.OR();
|
||||
return copy == null ? Condition.FALSE : copy.OR;
|
||||
}
|
||||
|
||||
private static final Meta<?> EMPTY = new Meta<Object>(
|
||||
@@ -326,37 +318,33 @@ public abstract class FilteredTraverserBase<T, Self extends FilteredTraverserBas
|
||||
return new Cond<T>(impl, this);
|
||||
}
|
||||
|
||||
private boolean valueAnd(T t) {
|
||||
boolean valueAnd(T t) {
|
||||
for (Cond<T> c = this; c != null; c = c.next) {
|
||||
if (!c.impl.value(t)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean valueOr(T t) {
|
||||
boolean valueOr(T t) {
|
||||
for (Cond<T> c = this; c != null; c = c.next) {
|
||||
if (c.impl.value(t)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Condition<? super T> OR() {
|
||||
return new Condition<T>() {
|
||||
@Override
|
||||
public boolean value(T t) {
|
||||
return valueOr(t);
|
||||
}
|
||||
};
|
||||
}
|
||||
final Condition<? super T> OR = new Condition<T>() {
|
||||
@Override
|
||||
public boolean value(T t) {
|
||||
return valueOr(t);
|
||||
}
|
||||
};
|
||||
|
||||
Condition<? super T> AND() {
|
||||
return new Condition<T>() {
|
||||
@Override
|
||||
public boolean value(T t) {
|
||||
return valueAnd(t);
|
||||
}
|
||||
};
|
||||
}
|
||||
final Condition<? super T> AND = new Condition<T>() {
|
||||
@Override
|
||||
public boolean value(T t) {
|
||||
return valueAnd(t);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.intellij.util.containers;
|
||||
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.Functions;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -148,14 +147,17 @@ public abstract class TreeTraversal {
|
||||
}
|
||||
|
||||
public static abstract class GuidedIt<T> extends It<T> {
|
||||
|
||||
public interface Guide<T> {
|
||||
void guide(GuidedIt<T> guidedIt);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public T curChild, curParent;
|
||||
@Nullable
|
||||
public Iterable<? extends T> curChildren;
|
||||
public boolean curNoChildren;
|
||||
|
||||
public abstract GuidedIt<T> setGuide(Consumer<GuidedIt<T>> guide);
|
||||
|
||||
public abstract GuidedIt<T> queueNext(T child);
|
||||
public abstract GuidedIt<T> result(T node);
|
||||
public abstract GuidedIt<T> queueLast(T child);
|
||||
@@ -166,13 +168,16 @@ public abstract class TreeTraversal {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static final TreeTraversal GUIDED_TRAVERSAL = new TreeTraversal("GUIDED_TRAVERSAL") {
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> It<T> createIterator(@NotNull Iterable<? extends T> roots, @NotNull Function<T, ? extends Iterable<? extends T>> tree) {
|
||||
return new GuidedItImpl<T>(roots, tree);
|
||||
}
|
||||
};
|
||||
public static TreeTraversal GUIDED_TRAVERSAL(@NotNull final GuidedIt.Guide<?> guide) {
|
||||
return new TreeTraversal("GUIDED_TRAVERSAL") {
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> It<T> createIterator(@NotNull Iterable<? extends T> roots, @NotNull Function<T, ? extends Iterable<? extends T>> tree) {
|
||||
//noinspection unchecked
|
||||
return new GuidedItImpl<T>(roots, tree, (GuidedIt.Guide<T>)guide);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the nodes in a tree structure, using pre-order
|
||||
@@ -503,19 +508,17 @@ public abstract class TreeTraversal {
|
||||
// Misc
|
||||
// -----------------------------------------------------------------------------
|
||||
private static final class GuidedItImpl<T> extends GuidedIt<T> {
|
||||
P1<T> first, last;
|
||||
final Guide<T> guide;
|
||||
|
||||
Consumer<GuidedIt<T>> guide;
|
||||
P1<T> first, last;
|
||||
T curResult;
|
||||
|
||||
GuidedItImpl(@NotNull Iterable<? extends T> roots, Function<T, ? extends Iterable<? extends T>> tree) {
|
||||
GuidedItImpl(@NotNull Iterable<? extends T> roots,
|
||||
@NotNull Function<T, ? extends Iterable<? extends T>> tree,
|
||||
@NotNull Guide<T> guide) {
|
||||
super(tree);
|
||||
first = last = P1.create(roots);
|
||||
}
|
||||
|
||||
public GuidedIt<T> setGuide(Consumer<GuidedIt<T>> guide) {
|
||||
this.guide = guide;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GuidedIt<T> queueNext(T child) {
|
||||
@@ -546,7 +549,7 @@ public abstract class TreeTraversal {
|
||||
curParent = top.node;
|
||||
curChildren = top.itle;
|
||||
curNoChildren = top.empty;
|
||||
guide.consume(this);
|
||||
guide.guide(this);
|
||||
}
|
||||
if (!hasNext) {
|
||||
last = last.remove();
|
||||
|
||||
@@ -88,7 +88,7 @@ abstract class VcsPlatformTest : PlatformTestCase() {
|
||||
// we don't need a module in Git tests
|
||||
}
|
||||
|
||||
override fun isRunInEdt(): Boolean {
|
||||
override fun runInDispatchThread(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -206,9 +206,4 @@ public abstract class GithubTest extends GitPlatformTest {
|
||||
|
||||
protected void afterTest() throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isRunInEdt() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+19
-2
@@ -20,11 +20,15 @@ import com.intellij.lang.properties.IProperty;
|
||||
import com.intellij.lang.properties.PropertiesBundle;
|
||||
import com.intellij.lang.properties.PropertiesImplUtil;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.lang.properties.xml.XmlPropertiesFileImpl;
|
||||
import com.intellij.lang.properties.xml.XmlProperty;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.pom.PomTargetPsiElement;
|
||||
import com.intellij.pom.references.PomService;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -32,7 +36,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -40,7 +43,7 @@ import java.util.Set;
|
||||
* @author nik
|
||||
*/
|
||||
public abstract class PropertyReferenceBase implements PsiPolyVariantReference, EmptyResolveMessageProvider {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.lang.properties.references.PropertyReferenceBase");
|
||||
private static final Logger LOG = Logger.getInstance(PropertyReferenceBase.class);
|
||||
protected final String myKey;
|
||||
protected final PsiElement myElement;
|
||||
protected boolean mySoft;
|
||||
@@ -114,6 +117,7 @@ public abstract class PropertyReferenceBase implements PsiPolyVariantReference,
|
||||
}
|
||||
|
||||
public boolean isReferenceTo(PsiElement element) {
|
||||
if (!isProperty(element)) return false;
|
||||
for (ResolveResult result : multiResolve(false)) {
|
||||
final PsiElement el = result.getElement();
|
||||
if (el != null && el.isEquivalentTo(element)) return true;
|
||||
@@ -181,4 +185,17 @@ public abstract class PropertyReferenceBase implements PsiPolyVariantReference,
|
||||
public Object[] getVariants() {
|
||||
return ArrayUtil.EMPTY_OBJECT_ARRAY;
|
||||
}
|
||||
|
||||
private static boolean isProperty(PsiElement element) {
|
||||
if (element instanceof IProperty) {
|
||||
return true;
|
||||
}
|
||||
if (element instanceof PomTargetPsiElement) {
|
||||
return ((PomTargetPsiElement)element).getTarget() instanceof XmlProperty;
|
||||
}
|
||||
if (element instanceof XmlTag && ((XmlTag)element).getName().equals(XmlPropertiesFileImpl.ENTRY_TAG_NAME)) {
|
||||
return PropertiesImplUtil.isPropertiesFile(element.getContainingFile());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -46,6 +46,8 @@ import java.util.*;
|
||||
* Date: 7/26/11
|
||||
*/
|
||||
public class XmlPropertiesFileImpl extends XmlPropertiesFile {
|
||||
public static final String ENTRY_TAG_NAME = "entry";
|
||||
|
||||
private static final Key<CachedValue<PropertiesFile>> KEY = Key.create("xml properties file");
|
||||
private final XmlFile myFile;
|
||||
|
||||
@@ -62,7 +64,7 @@ public class XmlPropertiesFileImpl extends XmlPropertiesFile {
|
||||
XmlTag rootTag = myFile.getRootTag();
|
||||
final List<IProperty> propertiesOrder = new ArrayList<IProperty>();
|
||||
if (rootTag != null) {
|
||||
XmlTag[] entries = rootTag.findSubTags("entry");
|
||||
XmlTag[] entries = rootTag.findSubTags(ENTRY_TAG_NAME);
|
||||
for (XmlTag entry : entries) {
|
||||
XmlProperty property = new XmlProperty(entry, this);
|
||||
propertiesOrder.add(property);
|
||||
|
||||
@@ -121,10 +121,10 @@ public class XmlSmartEnterProcessor extends SmartEnterProcessor {
|
||||
}
|
||||
else if (probableCommaOffset >= text.length() || ((ch = text.charAt(probableCommaOffset)) != '/' && ch != '>')) {
|
||||
final XmlAttribute xmlAttribute = PsiTreeUtil.getParentOfType(atCaret, XmlAttribute.class, false, XmlTag.class);
|
||||
final CharSequence text2insert = getClosingPart(xmlAttribute, tagAtCaret, true);
|
||||
final String text2insert = getClosingPart(xmlAttribute, tagAtCaret, true);
|
||||
|
||||
doc.insertString(insertionOffset, text2insert);
|
||||
caretTo = insertionOffset + (text2insert.length() > 2 ? 1 : text2insert.length());
|
||||
caretTo = insertionOffset + text2insert.indexOf('>') + 1;
|
||||
}
|
||||
|
||||
commitChanges(project, editor, psiFile, caretTo, null);
|
||||
|
||||
Reference in New Issue
Block a user