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:
+5
-2
@@ -80,9 +80,12 @@ sun.java2d.noddraw=true
|
||||
sun.java2d.d3d=false
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Workaround for slow scrolling in JDK6
|
||||
# Set swing.bufferPerWindow=false to workaround a slow scrolling in JDK6 (see IDEA-35883),
|
||||
# But this may lead to performance degradation, because it disables a double buffering,
|
||||
# which is needed to eliminate tearing on blit-accelerated scrolling and to restore
|
||||
# a frame buffer content without the usual repainting, even when the EDT is blocked.
|
||||
#---------------------------------------------------------------------
|
||||
swing.bufferPerWindow=false
|
||||
swing.bufferPerWindow=true
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Removing this property may lead to editor performance degradation under X Window.
|
||||
|
||||
@@ -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.
|
||||
@@ -383,14 +383,15 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy {
|
||||
catch (UnsupportedOperationException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
|
||||
if (Patches.JDK_BUG_EVENT_CONTROLLER_LEAK) {
|
||||
// Memory leak workaround, see IDEA-163334
|
||||
TargetVM target = ReflectionUtil.getField(myVirtualMachine.getClass(), myVirtualMachine, TargetVM.class, "target");
|
||||
if (target != null) {
|
||||
Thread controller = ReflectionUtil.getField(target.getClass(), target, Thread.class, "eventController");
|
||||
if (controller != null) {
|
||||
controller.stop();
|
||||
finally {
|
||||
if (Patches.JDK_BUG_EVENT_CONTROLLER_LEAK) {
|
||||
// Memory leak workaround, see IDEA-163334
|
||||
TargetVM target = ReflectionUtil.getField(myVirtualMachine.getClass(), myVirtualMachine, TargetVM.class, "target");
|
||||
if (target != null) {
|
||||
Thread controller = ReflectionUtil.getField(target.getClass(), target, Thread.class, "eventController");
|
||||
if (controller != null) {
|
||||
controller.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ public class CaptureConfigurable implements SearchableConfigurable {
|
||||
}
|
||||
});
|
||||
try {
|
||||
JDOMUtil.writeDocument(new Document(rootElement), wrapper.getFile(), "\n");
|
||||
JDOMUtil.write(rootElement, wrapper.getFile());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
final String msg = ex.getLocalizedMessage();
|
||||
|
||||
@@ -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.
|
||||
@@ -23,7 +23,6 @@ import com.intellij.openapi.extensions.PluginId;
|
||||
import com.intellij.openapi.module.ModuleType;
|
||||
import com.intellij.openapi.module.ModuleTypeManager;
|
||||
import com.intellij.openapi.util.ClearableLazyValue;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.platform.ProjectTemplate;
|
||||
import com.intellij.platform.ProjectTemplatesFactory;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -95,7 +94,7 @@ public class RemoteTemplatesFactory extends ProjectTemplatesFactory {
|
||||
@NotNull
|
||||
@TestOnly
|
||||
public static MultiMap<String, ArchivedProjectTemplate> createFromText(@NotNull String value) throws IOException, JDOMException {
|
||||
return create(JDOMUtil.loadDocument(value).getRootElement());
|
||||
return create(JdomKt.loadElement(value));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+23
-5
@@ -49,6 +49,9 @@ public class DataFlowRunner {
|
||||
|
||||
private Instruction[] myInstructions;
|
||||
private final MultiMap<PsiElement, DfaMemoryState> myNestedClosures = new MultiMap<>();
|
||||
// Closures which were registered for previous instruction and can be queried by visitor
|
||||
// to adjust them somehow
|
||||
private final List<DfaMemoryState> myStackTopClosures = new ArrayList<>();
|
||||
@NotNull
|
||||
private final DfaValueFactory myValueFactory;
|
||||
private final boolean myShouldCheckLimitTime;
|
||||
@@ -90,6 +93,10 @@ public class DataFlowRunner {
|
||||
return Collections.singletonList(createMemoryState());
|
||||
}
|
||||
|
||||
List<DfaMemoryState> getStackTopClosures() {
|
||||
return new ArrayList<>(myStackTopClosures);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final RunnerResult analyzeMethod(@NotNull PsiElement psiBlock, @NotNull InstructionVisitor visitor) {
|
||||
Collection<DfaMemoryState> initialStates = createInitialStates(psiBlock, visitor);
|
||||
@@ -109,6 +116,7 @@ public class DataFlowRunner {
|
||||
int endOffset = flow.getInstructionCount();
|
||||
myInstructions = flow.getInstructions();
|
||||
myNestedClosures.clear();
|
||||
myStackTopClosures.clear();
|
||||
|
||||
Set<Instruction> joinInstructions = ContainerUtil.newHashSet();
|
||||
for (int index = 0; index < myInstructions.length; index++) {
|
||||
@@ -270,6 +278,9 @@ public class DataFlowRunner {
|
||||
@NotNull
|
||||
protected DfaInstructionState[] acceptInstruction(@NotNull InstructionVisitor visitor, @NotNull DfaInstructionState instructionState) {
|
||||
Instruction instruction = instructionState.getInstruction();
|
||||
DfaInstructionState[] states = instruction.accept(this, instructionState.getMemoryState(), visitor);
|
||||
|
||||
myStackTopClosures.clear();
|
||||
PsiElement closure = DfaUtil.getClosureInside(instruction);
|
||||
if (closure instanceof PsiClass) {
|
||||
registerNestedClosures(instructionState, (PsiClass)closure);
|
||||
@@ -277,7 +288,7 @@ public class DataFlowRunner {
|
||||
registerNestedClosures(instructionState, (PsiLambdaExpression)closure);
|
||||
}
|
||||
|
||||
return instruction.accept(this, instructionState.getMemoryState(), visitor);
|
||||
return states;
|
||||
}
|
||||
|
||||
private void registerNestedClosures(@NotNull DfaInstructionState instructionState, @NotNull PsiClass nestedClass) {
|
||||
@@ -285,14 +296,14 @@ public class DataFlowRunner {
|
||||
for (PsiMethod method : nestedClass.getMethods()) {
|
||||
PsiCodeBlock body = method.getBody();
|
||||
if (body != null) {
|
||||
myNestedClosures.putValue(body, state.createClosureState());
|
||||
myNestedClosures.putValue(body, createClosureState(state));
|
||||
}
|
||||
}
|
||||
for (PsiClassInitializer initializer : nestedClass.getInitializers()) {
|
||||
myNestedClosures.putValue(initializer.getBody(), state.createClosureState());
|
||||
myNestedClosures.putValue(initializer.getBody(), createClosureState(state));
|
||||
}
|
||||
for (PsiField field : nestedClass.getFields()) {
|
||||
myNestedClosures.putValue(field, state.createClosureState());
|
||||
myNestedClosures.putValue(field, createClosureState(state));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,10 +311,17 @@ public class DataFlowRunner {
|
||||
DfaMemoryState state = instructionState.getMemoryState();
|
||||
PsiElement body = expr.getBody();
|
||||
if (body != null) {
|
||||
myNestedClosures.putValue(body, state.createClosureState());
|
||||
myNestedClosures.putValue(body, createClosureState(state));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private DfaMemoryState createClosureState(DfaMemoryState state) {
|
||||
DfaMemoryState closureState = state.createClosureState();
|
||||
myStackTopClosures.add(closureState);
|
||||
return closureState;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected DfaMemoryState createMemoryState() {
|
||||
return new DfaMemoryStateImpl(myValueFactory);
|
||||
|
||||
-10
@@ -53,8 +53,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
// dfa value id -> indices in myEqClasses list of the classes which contain the id (or wrapped)
|
||||
private final TIntObjectHashMap<int[]> myIdToEqClassesIndices;
|
||||
private final Stack<DfaValue> myStack;
|
||||
// Closures which correspond to the stack top (do not track other closures for now)
|
||||
private final List<DfaMemoryState> myStackTopClosures = new ArrayList<>();
|
||||
private final TLongHashSet myDistinctClasses;
|
||||
private final LinkedHashMap<DfaVariableValue,DfaVariableState> myVariableStates;
|
||||
private final Map<DfaVariableValue,DfaVariableState> myDefaultVariableStates;
|
||||
@@ -118,14 +116,9 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
copy.flushDependencies(value);
|
||||
}
|
||||
copy.emptyStack();
|
||||
myStackTopClosures.add(copy);
|
||||
return copy;
|
||||
}
|
||||
|
||||
List<DfaMemoryState> getStackTopClosures() {
|
||||
return new ArrayList<>(myStackTopClosures);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) return true;
|
||||
if (!(obj instanceof DfaMemoryStateImpl)) return false;
|
||||
@@ -241,7 +234,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
@Override
|
||||
public DfaValue pop() {
|
||||
myCachedHash = null;
|
||||
myStackTopClosures.clear();
|
||||
return myStack.pop();
|
||||
}
|
||||
|
||||
@@ -253,14 +245,12 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
@Override
|
||||
public void push(@NotNull DfaValue value) {
|
||||
myCachedHash = null;
|
||||
myStackTopClosures.clear();
|
||||
myStack.push(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emptyStack() {
|
||||
myCachedHash = null;
|
||||
myStackTopClosures.clear();
|
||||
while (!myStack.isEmpty() && !(myStack.peek() instanceof DfaControlTransferValue)) {
|
||||
myStack.pop();
|
||||
}
|
||||
|
||||
+1
-1
@@ -229,7 +229,7 @@ public class StandardInstructionVisitor extends InstructionVisitor {
|
||||
if (methodName == null || !OPTIONAL_METHOD_NAMES.contains(methodName)) return Collections.emptyList();
|
||||
PsiMethod method = call.resolveMethod();
|
||||
if (method == null || !TypeUtils.isOptional(method.getContainingClass())) return Collections.emptyList();
|
||||
List<DfaMemoryState> closures = ((DfaMemoryStateImpl)memState).getStackTopClosures();
|
||||
List<DfaMemoryState> closures = runner.getStackTopClosures();
|
||||
DfaValue[] argValues = popCallArguments(instruction, runner, memState);
|
||||
final DfaValue qualifier = popQualifier(instruction, runner, memState);
|
||||
switch (methodName) {
|
||||
|
||||
+48
-11
@@ -890,6 +890,10 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
|
||||
.parameterCount(1);
|
||||
private static final CallMatcher INT_STREAM_RANGE =
|
||||
CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_STREAM_INT_STREAM, "range").parameterTypes("int", "int");
|
||||
private static final CallMatcher MIN_INT =
|
||||
CallMatcher.anyOf(
|
||||
CallMatcher.staticCall(CommonClassNames.JAVA_LANG_MATH, "min").parameterTypes("int", "int"),
|
||||
CallMatcher.staticCall(CommonClassNames.JAVA_LANG_INTEGER, "min").parameterTypes("int", "int"));
|
||||
|
||||
private final String myName;
|
||||
|
||||
@@ -913,8 +917,10 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
|
||||
public PsiElement simplify(PsiMethodCallExpression mapToObjCall) {
|
||||
Project project = mapToObjCall.getProject();
|
||||
PsiExpression mapper = ArrayUtil.getFirstElement(mapToObjCall.getArgumentList().getExpressions());
|
||||
IndexedContainer container = extractContainer(getQualifierMethodCall(mapToObjCall), mapper);
|
||||
if (container == null) return null;
|
||||
LimitedContainer limitedContainer = extractContainer(getQualifierMethodCall(mapToObjCall), mapper);
|
||||
if (limitedContainer == null) return null;
|
||||
IndexedContainer container = limitedContainer.myContainer;
|
||||
PsiExpression limit = limitedContainer.myLimit;
|
||||
PsiExpression containerQualifier = container.getQualifier();
|
||||
PsiType type = containerQualifier.getType();
|
||||
PsiType elementType = container.getElementType();
|
||||
@@ -929,6 +935,9 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
|
||||
}
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
CommentTracker ct = new CommentTracker();
|
||||
if (limit != null) {
|
||||
replacement += ".limit(" + ct.text(limit) + ")";
|
||||
}
|
||||
if (mapper instanceof PsiMethodReferenceExpression) {
|
||||
mapper = LambdaRefactoringUtil.convertMethodReferenceToLambda((PsiMethodReferenceExpression)mapper, false, true);
|
||||
}
|
||||
@@ -975,22 +984,39 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
|
||||
static CallHandler<CallChainSimplification> handler() {
|
||||
return CallHandler.of(INT_STREAM_MAP, call -> {
|
||||
PsiExpression mapper = call.getArgumentList().getExpressions()[0];
|
||||
IndexedContainer container = extractContainer(getQualifierMethodCall(call), mapper);
|
||||
if (container == null) return null;
|
||||
return new ReplaceWithElementIterationFix(container, call.getMethodExpression().getReferenceName());
|
||||
LimitedContainer limitedContainer = extractContainer(getQualifierMethodCall(call), mapper);
|
||||
if (limitedContainer == null) return null;
|
||||
return new ReplaceWithElementIterationFix(limitedContainer.myContainer, call.getMethodExpression().getReferenceName());
|
||||
});
|
||||
}
|
||||
|
||||
@Contract("null, _ -> null")
|
||||
private static IndexedContainer extractContainer(PsiMethodCallExpression qualifierCall, PsiExpression mapper) {
|
||||
private static LimitedContainer extractContainer(PsiMethodCallExpression qualifierCall, PsiExpression mapper) {
|
||||
if (!INT_STREAM_RANGE.test(qualifierCall)) return null;
|
||||
PsiExpression[] rangeArgs = qualifierCall.getArgumentList().getExpressions();
|
||||
if (!ExpressionUtils.isZero(rangeArgs[0])) return null;
|
||||
PsiExpression bound = rangeArgs[1];
|
||||
PsiExpression bound = ExpressionUtils.resolveExpression(rangeArgs[1]);
|
||||
IndexedContainer container = IndexedContainer.fromLengthExpression(bound);
|
||||
if (container == null || !StreamApiUtil.isSupportedStreamElement(container.getElementType())) return null;
|
||||
PsiExpression limit = null;
|
||||
if (container == null) {
|
||||
if(bound instanceof PsiMethodCallExpression && MIN_INT.test((PsiMethodCallExpression)bound)) {
|
||||
PsiExpression[] args = ((PsiMethodCallExpression)bound).getArgumentList().getExpressions();
|
||||
container = IndexedContainer.fromLengthExpression(args[0]);
|
||||
if(container != null) {
|
||||
limit = args[1];
|
||||
} else {
|
||||
container = IndexedContainer.fromLengthExpression(args[1]);
|
||||
if(container != null) {
|
||||
limit = args[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if(container == null) return null;
|
||||
}
|
||||
if (!StreamApiUtil.isSupportedStreamElement(container.getElementType())) return null;
|
||||
LimitedContainer limitedContainer = new LimitedContainer(container, limit);
|
||||
if (mapper instanceof PsiMethodReferenceExpression && container.isGetMethodReference((PsiMethodReferenceExpression)mapper)) {
|
||||
return container;
|
||||
return limitedContainer;
|
||||
}
|
||||
if (mapper instanceof PsiLambdaExpression) {
|
||||
PsiLambdaExpression lambda = (PsiLambdaExpression)mapper;
|
||||
@@ -1001,12 +1027,23 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
|
||||
if (body == null) return null;
|
||||
Collection<PsiReference> refs = ReferencesSearch.search(indexParameter, new LocalSearchScope(body)).findAll();
|
||||
if (!refs.isEmpty() &&
|
||||
refs.stream().allMatch(ref -> container.extractGetExpressionFromIndex(tryCast(ref, PsiExpression.class)) != null)) {
|
||||
return container;
|
||||
refs.stream()
|
||||
.allMatch(ref -> limitedContainer.myContainer.extractGetExpressionFromIndex(tryCast(ref, PsiExpression.class)) != null)) {
|
||||
return limitedContainer;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static class LimitedContainer {
|
||||
@NotNull final IndexedContainer myContainer;
|
||||
@Nullable final PsiExpression myLimit;
|
||||
|
||||
LimitedContainer(@NotNull IndexedContainer container, @Nullable PsiExpression limit) {
|
||||
myContainer = container;
|
||||
myLimit = limit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class RemoveBooleanIdentityFix implements CallChainSimplification {
|
||||
|
||||
@@ -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.
|
||||
@@ -46,9 +46,7 @@ import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.sun.tools.doclint.DocLint
|
||||
import java.io.File
|
||||
|
||||
class JavadocHtmlLintAnnotator() :
|
||||
ExternalAnnotator<JavadocHtmlLintAnnotator.Info, JavadocHtmlLintAnnotator.Result>() {
|
||||
|
||||
class JavadocHtmlLintAnnotator : ExternalAnnotator<JavadocHtmlLintAnnotator.Info, JavadocHtmlLintAnnotator.Result>() {
|
||||
data class Info(val file: PsiFile)
|
||||
data class Anno(val row: Int, val col: Int, val error: Boolean, val message: String)
|
||||
data class Result(val annotations: List<Anno>)
|
||||
|
||||
@@ -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.
|
||||
@@ -25,5 +25,5 @@ class JavadocHtmlLintInspection : LocalInspectionTool(), ExternalAnnotatorBatchI
|
||||
val SHORT_NAME = "JavadocHtmlLint"
|
||||
}
|
||||
|
||||
override fun getBatchSuppressActions(element: PsiElement?) = SuppressQuickFix.EMPTY_ARRAY
|
||||
override fun getBatchSuppressActions(element: PsiElement?): Array<out SuppressQuickFix> = SuppressQuickFix.EMPTY_ARRAY
|
||||
}
|
||||
+42
-22
@@ -45,6 +45,8 @@ import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.slicer.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.indexing.FileBasedIndex;
|
||||
@@ -325,42 +327,60 @@ public class MagicConstantInspection extends BaseJavaLocalInspectionTool {
|
||||
private static AllowedValues getAllowedValuesFromMagic(@NotNull PsiType type,
|
||||
@NotNull PsiAnnotation magic,
|
||||
@NotNull PsiManager manager) {
|
||||
PsiAnnotationMemberValue[] allowedValues;
|
||||
final boolean canBeOred;
|
||||
PsiAnnotationMemberValue[] allowedValues = PsiAnnotationMemberValue.EMPTY_ARRAY;
|
||||
boolean values = false, flags = false;
|
||||
if (TypeConversionUtil.getTypeRank(type) <= TypeConversionUtil.LONG_RANK) {
|
||||
PsiAnnotationMemberValue intValues = magic.findAttributeValue("intValues");
|
||||
allowedValues = intValues instanceof PsiArrayInitializerMemberValue ? ((PsiArrayInitializerMemberValue)intValues).getInitializers() : PsiAnnotationMemberValue.EMPTY_ARRAY;
|
||||
if (allowedValues.length == 0) {
|
||||
PsiAnnotationMemberValue orValue = magic.findAttributeValue("flags");
|
||||
allowedValues = orValue instanceof PsiArrayInitializerMemberValue ? ((PsiArrayInitializerMemberValue)orValue).getInitializers() : PsiAnnotationMemberValue.EMPTY_ARRAY;
|
||||
canBeOred = true;
|
||||
if (intValues instanceof PsiArrayInitializerMemberValue) {
|
||||
final PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue)intValues).getInitializers();
|
||||
if (initializers.length != 0) {
|
||||
allowedValues = initializers;
|
||||
values = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
canBeOred = false;
|
||||
if (!values) {
|
||||
PsiAnnotationMemberValue orValue = magic.findAttributeValue("flags");
|
||||
if (orValue instanceof PsiArrayInitializerMemberValue) {
|
||||
final PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue)orValue).getInitializers();
|
||||
if (initializers.length != 0) {
|
||||
allowedValues = initializers;
|
||||
flags = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type.equals(PsiType.getJavaLangString(manager, GlobalSearchScope.allScope(manager.getProject())))) {
|
||||
PsiAnnotationMemberValue strValuesAttr = magic.findAttributeValue("stringValues");
|
||||
allowedValues = strValuesAttr instanceof PsiArrayInitializerMemberValue ? ((PsiArrayInitializerMemberValue)strValuesAttr).getInitializers() : PsiAnnotationMemberValue.EMPTY_ARRAY;
|
||||
canBeOred = false;
|
||||
if (strValuesAttr instanceof PsiArrayInitializerMemberValue) {
|
||||
final PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue)strValuesAttr).getInitializers();
|
||||
if (initializers.length != 0) {
|
||||
allowedValues = initializers;
|
||||
values = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return null; //other types not supported
|
||||
}
|
||||
|
||||
if (allowedValues.length != 0) {
|
||||
return new AllowedValues(allowedValues, canBeOred);
|
||||
PsiAnnotationMemberValue[] valuesFromClass = readFromClass("valuesFromClass", magic, type, manager);
|
||||
if (valuesFromClass != null) {
|
||||
allowedValues = ArrayUtil.mergeArrays(allowedValues, valuesFromClass, PsiAnnotationMemberValue.ARRAY_FACTORY);
|
||||
values = true;
|
||||
}
|
||||
|
||||
// last resort: try valuesFromClass
|
||||
PsiAnnotationMemberValue[] values = readFromClass("valuesFromClass", magic, type, manager);
|
||||
boolean ored = false;
|
||||
if (values == null) {
|
||||
values = readFromClass("flagsFromClass", magic, type, manager);
|
||||
ored = true;
|
||||
PsiAnnotationMemberValue[] flagsFromClass = readFromClass("flagsFromClass", magic, type, manager);
|
||||
if (flagsFromClass != null) {
|
||||
allowedValues = ArrayUtil.mergeArrays(allowedValues, flagsFromClass, PsiAnnotationMemberValue.ARRAY_FACTORY);
|
||||
flags = true;
|
||||
}
|
||||
if (values == null) return null;
|
||||
return new AllowedValues(values, ored);
|
||||
if (allowedValues.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (values && flags) {
|
||||
throw new IncorrectOperationException(
|
||||
"Misconfiguration of @MagicConstant annotation: 'flags' and 'values' shouldn't be used at the same time");
|
||||
}
|
||||
return new AllowedValues(allowedValues, flags);
|
||||
}
|
||||
|
||||
private static PsiAnnotationMemberValue[] readFromClass(@NonNls @NotNull String attributeName,
|
||||
|
||||
+7
-5
@@ -106,7 +106,8 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
return initializerClass != null &&
|
||||
varClass != null &&
|
||||
CommonClassNames.JAVA_UTIL_HASH_MAP.equals(initializerClass.getQualifiedName()) &&
|
||||
CommonClassNames.JAVA_UTIL_MAP.equals(varClass.getQualifiedName());
|
||||
CommonClassNames.JAVA_UTIL_MAP.equals(varClass.getQualifiedName()) &&
|
||||
!ConstructionUtils.isCustomizedEmptyCollectionInitializer(initializer);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -315,13 +316,14 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
PsiClassType rawVarType = type instanceof PsiClassType ? ((PsiClassType)type).rawType() : null;
|
||||
if (rawType != null && rawVarType != null &&
|
||||
rawType.equalsToText(CommonClassNames.JAVA_UTIL_ARRAY_LIST) &&
|
||||
(rawVarType.equalsToText(CommonClassNames.JAVA_UTIL_LIST) || rawVarType.equalsToText(CommonClassNames.JAVA_UTIL_COLLECTION))) {
|
||||
(rawVarType.equalsToText(CommonClassNames.JAVA_UTIL_LIST) || rawVarType.equalsToText(CommonClassNames.JAVA_UTIL_COLLECTION)) &&
|
||||
!ConstructionUtils.isCustomizedEmptyCollectionInitializer(initializer)) {
|
||||
collector = "toList()";
|
||||
}
|
||||
else if (rawType != null && rawVarType != null &&
|
||||
rawType.equalsToText(CommonClassNames.JAVA_UTIL_HASH_SET) &&
|
||||
(rawVarType.equalsToText(CommonClassNames.JAVA_UTIL_SET) ||
|
||||
rawVarType.equalsToText(CommonClassNames.JAVA_UTIL_COLLECTION))) {
|
||||
(rawVarType.equalsToText(CommonClassNames.JAVA_UTIL_SET) || rawVarType.equalsToText(CommonClassNames.JAVA_UTIL_COLLECTION)) &&
|
||||
!ConstructionUtils.isCustomizedEmptyCollectionInitializer(initializer)) {
|
||||
collector = "toSet()";
|
||||
}
|
||||
else {
|
||||
@@ -331,7 +333,7 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
PsiExpressionList argumentList = ((PsiNewExpression)copy).getArgumentList();
|
||||
if (argumentList != null) {
|
||||
PsiExpression arg = ArrayUtil.getFirstElement(argumentList.getExpressions());
|
||||
if (arg != null) {
|
||||
if (arg != null && !(arg.getType() instanceof PsiPrimitiveType)) {
|
||||
arg.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,27 @@
|
||||
/*
|
||||
* 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.jarFinder;
|
||||
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.io.StreamUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.JdomKt;
|
||||
import com.intellij.util.io.HttpRequests;
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -52,14 +66,14 @@ public abstract class SourceSearcher {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected static Document readDocumentCancelable(final ProgressIndicator indicator, String url) throws IOException {
|
||||
protected static Element readDocumentCancelable(final ProgressIndicator indicator, String url) throws IOException {
|
||||
return HttpRequests.request(url)
|
||||
.accept("application/xml")
|
||||
.connect(new HttpRequests.RequestProcessor<Document>() {
|
||||
.connect(new HttpRequests.RequestProcessor<Element>() {
|
||||
@Override
|
||||
public Document process(@NotNull HttpRequests.Request request) throws IOException {
|
||||
public Element process(@NotNull HttpRequests.Request request) throws IOException {
|
||||
try {
|
||||
return JDOMUtil.loadDocument(request.getReader(indicator));
|
||||
return JdomKt.loadElement(request.getReader(indicator));
|
||||
}
|
||||
catch (JDOMException e) {
|
||||
throw new IOException(e);
|
||||
|
||||
+28
-9
@@ -18,8 +18,8 @@ package com.intellij.psi.impl.source.resolve.reference.impl;
|
||||
import com.intellij.codeInsight.completion.InsertHandler;
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.completion.JavaLookupElementBuilder;
|
||||
import com.intellij.codeInsight.completion.PrioritizedLookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
import static com.intellij.psi.impl.source.resolve.reference.impl.JavaReflectionReferenceUtil.*;
|
||||
|
||||
@@ -71,7 +72,7 @@ public class JavaLangClassMemberReference extends PsiReferenceBase<PsiLiteralExp
|
||||
|
||||
case DECLARED_FIELD: {
|
||||
PsiField field = psiClass.findFieldByName(name, false);
|
||||
return isReachable(field, psiClass) ? field : null;
|
||||
return isPotentiallyAccessible(field, psiClass) ? field : null;
|
||||
}
|
||||
|
||||
case METHOD: {
|
||||
@@ -85,7 +86,7 @@ public class JavaLangClassMemberReference extends PsiReferenceBase<PsiLiteralExp
|
||||
|
||||
case DECLARED_METHOD: {
|
||||
final PsiMethod[] methods = psiClass.findMethodsByName(name, false);
|
||||
return ContainerUtil.find(methods, method -> isRegularMethod(method) && isReachable(method, psiClass));
|
||||
return ContainerUtil.find(methods, method -> isRegularMethod(method) && isPotentiallyAccessible(method, psiClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,21 +116,30 @@ public class JavaLangClassMemberReference extends PsiReferenceBase<PsiLiteralExp
|
||||
switch (type) {
|
||||
|
||||
case DECLARED_FIELD:
|
||||
return psiClass.getFields();
|
||||
return Arrays.stream(psiClass.getFields())
|
||||
.sorted(Comparator.comparing(PsiField::getName))
|
||||
.map(field -> lookupField(field))
|
||||
.toArray();
|
||||
|
||||
case FIELD:
|
||||
return ContainerUtil.filter(psiClass.getAllFields(), field -> isReachable(field, psiClass)).toArray();
|
||||
return Arrays.stream(psiClass.getAllFields())
|
||||
.filter(field -> isPotentiallyAccessible(field, psiClass))
|
||||
.sorted(Comparator.comparingInt((PsiField field) -> isPublic(field) ? 0 : 1).thenComparing(PsiField::getName))
|
||||
.map(field -> withPriority(lookupField(field), isPublic(field)))
|
||||
.toArray();
|
||||
|
||||
case DECLARED_METHOD:
|
||||
return Arrays.stream(psiClass.getMethods())
|
||||
.filter(method -> isRegularMethod(method))
|
||||
.map(this::lookupMethod)
|
||||
.sorted(Comparator.comparing(PsiMethod::getName))
|
||||
.map(method -> lookupMethod(method))
|
||||
.toArray();
|
||||
|
||||
case METHOD:
|
||||
return Arrays.stream(psiClass.getAllMethods())
|
||||
.filter(method -> isRegularMethod(method) && isReachable(method, psiClass) && !isJavaLangObject(method.getContainingClass()))
|
||||
.map(this::lookupMethod)
|
||||
.filter(method -> isRegularMethod(method) && isPotentiallyAccessible(method, psiClass))
|
||||
.sorted(Comparator.comparingInt((PsiMethod method) -> getMethodSortOrder(method)).thenComparing(PsiMethod::getName))
|
||||
.map(method -> PrioritizedLookupElement.withPriority(lookupMethod(method), -getMethodSortOrder(method)))
|
||||
.toArray();
|
||||
}
|
||||
}
|
||||
@@ -137,8 +147,17 @@ public class JavaLangClassMemberReference extends PsiReferenceBase<PsiLiteralExp
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
private static int getMethodSortOrder(PsiMethod method) {
|
||||
return isJavaLangObject(method.getContainingClass()) ? 1 : isPublic(method) ? -1 : 0;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private LookupElementBuilder lookupMethod(PsiMethod method) {
|
||||
private static LookupElement lookupField(PsiField field) {
|
||||
return JavaLookupElementBuilder.forField(field);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private LookupElement lookupMethod(PsiMethod method) {
|
||||
return JavaLookupElementBuilder.forMethod(method, PsiSubstitutor.EMPTY).withInsertHandler(this);
|
||||
}
|
||||
|
||||
|
||||
+44
-32
@@ -27,11 +27,11 @@ import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static com.intellij.codeInsight.completion.JavaCompletionContributor.isInJavaContext;
|
||||
import static com.intellij.patterns.PsiJavaPatterns.*;
|
||||
@@ -42,18 +42,27 @@ import static com.intellij.psi.impl.source.resolve.reference.impl.JavaReflection
|
||||
* @author Pavel.Dolgov
|
||||
*/
|
||||
public class JavaReflectionCompletionContributor extends CompletionContributor {
|
||||
private static final String CONSTRUCTOR = "getConstructor";
|
||||
private static final String DECLARED_CONSTRUCTOR = "getDeclaredConstructor";
|
||||
private static final String ANNOTATION = "getAnnotation";
|
||||
private static final String DECLARED_ANNOTATION = "getDeclaredAnnotation";
|
||||
private static final String ANNOTATIONS_BY_TYPE = "getAnnotationsByType";
|
||||
private static final String DECLARED_ANNOTATIONS_BY_TYPE = "getDeclaredAnnotationsByType";
|
||||
private static final String ANNOTATED_ELEMENT = "java.lang.reflect.AnnotatedElement";
|
||||
|
||||
private static final Set<String> DECLARED_NAMES =
|
||||
ContainerUtil.immutableSet(DECLARED_CONSTRUCTOR, DECLARED_ANNOTATION, DECLARED_ANNOTATIONS_BY_TYPE);
|
||||
private static final ElementPattern<? extends PsiElement> CONSTRUCTOR_ARGUMENTS = psiElement(PsiExpressionList.class)
|
||||
.withParent(psiExpression().methodCall(
|
||||
psiMethod()
|
||||
.withName("getConstructor", "getDeclaredConstructor")
|
||||
.withName(CONSTRUCTOR, DECLARED_CONSTRUCTOR)
|
||||
.definedInClass(CommonClassNames.JAVA_LANG_CLASS)));
|
||||
|
||||
private static final ElementPattern<? extends PsiElement> ANNOTATION_ARGUMENTS = psiElement(PsiExpressionList.class)
|
||||
.withParent(psiExpression().methodCall(
|
||||
psiMethod()
|
||||
.withName("getAnnotation", "getDeclaredAnnotation", "getAnnotationsByType", "getDeclaredAnnotationsByType")
|
||||
.with(new MethodDefinedInInterfacePatternCondition("java.lang.reflect.AnnotatedElement"))));
|
||||
.withName(ANNOTATION, DECLARED_ANNOTATION, ANNOTATIONS_BY_TYPE, DECLARED_ANNOTATIONS_BY_TYPE)
|
||||
.with(new MethodDefinedInInterfacePatternCondition(ANNOTATED_ELEMENT))));
|
||||
|
||||
private static final ElementPattern<PsiElement> BEGINNING_OF_CONSTRUCTOR_ARGUMENTS = beginningOfArguments(CONSTRUCTOR_ARGUMENTS);
|
||||
|
||||
@@ -79,28 +88,32 @@ public class JavaReflectionCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
if (BEGINNING_OF_ANNOTATION_ARGUMENTS.accepts(position)) {
|
||||
PsiClass psiClass = getQualifierClass(position);
|
||||
if (psiClass != null) {
|
||||
addAnnotationClasses(psiClass, result);
|
||||
}
|
||||
addVariants(position, (psiClass, isDeclared) -> addAnnotationClasses(psiClass, isDeclared, result));
|
||||
//TODO handle annotations on fields and methods
|
||||
}
|
||||
if (BEGINNING_OF_CONSTRUCTOR_ARGUMENTS.accepts(position)) {
|
||||
PsiClass psiClass = getQualifierClass(position);
|
||||
else if (BEGINNING_OF_CONSTRUCTOR_ARGUMENTS.accepts(position)) {
|
||||
addVariants(position, (psiClass, isDeclared) -> addConstructorParameterTypes(psiClass, isDeclared, result));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addVariants(PsiElement position, BiConsumer<PsiClass, Boolean> variantAdder) {
|
||||
PsiMethodCallExpression methodCall = PsiTreeUtil.getParentOfType(position, PsiMethodCallExpression.class);
|
||||
if (methodCall != null) {
|
||||
PsiClass psiClass = getReflectiveClass(methodCall.getMethodExpression().getQualifierExpression());
|
||||
if (psiClass != null) {
|
||||
addConstructorParameterTypes(psiClass, result);
|
||||
String methodName = methodCall.getMethodExpression().getReferenceName();
|
||||
if (methodName != null) {
|
||||
variantAdder.accept(psiClass, DECLARED_NAMES.contains(methodName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass getQualifierClass(@Nullable PsiElement position) {
|
||||
PsiMethodCallExpression methodCall = PsiTreeUtil.getParentOfType(position, PsiMethodCallExpression.class);
|
||||
return methodCall != null ? getReflectiveClass(methodCall.getMethodExpression().getQualifierExpression()) : null;
|
||||
}
|
||||
private static void addAnnotationClasses(@NotNull PsiClass psiClass, boolean isDeclared, @NotNull CompletionResultSet result) {
|
||||
Set<PsiAnnotation> declaredAnnotations =
|
||||
isDeclared ? ContainerUtil.set(AnnotationUtil.getAllAnnotations(psiClass, false, null, false)) : null;
|
||||
|
||||
private static void addAnnotationClasses(@NotNull PsiModifierListOwner annotationsOwner, @NotNull CompletionResultSet result) {
|
||||
PsiAnnotation[] annotations = AnnotationUtil.getAllAnnotations(annotationsOwner, true, null);
|
||||
PsiAnnotation[] annotations = AnnotationUtil.getAllAnnotations(psiClass, true, null, false);
|
||||
for (PsiAnnotation annotation : annotations) {
|
||||
PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement();
|
||||
if (referenceElement != null) {
|
||||
@@ -112,6 +125,9 @@ public class JavaReflectionCompletionContributor extends CompletionContributor {
|
||||
LookupElement lookupElement = LookupElementBuilder.createWithIcon(annotationClass)
|
||||
.withPresentableText(className + ".class")
|
||||
.withInsertHandler(JavaReflectionCompletionContributor::handleAnnotationClassInsertion);
|
||||
if (isDeclared) {
|
||||
lookupElement = withPriority(lookupElement, declaredAnnotations.contains(annotation));
|
||||
}
|
||||
result.addElement(lookupElement);
|
||||
}
|
||||
}
|
||||
@@ -119,26 +135,22 @@ public class JavaReflectionCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
}
|
||||
|
||||
private static void addConstructorParameterTypes(@NotNull PsiClass psiClass, @NotNull CompletionResultSet result) {
|
||||
private static void addConstructorParameterTypes(@NotNull PsiClass psiClass, boolean isDeclared, @NotNull CompletionResultSet result) {
|
||||
PsiMethod[] constructors = psiClass.getConstructors();
|
||||
if (constructors.length != 0) {
|
||||
for (PsiMethod constructor : constructors) {
|
||||
String parameterTypesText = Arrays.stream(constructor.getParameterList().getParameters())
|
||||
.map(p -> p.getType().getCanonicalText())
|
||||
.collect(Collectors.joining(",", constructor.getName() + "(", ")"));
|
||||
|
||||
LookupElement lookupElement = LookupElementBuilder.createWithIcon(constructor)
|
||||
.withPresentableText(parameterTypesText)
|
||||
.withInsertHandler(JavaReflectionCompletionContributor::handleConstructorSignatureInsertion);
|
||||
result.addElement(lookupElement);
|
||||
for (PsiMethod constructor : constructors) {
|
||||
LookupElement lookupElement = JavaLookupElementBuilder.forMethod(constructor, PsiSubstitutor.EMPTY)
|
||||
.withInsertHandler(JavaReflectionCompletionContributor::handleConstructorSignatureInsertion);
|
||||
if (isDeclared) {
|
||||
lookupElement = withPriority(lookupElement, isPublic(constructor));
|
||||
}
|
||||
result.addElement(lookupElement);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleAnnotationClassInsertion(@NotNull InsertionContext context, @NotNull LookupElement item) {
|
||||
Object object = item.getObject();
|
||||
if (object instanceof PsiClass) {
|
||||
String className = ((PsiClass)object).getName();
|
||||
String className = ((PsiClass)object).getQualifiedName();
|
||||
if (className != null) {
|
||||
handleParametersInsertion(context, className + ".class");
|
||||
}
|
||||
|
||||
+8
-1
@@ -16,6 +16,8 @@
|
||||
package com.intellij.psi.impl.source.resolve.reference.impl;
|
||||
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.completion.PrioritizedLookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.RecursionGuard;
|
||||
import com.intellij.openapi.util.RecursionManager;
|
||||
@@ -151,7 +153,7 @@ class JavaReflectionReferenceUtil {
|
||||
* Non-public members of superclass/superinterface can't be obtained via reflection, they need to be filtered out.
|
||||
*/
|
||||
@Contract("null, _ -> false")
|
||||
static boolean isReachable(PsiMember member, PsiClass psiClass) {
|
||||
static boolean isPotentiallyAccessible(PsiMember member, PsiClass psiClass) {
|
||||
return member != null && (member.getContainingClass() == psiClass || isPublic(member));
|
||||
}
|
||||
|
||||
@@ -175,4 +177,9 @@ class JavaReflectionReferenceUtil {
|
||||
JavaCodeStyleManager.getInstance(context.getProject()).shortenClassReferences(methodCall.getArgumentList());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static LookupElement withPriority(LookupElement lookupElement, boolean hasPriority) {
|
||||
return PrioritizedLookupElement.withPriority(lookupElement, hasPriority ? 1 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-8
@@ -62,10 +62,9 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
|
||||
final PsiClass baseClass = parameters.getClassToProcess();
|
||||
assert parameters.isCheckInheritance();
|
||||
|
||||
SearchScope useScope = ReadAction.compute(baseClass::getUseScope);
|
||||
|
||||
final Project project = PsiUtilCore.getProjectInReadAction(baseClass);
|
||||
if (JavaClassInheritorsSearcher.isJavaLangObject(baseClass)) {
|
||||
SearchScope useScope = ReadAction.compute(baseClass::getUseScope);
|
||||
return AllClassesSearch.search(useScope, project).forEach(psiClass -> {
|
||||
ProgressManager.checkCanceled();
|
||||
if (psiClass.isInterface()) {
|
||||
@@ -76,13 +75,17 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
|
||||
});
|
||||
}
|
||||
|
||||
SearchScope scope = parameters.getScope();
|
||||
|
||||
CompilerDirectHierarchyInfo info = performSearchUsingCompilerIndices(parameters, scope, project);
|
||||
if (info != null) {
|
||||
SearchScope scope;
|
||||
SearchScope useScope;
|
||||
CompilerDirectHierarchyInfo info = performSearchUsingCompilerIndices(parameters, parameters.getScope(), project);
|
||||
if (info == null) {
|
||||
scope = parameters.getScope();
|
||||
useScope = ReadAction.compute(baseClass::getUseScope);
|
||||
}
|
||||
else {
|
||||
if (!processInheritorCandidates(info.getHierarchyChildren(), consumer, parameters.includeAnonymous())) return false;
|
||||
scope = scope.intersectWith(info.getDirtyScope());
|
||||
useScope = useScope.intersectWith(info.getDirtyScope());
|
||||
scope = ReadAction.compute(() -> parameters.getScope().intersectWith(info.getDirtyScope()));
|
||||
useScope = ReadAction.compute(() -> baseClass.getUseScope().intersectWith(info.getDirtyScope()));
|
||||
}
|
||||
|
||||
PsiClass[] cache = getOrCalculateDirectSubClasses(project, baseClass, useScope);
|
||||
|
||||
@@ -35,13 +35,14 @@ public interface PsiModifier {
|
||||
String VOLATILE = "volatile";
|
||||
String DEFAULT = "default";
|
||||
String OPEN = "open";
|
||||
String TRANSITIVE = "transitive";
|
||||
|
||||
String[] MODIFIERS = {
|
||||
PUBLIC, PROTECTED, PRIVATE, STATIC, ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, STRICTFP, TRANSIENT, VOLATILE, DEFAULT, OPEN
|
||||
PUBLIC, PROTECTED, PRIVATE, STATIC, ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, STRICTFP, TRANSIENT, VOLATILE, DEFAULT, OPEN, TRANSITIVE
|
||||
};
|
||||
|
||||
@MagicConstant(stringValues = {
|
||||
PUBLIC, PROTECTED, PRIVATE, STATIC, ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, STRICTFP, TRANSIENT, VOLATILE, DEFAULT, OPEN, PACKAGE_LOCAL
|
||||
PUBLIC, PROTECTED, PRIVATE, STATIC, ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, STRICTFP, TRANSIENT, VOLATILE, DEFAULT, OPEN, TRANSITIVE, PACKAGE_LOCAL
|
||||
})
|
||||
@interface ModifierConstant { }
|
||||
}
|
||||
@@ -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.
|
||||
@@ -22,7 +22,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
*
|
||||
* @since 2016.3
|
||||
*/
|
||||
public interface PsiRequiresStatement extends PsiElement {
|
||||
public interface PsiRequiresStatement extends PsiModifierListOwner {
|
||||
PsiRequiresStatement[] EMPTY_ARRAY = new PsiRequiresStatement[0];
|
||||
|
||||
@Nullable PsiJavaModuleReferenceElement getReferenceElement();
|
||||
|
||||
@@ -42,6 +42,7 @@ public final class ModifierFlags {
|
||||
public static final int STRICTFP_MASK = 0x0800;
|
||||
public static final int PACKAGE_LOCAL_MASK = 0x1000;
|
||||
public static final int OPEN_MASK = 0x2000;
|
||||
public static final int TRANSITIVE_MASK = 0x4000;
|
||||
|
||||
public static final TObjectIntHashMap<String> NAME_TO_MODIFIER_FLAG_MAP = new TObjectIntHashMap<String>();
|
||||
public static final TIntObjectHashMap<String> MODIFIER_FLAG_TO_NAME_MAP = new TIntObjectHashMap<String>();
|
||||
@@ -61,6 +62,7 @@ public final class ModifierFlags {
|
||||
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.STRICTFP, STRICTFP_MASK);
|
||||
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.PACKAGE_LOCAL, PACKAGE_LOCAL_MASK);
|
||||
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.OPEN, OPEN_MASK);
|
||||
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.TRANSITIVE, TRANSITIVE_MASK);
|
||||
|
||||
for (Object name : NAME_TO_MODIFIER_FLAG_MAP.keys()) {
|
||||
MODIFIER_FLAG_TO_NAME_MAP.put(NAME_TO_MODIFIER_FLAG_MAP.get((String)name), (String)name);
|
||||
@@ -79,6 +81,7 @@ public final class ModifierFlags {
|
||||
KEYWORD_TO_MODIFIER_FLAG_MAP.put(JavaTokenType.ABSTRACT_KEYWORD, ABSTRACT_MASK);
|
||||
KEYWORD_TO_MODIFIER_FLAG_MAP.put(JavaTokenType.STRICTFP_KEYWORD, STRICTFP_MASK);
|
||||
KEYWORD_TO_MODIFIER_FLAG_MAP.put(JavaTokenType.OPEN_KEYWORD, OPEN_MASK);
|
||||
KEYWORD_TO_MODIFIER_FLAG_MAP.put(JavaTokenType.TRANSITIVE_KEYWORD, TRANSITIVE_MASK);
|
||||
}
|
||||
|
||||
public static boolean hasModifierProperty(String name, int mask) {
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Collections;
|
||||
|
||||
import static com.intellij.util.containers.ContainerUtil.newArrayList;
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
public class ClsJavaModuleImpl extends ClsRepositoryPsiElement<PsiJavaModuleStub> implements PsiJavaModule {
|
||||
private PsiJavaModuleReferenceElement myReference;
|
||||
@@ -93,16 +94,16 @@ public class ClsJavaModuleImpl extends ClsRepositoryPsiElement<PsiJavaModuleStub
|
||||
|
||||
@Override
|
||||
public void setMirror(@NotNull TreeElement element) throws InvalidMirrorException {
|
||||
setMirrorCheckingType(element, JavaElementType.MODULE);
|
||||
|
||||
PsiJavaModule mirror = SourceTreeToPsiMap.treeToPsiNotNull(element);
|
||||
|
||||
setMirrorCheckingType(element, JavaElementType.MODULE);
|
||||
setMirror(getNameIdentifier(), mirror.getNameIdentifier());
|
||||
setMirror(getModifierList(), mirror.getModifierList());
|
||||
//setMirror(getModifierList(), mirror.getModifierList());
|
||||
|
||||
setMirrors(newArrayList(getStub().getChildrenByType(JavaElementType.REQUIRES_STATEMENT, PsiRequiresStatement.EMPTY_ARRAY)),
|
||||
setMirrors(asList(getStub().getChildrenByType(JavaElementType.REQUIRES_STATEMENT, PsiRequiresStatement.EMPTY_ARRAY)),
|
||||
newArrayList(mirror.getRequires()));
|
||||
|
||||
setMirrors(newArrayList(getStub().getChildrenByType(JavaElementType.EXPORTS_STATEMENT, PsiPackageAccessibilityStatement.EMPTY_ARRAY)),
|
||||
setMirrors(asList(getStub().getChildrenByType(JavaElementType.EXPORTS_STATEMENT, PsiPackageAccessibilityStatement.EMPTY_ARRAY)),
|
||||
newArrayList(mirror.getExports()));
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -24,12 +24,10 @@ import com.intellij.psi.impl.source.SourceTreeToPsiMap;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.impl.source.tree.TreeElement;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@SuppressWarnings("ForLoopReplaceableByForEach")
|
||||
public class ClsModifierListImpl extends ClsRepositoryPsiElement<PsiModifierListStub> implements PsiModifierList {
|
||||
public ClsModifierListImpl(final PsiModifierListStub stub) {
|
||||
public ClsModifierListImpl(PsiModifierListStub stub) {
|
||||
super(stub);
|
||||
}
|
||||
|
||||
@@ -78,29 +76,29 @@ public class ClsModifierListImpl extends ClsRepositoryPsiElement<PsiModifierList
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiAnnotation addAnnotation(@NotNull @NonNls String qualifiedName) {
|
||||
public PsiAnnotation addAnnotation(@NotNull String qualifiedName) {
|
||||
throw cannotModifyException(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendMirrorText(int indentLevel, @NotNull StringBuilder buffer) {
|
||||
final PsiElement parent = getParent();
|
||||
final PsiAnnotation[] annotations = getAnnotations();
|
||||
final boolean separateAnnotations = parent instanceof PsiClass || parent instanceof PsiMethod || parent instanceof PsiField;
|
||||
PsiElement parent = getParent();
|
||||
PsiAnnotation[] annotations = getAnnotations();
|
||||
boolean separateAnnotations = parent instanceof PsiClass || parent instanceof PsiMethod || parent instanceof PsiField;
|
||||
|
||||
for (int i = 0; i < annotations.length; i++) {
|
||||
appendText(annotations[i], indentLevel, buffer, separateAnnotations ? NEXT_LINE : " ");
|
||||
for (PsiAnnotation annotation : annotations) {
|
||||
appendText(annotation, indentLevel, buffer, separateAnnotations ? NEXT_LINE : " ");
|
||||
}
|
||||
|
||||
final boolean isClass = parent instanceof PsiClass;
|
||||
final boolean isInterface = isClass && ((PsiClass)parent).isInterface();
|
||||
final boolean isEnum = isClass && ((PsiClass)parent).isEnum();
|
||||
final boolean isInterfaceClass = isClass && parent.getParent() instanceof PsiClass && ((PsiClass)parent.getParent()).isInterface();
|
||||
final boolean isMethod = parent instanceof PsiMethod;
|
||||
final boolean isInterfaceMethod = isMethod && parent.getParent() instanceof PsiClass && ((PsiClass)parent.getParent()).isInterface();
|
||||
final boolean isField = parent instanceof PsiField;
|
||||
final boolean isInterfaceField = isField && parent.getParent() instanceof PsiClass && ((PsiClass)parent.getParent()).isInterface();
|
||||
final boolean isEnumConstant = parent instanceof PsiEnumConstant;
|
||||
boolean isClass = parent instanceof PsiClass;
|
||||
boolean isInterface = isClass && ((PsiClass)parent).isInterface();
|
||||
boolean isEnum = isClass && ((PsiClass)parent).isEnum();
|
||||
boolean isInterfaceClass = isClass && parent.getParent() instanceof PsiClass && ((PsiClass)parent.getParent()).isInterface();
|
||||
boolean isMethod = parent instanceof PsiMethod;
|
||||
boolean isInterfaceMethod = isMethod && parent.getParent() instanceof PsiClass && ((PsiClass)parent.getParent()).isInterface();
|
||||
boolean isField = parent instanceof PsiField;
|
||||
boolean isInterfaceField = isField && parent.getParent() instanceof PsiClass && ((PsiClass)parent.getParent()).isInterface();
|
||||
boolean isEnumConstant = parent instanceof PsiEnumConstant;
|
||||
|
||||
if (hasModifierProperty(PsiModifier.PUBLIC) && !isInterfaceMethod && !isInterfaceField && !isInterfaceClass && !isEnumConstant) {
|
||||
buffer.append(PsiModifier.PUBLIC).append(' ');
|
||||
@@ -160,4 +158,4 @@ public class ClsModifierListImpl extends ClsRepositoryPsiElement<PsiModifierList
|
||||
public String toString() {
|
||||
return "PsiModifierList";
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
-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.
|
||||
@@ -19,10 +19,14 @@ import com.intellij.openapi.util.AtomicNotNullLazyValue;
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiJavaModuleReferenceElement;
|
||||
import com.intellij.psi.PsiModifierList;
|
||||
import com.intellij.psi.PsiRequiresStatement;
|
||||
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
|
||||
import com.intellij.psi.impl.java.stubs.PsiRequiresStatementStub;
|
||||
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.impl.source.tree.TreeElement;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -70,6 +74,19 @@ public class ClsRequiresStatementImpl extends ClsRepositoryPsiElement<PsiRequire
|
||||
@Override
|
||||
public void setMirror(@NotNull TreeElement element) throws InvalidMirrorException {
|
||||
setMirrorCheckingType(element, JavaElementType.REQUIRES_STATEMENT);
|
||||
//setMirror(getModifierList(), SourceTreeToPsiMap.<PsiRequiresStatement>treeToPsiNotNull(element).getModifierList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiModifierList getModifierList() {
|
||||
StubElement<PsiModifierList> childStub = getStub().findChildStubByType(JavaStubElementTypes.MODIFIER_LIST);
|
||||
return childStub != null ? childStub.getPsi() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasModifierProperty(@NotNull String name) {
|
||||
PsiModifierList modifierList = getModifierList();
|
||||
return modifierList != null && modifierList.hasModifierProperty(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.intellij.psi.impl.java.stubs;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.compiled.*;
|
||||
|
||||
/*
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class ClsStubPsiFactory extends StubPsiFactory {
|
||||
|
||||
@@ -13,16 +13,15 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author max
|
||||
*/
|
||||
package com.intellij.psi.impl.java.stubs;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.*;
|
||||
import com.intellij.psi.impl.source.tree.java.*;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class SourceStubPsiFactory extends StubPsiFactory {
|
||||
public static final SourceStubPsiFactory INSTANCE = new SourceStubPsiFactory();
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ package com.intellij.psi.impl.java.stubs;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
|
||||
/*
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public abstract class StubPsiFactory {
|
||||
|
||||
@@ -61,6 +61,7 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
|
||||
NAME_TO_KEYWORD_TYPE_MAP.put(VOLATILE, JavaTokenType.VOLATILE_KEYWORD);
|
||||
NAME_TO_KEYWORD_TYPE_MAP.put(DEFAULT, JavaTokenType.DEFAULT_KEYWORD);
|
||||
NAME_TO_KEYWORD_TYPE_MAP.put(OPEN, JavaTokenType.OPEN_KEYWORD);
|
||||
NAME_TO_KEYWORD_TYPE_MAP.put(TRANSITIVE, JavaTokenType.TRANSITIVE_KEYWORD);
|
||||
|
||||
KEYWORD_TYPE_TO_NAME_MAP = ContainerUtil.newTroveMap();
|
||||
for (String name : NAME_TO_KEYWORD_TYPE_MAP.keySet()) {
|
||||
|
||||
@@ -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.
|
||||
@@ -67,6 +67,17 @@ public class PsiRequiresStatementImpl extends JavaStubPsiElement<PsiRequiresStat
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiModifierList getModifierList() {
|
||||
return getStubOrPsiChild(JavaStubElementTypes.MODIFIER_LIST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasModifierProperty(@NotNull String name) {
|
||||
PsiModifierList modifierList = getModifierList();
|
||||
return modifierList != null && modifierList.hasModifierProperty(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
|
||||
@@ -35,7 +35,8 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen
|
||||
PRIVATE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD, RETURN_KEYWORD, SHORT_KEYWORD, SUPER_KEYWORD, STATIC_KEYWORD, STRICTFP_KEYWORD,
|
||||
SWITCH_KEYWORD, SYNCHRONIZED_KEYWORD, THIS_KEYWORD, THROW_KEYWORD, THROWS_KEYWORD, TRANSIENT_KEYWORD, TRY_KEYWORD, VOID_KEYWORD,
|
||||
VOLATILE_KEYWORD, WHILE_KEYWORD,
|
||||
OPEN_KEYWORD, MODULE_KEYWORD, REQUIRES_KEYWORD, EXPORTS_KEYWORD, OPENS_KEYWORD, USES_KEYWORD, PROVIDES_KEYWORD, TO_KEYWORD, WITH_KEYWORD);
|
||||
OPEN_KEYWORD, MODULE_KEYWORD, REQUIRES_KEYWORD, EXPORTS_KEYWORD, OPENS_KEYWORD, USES_KEYWORD, PROVIDES_KEYWORD,
|
||||
TRANSITIVE_KEYWORD, TO_KEYWORD, WITH_KEYWORD);
|
||||
|
||||
TokenSet LITERAL_BIT_SET = TokenSet.create(TRUE_KEYWORD, FALSE_KEYWORD, NULL_KEYWORD);
|
||||
|
||||
@@ -70,7 +71,8 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen
|
||||
WHILE_STATEMENT, FOR_STATEMENT, FOREACH_STATEMENT, DO_WHILE_STATEMENT, SWITCH_STATEMENT, SWITCH_LABEL_STATEMENT, BREAK_STATEMENT,
|
||||
CONTINUE_STATEMENT, RETURN_STATEMENT, THROW_STATEMENT, SYNCHRONIZED_STATEMENT, TRY_STATEMENT, LABELED_STATEMENT, ASSERT_STATEMENT);
|
||||
|
||||
TokenSet JAVA_MODULE_STATEMENT_BIT_SET = TokenSet.create(REQUIRES_STATEMENT, EXPORTS_STATEMENT, OPENS_STATEMENT, USES_STATEMENT, PROVIDES_STATEMENT);
|
||||
TokenSet JAVA_MODULE_STATEMENT_BIT_SET = TokenSet.create(
|
||||
REQUIRES_STATEMENT, EXPORTS_STATEMENT, OPENS_STATEMENT, USES_STATEMENT, PROVIDES_STATEMENT);
|
||||
|
||||
TokenSet IMPORT_STATEMENT_BASE_BIT_SET = TokenSet.create(IMPORT_STATEMENT, IMPORT_STATIC_STATEMENT);
|
||||
TokenSet CLASS_KEYWORD_BIT_SET = TokenSet.create(CLASS_KEYWORD, INTERFACE_KEYWORD, ENUM_KEYWORD);
|
||||
|
||||
@@ -22,5 +22,5 @@ class DeclaredField {
|
||||
class Test {
|
||||
public int num;
|
||||
public int num2;
|
||||
int num3;
|
||||
int num1;
|
||||
}
|
||||
@@ -22,5 +22,5 @@ class DeclaredField {
|
||||
class Test {
|
||||
public int num;
|
||||
public int num2;
|
||||
int num3;
|
||||
int num1;
|
||||
}
|
||||
@@ -22,7 +22,7 @@ class DecalredMethod {
|
||||
class Test {
|
||||
public void method(){}
|
||||
public void method2(A a, B b){}
|
||||
public void method3(){}
|
||||
void method1(){}
|
||||
}
|
||||
|
||||
class A {}
|
||||
|
||||
@@ -22,7 +22,7 @@ class DecalredMethod2 {
|
||||
class Test {
|
||||
void method(){}
|
||||
void method2(A a, B b){}
|
||||
void method3(){}
|
||||
void method1(){}
|
||||
}
|
||||
|
||||
class A {}
|
||||
|
||||
+2
-2
@@ -15,14 +15,14 @@
|
||||
*/
|
||||
class DecalredMethod2 {
|
||||
void foo() {
|
||||
Test.class.getDeclaredMethod("method3");
|
||||
Test.class.getDeclaredMethod("method1");
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
void method(){}
|
||||
void method2(A a, B b){}
|
||||
void method3(){}
|
||||
void method1(){}
|
||||
}
|
||||
|
||||
class A {}
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ class DecalredMethod {
|
||||
class Test {
|
||||
public void method(){}
|
||||
public void method2(A a, B b){}
|
||||
public void method3(){}
|
||||
void method1(){}
|
||||
}
|
||||
|
||||
class A {}
|
||||
|
||||
+1
-1
@@ -22,5 +22,5 @@ class ForNameDeclaredField {
|
||||
class Test {
|
||||
public int num;
|
||||
public int num2;
|
||||
int num3;
|
||||
int num1;
|
||||
}
|
||||
+2
-2
@@ -15,12 +15,12 @@
|
||||
*/
|
||||
class ForNameDeclaredField {
|
||||
void foo() {
|
||||
Class.forName("Test").getDeclaredField("num3");
|
||||
Class.forName("Test").getDeclaredField("num1");
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
public int num;
|
||||
public int num2;
|
||||
int num3;
|
||||
int num1;
|
||||
}
|
||||
+1
-1
@@ -22,7 +22,7 @@ class ForNameDeclaredMethod {
|
||||
class Test {
|
||||
public void method(){}
|
||||
public void method2(A a, B b){}
|
||||
void method3(){}
|
||||
void method1(){}
|
||||
}
|
||||
|
||||
class A {}
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ class ForNameDeclaredMethod {
|
||||
class Test {
|
||||
public void method(){}
|
||||
public void method2(A a, B b){}
|
||||
void method3(){}
|
||||
void method1(){}
|
||||
}
|
||||
|
||||
class A {}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
class HasConstructor {
|
||||
void foo() {
|
||||
Test.class.getMethod("<caret>");
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
public Test() {}
|
||||
Test(int n) {}
|
||||
public void method(){}
|
||||
public void method2(A a, B b){}
|
||||
void method1(){}
|
||||
}
|
||||
|
||||
class A {}
|
||||
class B {}
|
||||
class C {}
|
||||
@@ -0,0 +1,17 @@
|
||||
class HasConstructor {
|
||||
void foo() {
|
||||
Test.class.getMethod("method1");
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
public Test() {}
|
||||
Test(int n) {}
|
||||
public void method(){}
|
||||
public void method2(A a, B b){}
|
||||
void method1(){}
|
||||
}
|
||||
|
||||
class A {}
|
||||
class B {}
|
||||
class C {}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class Main {
|
||||
void foo() {
|
||||
Test.class.getMethod("<caret>");
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
public void method(){}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class Main {
|
||||
void foo() {
|
||||
Test.class.getMethod("notifyAll");
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
public void method(){}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class Main {
|
||||
void foo() {
|
||||
Object.class.getMethod("<caret>");
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class Main {
|
||||
void foo() {
|
||||
Object.class.getMethod("wait", long.class);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Main {
|
||||
void foo() {
|
||||
Test.class.getMethod("<caret>");
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
public Test() {}
|
||||
Test(int n) {}
|
||||
public void method(){}
|
||||
void method(A a, B b){}
|
||||
public void method(C c){}
|
||||
}
|
||||
|
||||
class A {}
|
||||
class B {}
|
||||
class C {}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Main {
|
||||
void foo() {
|
||||
Test.class.getMethod("method", A.class, B.class);
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
public Test() {}
|
||||
Test(int n) {}
|
||||
public void method(){}
|
||||
void method(A a, B b){}
|
||||
public void method(C c){}
|
||||
}
|
||||
|
||||
class A {}
|
||||
class B {}
|
||||
class C {}
|
||||
@@ -1,7 +1,6 @@
|
||||
import foo.bar.*;
|
||||
class Main {
|
||||
void foo() throws ReflectiveOperationException {
|
||||
Class<Annotation> aType = Baz.class;
|
||||
Test.class.getAnnotation(<caret>);
|
||||
}
|
||||
}
|
||||
-1
@@ -1,7 +1,6 @@
|
||||
import foo.bar.*;
|
||||
class Main {
|
||||
void foo() throws ReflectiveOperationException {
|
||||
Class<Annotation> aType = Baz.class;
|
||||
Test.class.getAnnotation(Bar.class);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import foo.bar.*;
|
||||
class Main {
|
||||
void foo() throws ReflectiveOperationException {
|
||||
Test.class.getDeclaredAnnotation(Bar.class);
|
||||
Test.class.getDeclaredAnnotation(Foo.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import foo.bar.*;
|
||||
class Main {
|
||||
void foo() throws ReflectiveOperationException {
|
||||
More.class.getAnnotation(<caret>);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import foo.bar.*;
|
||||
import foo.baz.Baz;
|
||||
|
||||
class Main {
|
||||
void foo() throws ReflectiveOperationException {
|
||||
More.class.getAnnotation(Baz.class);
|
||||
}
|
||||
}
|
||||
-1
@@ -1,7 +1,6 @@
|
||||
import foo.bar.*;
|
||||
class Main {
|
||||
void foo() throws ReflectiveOperationException {
|
||||
Class<Annotation> aType = Baz.class;
|
||||
Test.class.getAnnotation(<caret>);
|
||||
}
|
||||
}
|
||||
-1
@@ -1,7 +1,6 @@
|
||||
import foo.bar.*;
|
||||
class Main {
|
||||
void foo() throws ReflectiveOperationException {
|
||||
Class<Annotation> aType = Baz.class;
|
||||
Test.class.getAnnotation(Foo.class);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import foo.bar.*;
|
||||
class Main {
|
||||
void foo() throws ReflectiveOperationException {
|
||||
Test.class.getDeclaredAnnotation(Foo.class);
|
||||
Test.class.getDeclaredAnnotation(Bar.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import foo.bar.*;
|
||||
import foo.baz.Baz;
|
||||
class Main {
|
||||
void foo() throws ReflectiveOperationException {
|
||||
Class<Annotation> aType = Baz.class;
|
||||
Test.class.getAnnotation(<caret>);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import foo.bar.*;
|
||||
import foo.baz.Baz;
|
||||
class Main {
|
||||
void foo() throws ReflectiveOperationException {
|
||||
Class<Annotation> aType = Baz.class;
|
||||
Test.class.getAnnotation(aType);
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
// "Fix all 'Loop can be collapsed with Stream API' problems in file" "true"
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Test {
|
||||
void testList(List<String> input) {
|
||||
List<String> result = input.stream().filter(s -> !s.isEmpty()).collect(Collectors.toCollection(() -> new ArrayList<>(10)));
|
||||
System.out.println(result);
|
||||
|
||||
ArrayList<String> result2 = input.stream().filter(s -> !s.isEmpty()).collect(Collectors.toCollection(() -> new ArrayList<>(20)));
|
||||
System.out.println(result2);
|
||||
|
||||
// Non-empty
|
||||
ArrayList<String> result3 = new ArrayList<>(input);
|
||||
input.stream().filter(s -> !s.isEmpty()).forEach(result3::add);
|
||||
System.out.println(result3);
|
||||
}
|
||||
|
||||
void testSet(List<String> input) {
|
||||
Set<String> result = input.stream().filter(s -> !s.isEmpty()).collect(Collectors.toCollection(() -> new HashSet<>(10)));
|
||||
System.out.println(result);
|
||||
|
||||
Collection<String> result2 = input.stream().filter(s -> !s.isEmpty()).collect(Collectors.toCollection(() -> new LinkedHashSet<>(20, 0.8f)));
|
||||
System.out.println(result2);
|
||||
|
||||
// Non-empty
|
||||
AbstractSet<String> result3 = new HashSet<>(input);
|
||||
input.stream().filter(s -> !s.isEmpty()).forEach(result3::add);
|
||||
System.out.println(result3);
|
||||
|
||||
Collection<TimeUnit> result4 = input.stream().filter(s -> !s.isEmpty()).map(TimeUnit::valueOf).collect(Collectors.toCollection(() -> EnumSet.noneOf(TimeUnit.class)));
|
||||
System.out.println(result4);
|
||||
}
|
||||
|
||||
void testMap(List<String> input) {
|
||||
Map<Integer, String> result = input.stream().filter(s -> !s.isEmpty()).collect(Collectors.toMap(String::length, s -> s, (a, b) -> b, () -> new HashMap<>(10)));
|
||||
System.out.println(result);
|
||||
|
||||
Map<Integer, String> result2 = input.stream().filter(s -> !s.isEmpty()).collect(Collectors.toMap(String::length, s -> s, (a, b) -> b, () -> new HashMap<>(10, 0.8f)));
|
||||
System.out.println(result2);
|
||||
|
||||
EnumMap<TimeUnit, String> result3 = input.stream().filter(s -> !s.isEmpty()).collect(Collectors.toMap(TimeUnit::valueOf, s -> s, (a, b) -> b, () -> new EnumMap<>(TimeUnit.class)));
|
||||
System.out.println(result3);
|
||||
|
||||
// Non-empty
|
||||
EnumMap<TimeUnit, String> result4 = new EnumMap<>(result3);
|
||||
input.stream().filter(s -> !s.isEmpty()).forEach(s -> result4.put(TimeUnit.valueOf(s), s));
|
||||
System.out.println(result4);
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Replace with collect" "true"
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Test {
|
||||
public List<String> test(String[] data) {
|
||||
int top = Math.min(10, data.length);
|
||||
List<String> result = Arrays.stream(data).limit(10).map(String::trim).filter(item -> !item.isEmpty()).collect(Collectors.toList());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
// "Fix all 'Loop can be collapsed with Stream API' problems in file" "true"
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class Test {
|
||||
void testList(List<String> input) {
|
||||
List<String> result = new ArrayList<>(10);
|
||||
for (String s : in<caret>put) {
|
||||
if (!s.isEmpty()) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
System.out.println(result);
|
||||
|
||||
ArrayList<String> result2 = new ArrayList<>(20);
|
||||
for (String s : input) {
|
||||
if (!s.isEmpty()) {
|
||||
result2.add(s);
|
||||
}
|
||||
}
|
||||
System.out.println(result2);
|
||||
|
||||
// Non-empty
|
||||
ArrayList<String> result3 = new ArrayList<>(input);
|
||||
for (String s : input) {
|
||||
if (!s.isEmpty()) {
|
||||
result3.add(s);
|
||||
}
|
||||
}
|
||||
System.out.println(result3);
|
||||
}
|
||||
|
||||
void testSet(List<String> input) {
|
||||
Set<String> result = new HashSet<>(10);
|
||||
for (String s : input) {
|
||||
if (!s.isEmpty()) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
System.out.println(result);
|
||||
|
||||
Collection<String> result2 = new LinkedHashSet<>(20, 0.8f);
|
||||
for (String s : input) {
|
||||
if (!s.isEmpty()) {
|
||||
result2.add(s);
|
||||
}
|
||||
}
|
||||
System.out.println(result2);
|
||||
|
||||
// Non-empty
|
||||
AbstractSet<String> result3 = new HashSet<>(input);
|
||||
for (String s : input) {
|
||||
if (!s.isEmpty()) {
|
||||
result3.add(s);
|
||||
}
|
||||
}
|
||||
System.out.println(result3);
|
||||
|
||||
Collection<TimeUnit> result4 = EnumSet.noneOf(TimeUnit.class);
|
||||
for (String s : input) {
|
||||
if (!s.isEmpty()) {
|
||||
result4.add(TimeUnit.valueOf(s));
|
||||
}
|
||||
}
|
||||
System.out.println(result4);
|
||||
}
|
||||
|
||||
void testMap(List<String> input) {
|
||||
Map<Integer, String> result = new HashMap<>(10);
|
||||
for (String s : input) {
|
||||
if (!s.isEmpty()) {
|
||||
result.put(s.length(), s);
|
||||
}
|
||||
}
|
||||
System.out.println(result);
|
||||
|
||||
Map<Integer, String> result2 = new HashMap<>(10, 0.8f);
|
||||
for (String s : input) {
|
||||
if (!s.isEmpty()) {
|
||||
result2.put(s.length(), s);
|
||||
}
|
||||
}
|
||||
System.out.println(result2);
|
||||
|
||||
EnumMap<TimeUnit, String> result3 = new EnumMap<>(TimeUnit.class);
|
||||
for (String s : input) {
|
||||
if (!s.isEmpty()) {
|
||||
result3.put(TimeUnit.valueOf(s), s);
|
||||
}
|
||||
}
|
||||
System.out.println(result3);
|
||||
|
||||
// Non-empty
|
||||
EnumMap<TimeUnit, String> result4 = new EnumMap<>(result3);
|
||||
for (String s : input) {
|
||||
if (!s.isEmpty()) {
|
||||
result4.put(TimeUnit.valueOf(s), s);
|
||||
}
|
||||
}
|
||||
System.out.println(result4);
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Replace with collect" "true"
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Test {
|
||||
public List<String> test(String[] data) {
|
||||
int top = Math.min(10, data.length);
|
||||
List<String> result = new ArrayList<>();
|
||||
for(int<caret> i=0; i<top; i++) {
|
||||
String item = data[i].trim();
|
||||
if(!item.isEmpty()) {
|
||||
result.add(item);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>31</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const1.X, Const2.I</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>32</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const1.X, Const2.I</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>33</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const1.X, Const2.I</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>44</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const2.I, Const1.X</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>45</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const2.I, Const1.X</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>46</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const2.I, Const1.X</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>57</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const1.X, Const2.I or their combination</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>58</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const1.X, Const2.I or their combination</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>59</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const1.X, Const2.I</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>61</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const1.X, Const2.I or their combination</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>72</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const2.I, Const1.X or their combination</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>73</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const2.I, Const1.X or their combination</description>
|
||||
</problem>
|
||||
|
||||
</problems>
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
*/
|
||||
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
|
||||
class Const1 {
|
||||
public static final int X = 1;
|
||||
}
|
||||
|
||||
class Const2 {
|
||||
public static final int I = 4;
|
||||
}
|
||||
|
||||
public class X {
|
||||
|
||||
void f(@MagicConstant(intValues = {Const1.X, Const2.I}) int x) {
|
||||
/////////// BAD
|
||||
f(0);
|
||||
f(1);
|
||||
f(Const1.X | Const2.I);
|
||||
|
||||
////////////// GOOD
|
||||
f(Const1.X);
|
||||
f(Const2.I);
|
||||
|
||||
f2(x);
|
||||
}
|
||||
|
||||
void f2(@MagicConstant(valuesFromClass = Const1.class, intValues = {Const2.I}) int x) {
|
||||
/////////// BAD
|
||||
f2(0);
|
||||
f2(1);
|
||||
f2(Const1.X | Const2.I);
|
||||
|
||||
////////////// GOOD
|
||||
f2(Const1.X);
|
||||
f2(Const2.I);
|
||||
|
||||
f(x);
|
||||
}
|
||||
|
||||
void f3(@MagicConstant(flags = {Const1.X, Const2.I}) int x) {
|
||||
/////////// BAD
|
||||
f3(2);
|
||||
f3(1);
|
||||
f(Const1.X | Const2.I);
|
||||
int i = Const1.X | 4;
|
||||
f3(i);
|
||||
|
||||
////////////// GOOD
|
||||
f3(Const1.X);
|
||||
f3(Const2.I);
|
||||
|
||||
f4(x);
|
||||
}
|
||||
|
||||
void f4(@MagicConstant(flagsFromClass = Const1.class, flags = {Const2.I}) int x) {
|
||||
/////////// BAD
|
||||
f4(-3);
|
||||
f4(1);
|
||||
|
||||
////////////// GOOD
|
||||
f4(Const1.X);
|
||||
f4(Const2.I);
|
||||
f4(Const1.X | Const2.I);
|
||||
|
||||
f3(x);
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.codeInsight.completion
|
||||
|
||||
import com.intellij.JavaTestUtil
|
||||
|
||||
/**
|
||||
* @author Pavel.Dolgov
|
||||
*/
|
||||
class JavaReflectionCompletionOverloadTest : LightFixtureCompletionTestCase() {
|
||||
|
||||
override fun getBasePath() = JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/completion/reflectionOverload/"
|
||||
|
||||
fun testOverloadMethods() = doTest(2, "method()", "method(C c)", "method(A a,B b)")
|
||||
|
||||
fun testJavaLangObjectMethods() = doTest(6,
|
||||
"method()",
|
||||
"equals(java.lang.Object obj)", "hashCode()", "toString()",
|
||||
"getClass()", "notify()", "notifyAll()",
|
||||
"wait()", "wait(long timeout)", "wait(long timeout,int nanos)"
|
||||
)
|
||||
|
||||
fun testJavaLangObjectOwnMethods() = doTest(9,
|
||||
"clone()", "equals(java.lang.Object obj)", "hashCode()",
|
||||
"toString()", "finalize()", "getClass()",
|
||||
"notify()", "notifyAll()",
|
||||
"wait()", "wait(long timeout)", "wait(long timeout,int nanos)",
|
||||
"registerNatives()")
|
||||
|
||||
|
||||
private fun doTest(index: Int, vararg expected: String) {
|
||||
configureByFile(getTestName(false) + ".java")
|
||||
|
||||
val lookupItems = lookup.items
|
||||
val texts = lookupItemTexts(lookupItems, expected.size)
|
||||
assertOrderedEquals(texts, *expected)
|
||||
if (index >= 0) selectItem(lookupItems[index])
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java")
|
||||
}
|
||||
}
|
||||
+12
-7
@@ -34,15 +34,15 @@ public class JavaReflectionCompletionTest extends LightFixtureCompletionTestCase
|
||||
}
|
||||
|
||||
public void testDeclaredField() throws Exception {
|
||||
doTest(1, "num", "num2", "num3");
|
||||
doTest(2, "num", "num1", "num2");
|
||||
}
|
||||
|
||||
public void testDeclaredMethod() throws Exception {
|
||||
doTest(1, "method", "method2", "method3");
|
||||
doTest(2, "method", "method1", "method2");
|
||||
}
|
||||
|
||||
public void testDeclaredMethod2() throws Exception {
|
||||
doTest(2, "method", "method2", "method3");
|
||||
doTest(1, "method", "method1", "method2");
|
||||
}
|
||||
|
||||
public void testMethod() throws Exception {
|
||||
@@ -50,7 +50,7 @@ public class JavaReflectionCompletionTest extends LightFixtureCompletionTestCase
|
||||
}
|
||||
|
||||
public void testForNameDeclaredMethod() throws Exception {
|
||||
doTest(1, "method", "method2", "method3");
|
||||
doTest(2, "method", "method1", "method2");
|
||||
}
|
||||
|
||||
public void testForNameMethod() throws Exception {
|
||||
@@ -62,7 +62,7 @@ public class JavaReflectionCompletionTest extends LightFixtureCompletionTestCase
|
||||
}
|
||||
|
||||
public void testForNameDeclaredField() throws Exception {
|
||||
doTest(2, "num", "num2", "num3");
|
||||
doTest(1, "num", "num1", "num2");
|
||||
}
|
||||
|
||||
public void testVarargMethod() throws Exception {
|
||||
@@ -135,7 +135,7 @@ public class JavaReflectionCompletionTest extends LightFixtureCompletionTestCase
|
||||
}
|
||||
|
||||
public void testConstantGetClassField() throws Exception {
|
||||
doTest(1, "num", "num2", "num3");
|
||||
doTest(2, "num", "num3", "num2");
|
||||
}
|
||||
|
||||
public void testExpressionGetClassField() throws Exception {
|
||||
@@ -165,9 +165,14 @@ public class JavaReflectionCompletionTest extends LightFixtureCompletionTestCase
|
||||
doTest(0, "PublicClass");
|
||||
}
|
||||
|
||||
public void testHasConstructor() {
|
||||
doTest(2, "method", "method2", "method1");
|
||||
}
|
||||
|
||||
|
||||
private void doTest(int index, String... expected) {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
assertStringItems(expected);
|
||||
assertFirstStringItems(expected);
|
||||
if (index >= 0) selectItem(getLookup().getItems().get(index));
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java");
|
||||
}
|
||||
|
||||
+43
-15
@@ -31,7 +31,9 @@
|
||||
package com.intellij.codeInsight.completion
|
||||
|
||||
import com.intellij.JavaTestUtil
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
|
||||
/**
|
||||
@@ -42,26 +44,36 @@ class JavaReflectionParametersCompletionTest : LightFixtureCompletionTestCase()
|
||||
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor = com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase.JAVA_8
|
||||
|
||||
fun testAnnotation() = doTest(0, "Bar.class", "Foo.class", "aType")
|
||||
fun testAnnotation() = doTest(0, "Bar.class", "Foo.class")
|
||||
|
||||
fun testInheritedAnnotation() = doTest(1, "Bar.class", "Foo.class", "aType")
|
||||
fun testInheritedAnnotation() = doTest(1, "Bar.class", "Foo.class")
|
||||
|
||||
fun testDeclaredAnnotation() = doTest(0, "Bar.class", "Foo.class")
|
||||
fun testDeclaredAnnotation() = doTest(0, "Foo.class", "Bar.class")
|
||||
|
||||
fun testInheritedDeclaredAnnotation() = doTest(1, "Bar.class", "Foo.class")
|
||||
fun testInheritedDeclaredAnnotation() = doTest(1, "Foo.class", "Bar.class")
|
||||
|
||||
fun testAnnotationsByType() = doTest(0, "Bar.class", "Foo.class")
|
||||
|
||||
fun testDeclaredAnnotationsByType() = doTest(1, "Bar.class", "Foo.class")
|
||||
fun testDeclaredAnnotationsByType() = doTest(0, "Foo.class", "Bar.class")
|
||||
|
||||
fun testConstructor() {
|
||||
addConstructors()
|
||||
doTest(2, "Construct()", "Construct(int)", "Construct(int,java.lang.String)", "Construct(java.lang.String)")
|
||||
doTest(3, "Construct()", "Construct(int n)", "Construct(java.lang.String s)", "Construct(int n,java.lang.String s)")
|
||||
}
|
||||
|
||||
fun testDeclaredConstructor() {
|
||||
addConstructors()
|
||||
doTest(0, "Construct()", "Construct(int)", "Construct(int,java.lang.String)", "Construct(java.lang.String)")
|
||||
doTest(0, "Construct()", "Construct(int n,java.lang.String s)", "Construct(int n)", "Construct(java.lang.String s)")
|
||||
}
|
||||
|
||||
fun testImports() {
|
||||
addMoreClasses()
|
||||
doTest(1, "Bar.class", "Baz.class")
|
||||
}
|
||||
|
||||
fun testVariable() {
|
||||
addMoreClasses()
|
||||
doTest(2, "Bar.class", "Foo.class", "aType")
|
||||
}
|
||||
|
||||
private fun doTest(index: Int, vararg expected: String) {
|
||||
@@ -69,11 +81,7 @@ class JavaReflectionParametersCompletionTest : LightFixtureCompletionTestCase()
|
||||
configureByFile(getTestName(false) + ".java")
|
||||
|
||||
val lookupItems = lookup.items
|
||||
val texts = lookupItems.subList(0, Math.min(lookupItems.size, expected.size)).map {
|
||||
val presentation = LookupElementPresentation()
|
||||
it?.renderElement(presentation)
|
||||
presentation.itemText ?: ""
|
||||
}
|
||||
val texts = lookupItemTexts(lookupItems, expected.size)
|
||||
assertOrderedEquals(texts, *expected)
|
||||
selectItem(lookupItems[index])
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java")
|
||||
@@ -82,9 +90,13 @@ class JavaReflectionParametersCompletionTest : LightFixtureCompletionTestCase()
|
||||
private fun addClasses() {
|
||||
myFixture.addClass("package foo.bar; public @interface Foo {}")
|
||||
myFixture.addClass("package foo.bar; public @interface Bar {}")
|
||||
myFixture.addClass("package foo.bar; public @interface Baz {}")
|
||||
myFixture.addClass("package foo.bar; @Foo class Parent {}")
|
||||
myFixture.addClass("package foo.bar; @Bar class Test extends Parent {}")
|
||||
myFixture.addClass("package foo.bar; @Bar class Parent {}")
|
||||
myFixture.addClass("package foo.bar; @Foo class Test extends Parent {}")
|
||||
}
|
||||
|
||||
private fun addMoreClasses() {
|
||||
myFixture.addClass("package foo.baz; public @interface Baz {}")
|
||||
myFixture.addClass("package foo.bar; @foo.baz.Baz class More extends Parent {}")
|
||||
}
|
||||
|
||||
private fun addConstructors() {
|
||||
@@ -96,4 +108,20 @@ public class Construct {
|
||||
public Construct() {}
|
||||
}""")
|
||||
}
|
||||
|
||||
}
|
||||
fun lookupItemTexts(lookupItems: List<LookupElement?>, maxSize: Int): List<String> =
|
||||
lookupItems.subList(0, Math.min(lookupItems.size, maxSize)).map {
|
||||
val obj = it?.`object`
|
||||
when (obj) {
|
||||
is PsiMethod -> {
|
||||
obj.name + obj.parameterList.parameters.map { it.type.canonicalText + " " + it.name }
|
||||
.joinToString(",", prefix = "(", postfix = ")")
|
||||
}
|
||||
else -> {
|
||||
val presentation = LookupElementPresentation()
|
||||
it?.renderElement(presentation)
|
||||
presentation.itemText ?: ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -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,11 +15,11 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.javadoc
|
||||
|
||||
import com.intellij.openapi.util.JDOMUtil
|
||||
import com.intellij.psi.PsiJavaFile
|
||||
import com.intellij.testFramework.assertions.Assertions.assertThat
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import com.intellij.testFramework.assertions.Assertions.assertThat
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import com.intellij.util.loadElement
|
||||
|
||||
class LightJavadocGeneratorTest : LightCodeInsightFixtureTestCase() {
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor = JAVA_9
|
||||
@@ -45,7 +45,7 @@ class LightJavadocGeneratorTest : LightCodeInsightFixtureTestCase() {
|
||||
val file = myFixture.configureByText("module-info.java", text)
|
||||
val module = (file as PsiJavaFile).moduleDeclaration!!
|
||||
val docInfo = JavaDocInfoGeneratorFactory.create(project, module).generateDocInfo(null)!!
|
||||
val body = JDOMUtil.loadDocument(docInfo).rootElement.getChild("body")
|
||||
val body = loadElement(docInfo).getChild("body")
|
||||
assertThat(body).isEqualTo(expected)
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import com.intellij.psi.codeStyle.CommonCodeStyleSettings
|
||||
import com.intellij.testFramework.LightPlatformCodeInsightTestCase
|
||||
import com.intellij.testFramework.fixtures.CodeInsightTestUtil
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import com.intellij.util.JdomKt
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import org.jdom.Element
|
||||
@@ -658,11 +659,11 @@ class Outer {
|
||||
}
|
||||
|
||||
void testDontSaveDefaultContexts() {
|
||||
def defElement = JDOMUtil.loadDocument('''\
|
||||
def defElement = JdomKt.loadElement('''\
|
||||
<context>
|
||||
<option name="JAVA_STATEMENT" value="false"/>
|
||||
<option name="JAVA_CODE" value="true"/>
|
||||
</context>''').rootElement
|
||||
</context>''')
|
||||
def defContext = new TemplateContext()
|
||||
defContext.readTemplateContext(defElement)
|
||||
|
||||
@@ -695,10 +696,10 @@ class Outer {
|
||||
}
|
||||
|
||||
void "test adding new context to Other"() {
|
||||
def defElement = JDOMUtil.loadDocument('''\
|
||||
def defElement = JdomKt.loadElement('''\
|
||||
<context>
|
||||
<option name="OTHER" value="true"/>
|
||||
</context>''').rootElement
|
||||
</context>''')
|
||||
def context = new TemplateContext()
|
||||
context.readTemplateContext(defElement)
|
||||
|
||||
|
||||
@@ -92,6 +92,8 @@ public class MagicConstantInspectionTest extends InspectionTestCase {
|
||||
}
|
||||
|
||||
public void testSimple() throws Exception { doTest(); }
|
||||
|
||||
public void testManyConstantSources() throws Exception { doTest(); }
|
||||
// test that the optimisation for not loading AST works
|
||||
public void testWithLibrary() throws Exception { doTest(); }
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -117,7 +117,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
}
|
||||
|
||||
public void testConvertOldProfile() throws Exception {
|
||||
Element element = JDOMUtil.loadDocument("<inspections version=\"1.0\">\n" +
|
||||
Element element = JdomKt.loadElement("<inspections version=\"1.0\">\n" +
|
||||
" <option name=\"myName\" value=\"ToConvert\" />\n" +
|
||||
" <inspection_tool class=\"JavaDoc\" enabled=\"false\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
|
||||
" <option name=\"TOP_LEVEL_CLASS_OPTIONS\">\n" +
|
||||
@@ -149,7 +149,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
" <option name=\"IGNORE_POINT_TO_ITSELF\" value=\"false\" />\n" +
|
||||
" <option name=\"myAdditionalJavadocTags\" value=\"tag1,tag2 \" />\n" +
|
||||
" </inspection_tool>\n" +
|
||||
"</inspections>").getRootElement();
|
||||
"</inspections>");
|
||||
InspectionProfileImpl profile = createProfile();
|
||||
profile.readExternal(element);
|
||||
profile.getModifiableModel().commit();
|
||||
@@ -296,7 +296,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
InspectionToolsConfigurable.importInspectionProfile(toImportElement, getApplicationProfileManager(), getProject(), null);
|
||||
|
||||
//check merged
|
||||
Element mergedElement = JDOMUtil.loadDocument(mergedText).getRootElement();
|
||||
Element mergedElement = JdomKt.loadElement(mergedText);
|
||||
profile = createProfile(new InspectionProfileImpl("foo"));
|
||||
profile.readExternal(mergedElement);
|
||||
profile.getModifiableModel().commit();
|
||||
@@ -307,7 +307,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
|
||||
public void testStoredMemberVisibility() throws Exception {
|
||||
InspectionProfileImpl profile = createProfile(new InspectionProfileImpl("foo"));
|
||||
profile.readExternal(JDOMUtil.loadDocument("<profile version=\"1.0\">\n" +
|
||||
profile.readExternal(JdomKt.loadElement("<profile version=\"1.0\">\n" +
|
||||
" <inspection_tool class=\"unused\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n" +
|
||||
" <option name=\"LOCAL_VARIABLE\" value=\"true\" />\n" +
|
||||
" <option name=\"FIELD\" value=\"true\" />\n" +
|
||||
@@ -320,7 +320,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
" <option name=\"ADD_SERVLET_TO_ENTRIES\" value=\"true\" />\n" +
|
||||
" <option name=\"ADD_NONJAVA_TO_ENTRIES\" value=\"false\" />\n" +
|
||||
" </inspection_tool>\n" +
|
||||
"</profile>").getRootElement());
|
||||
"</profile>"));
|
||||
profile.modifyProfile(it -> {
|
||||
InspectionToolWrapper toolWrapper = it.getInspectionTool("unused", getProject());
|
||||
UnusedDeclarationInspectionBase tool = (UnusedDeclarationInspectionBase)toolWrapper.getTool();
|
||||
@@ -481,7 +481,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
}
|
||||
|
||||
private static void checkMergedNoChanges(String initialText) throws Exception {
|
||||
final Element element = JDOMUtil.loadDocument(initialText).getRootElement();
|
||||
final Element element = JdomKt.loadElement(initialText);
|
||||
InspectionProfileImpl profile = createProfile(new InspectionProfileImpl("foo"));
|
||||
profile.readExternal(element);
|
||||
profile.getModifiableModel().commit();
|
||||
@@ -615,13 +615,13 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
|
||||
public void testInspectionInitializationForSerialization() throws Exception {
|
||||
InspectionProfileImpl foo = new InspectionProfileImpl("foo");
|
||||
foo.readExternal(JDOMUtil.loadDocument("<profile version=\"1.0\">\n" +
|
||||
foo.readExternal(JdomKt.loadElement("<profile version=\"1.0\">\n" +
|
||||
" <option name=\"myName\" value=\"idea.default\" />\n" +
|
||||
" <inspection_tool class=\"AbstractMethodCallInConstructor\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\" />\n" +
|
||||
" <inspection_tool class=\"AssignmentToForLoopParameter\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n" +
|
||||
" <option name=\"m_checkForeachParameters\" value=\"false\" />\n" +
|
||||
" </inspection_tool>\n" +
|
||||
"</profile>").getRootElement());
|
||||
"</profile>"));
|
||||
foo.initInspectionTools(getProject());
|
||||
assertEquals(1, countInitializedTools(foo));
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -21,11 +21,11 @@ import com.intellij.execution.configurations.UnknownConfigurationType;
|
||||
import com.intellij.execution.junit.JUnitConfigurationType;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.testFramework.LightIdeaTestCase;
|
||||
import com.intellij.ui.RowsDnDSupport;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import com.intellij.util.JdomKt;
|
||||
import org.jdom.Element;
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
@@ -66,7 +66,7 @@ public class RunConfigurableTest extends LightIdeaTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myConfigurable = new MockRunConfigurable(createRunManager(JDOMUtil.loadDocument(FOLDERS_CONFIGURATION).getRootElement()));
|
||||
myConfigurable = new MockRunConfigurable(createRunManager(JdomKt.loadElement(FOLDERS_CONFIGURATION)));
|
||||
myTree = myConfigurable.myTree;
|
||||
myRoot = myConfigurable.myRoot;
|
||||
myModel = myConfigurable.myTreeModel;
|
||||
|
||||
@@ -282,6 +282,18 @@ public class GotoImplementationHandlerTest extends JavaCodeInsightFixtureTestCas
|
||||
assertEquals(1, impls.length);
|
||||
}
|
||||
|
||||
public void testPrivateClassInheritors() {
|
||||
PsiFile file = myFixture.addFileToProject("Foo.java",
|
||||
"class C {\n" +
|
||||
" private static class Pr<caret>ivate {}\n" +
|
||||
" public static class Public extends Private {}" +
|
||||
"}");
|
||||
myFixture.addClass("class Inheritor extends C.Public {}");
|
||||
myFixture.configureFromExistingVirtualFile(file.getVirtualFile());
|
||||
|
||||
assertSize(2, getTargets(file));
|
||||
}
|
||||
|
||||
private PsiElement[] getTargets(PsiFile file) {
|
||||
GotoTargetHandler.GotoData gotoData = CodeInsightTestUtil.gotoImplementation(myFixture.getEditor(), file);
|
||||
assertNotNull(gotoData);
|
||||
|
||||
@@ -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.
|
||||
@@ -16,10 +16,10 @@
|
||||
package com.intellij.openapi.wm.impl;
|
||||
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.wm.ToolWindowEP;
|
||||
import com.intellij.openapi.wm.ToolWindowId;
|
||||
import com.intellij.usageView.impl.UsageViewManagerImpl;
|
||||
import com.intellij.util.JdomKt;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -41,7 +41,7 @@ public class HiddenSidebarButtonTest extends ToolWindowManagerTestCase {
|
||||
|
||||
public void testHiddenButton() throws Exception {
|
||||
DesktopLayout layout = myManager.getLayout();
|
||||
layout.readExternal(JDOMUtil.loadDocument(LAYOUT).getRootElement());
|
||||
layout.readExternal(JdomKt.loadElement(LAYOUT));
|
||||
for (String ID : IDS) {
|
||||
assertFalse(layout.isToolWindowRegistered(ID));
|
||||
assertTrue(layout.isToolWindowUnregistered(ID));
|
||||
|
||||
@@ -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.
|
||||
@@ -206,6 +206,8 @@ public class ClsMirrorBuildingTest extends LightIdeaTestCase {
|
||||
}
|
||||
|
||||
assertEquals(expected, ClsFileImpl.decompile(file).toString());
|
||||
|
||||
((ClsFileImpl)getPsiManager().findFile(file)).getMirror();
|
||||
}
|
||||
|
||||
private static boolean isInner(String name) throws IOException {
|
||||
|
||||
@@ -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.
|
||||
@@ -16,8 +16,8 @@
|
||||
package com.intellij.run
|
||||
|
||||
import com.intellij.application.options.PathMacrosCollector
|
||||
import com.intellij.openapi.util.JDOMUtil
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import com.intellij.util.JdomKt
|
||||
|
||||
class JavaPathMacroCollectorTest extends LightCodeInsightFixtureTestCase {
|
||||
void testJunitConfiguration() {
|
||||
@@ -56,8 +56,7 @@ class JavaPathMacroCollectorTest extends LightCodeInsightFixtureTestCase {
|
||||
</recent_temporary>
|
||||
</component>
|
||||
'''
|
||||
def element = JDOMUtil.loadDocument(text).rootElement
|
||||
assert PathMacrosCollector.getMacroNames(element).empty
|
||||
assert PathMacrosCollector.getMacroNames(JdomKt.loadElement(text)).empty
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.jetbrains.jsonSchema;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.xmlb.annotations.Transient;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -74,7 +76,7 @@ public class JsonSchemaMappingsProjectConfiguration extends JsonSchemaMappingsCo
|
||||
private void recalculateSchemaFiles() {
|
||||
ApplicationManager.getApplication().invokeLater(() -> {
|
||||
ApplicationManager.getApplication().runWriteAction(() -> FileTypeManagerEx.getInstanceEx().fireFileTypesChanged());
|
||||
}, o -> !myProject.isDisposed());
|
||||
}, ModalityState.NON_MODAL, myProject == null ? Condition.FALSE : myProject.getDisposed());
|
||||
mySchemaFiles.clear();
|
||||
if (myProject == null || myProject.getBaseDir() == null) return;
|
||||
|
||||
|
||||
+10
-9
@@ -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.
|
||||
@@ -20,17 +20,19 @@ import com.intellij.codeInspection.ex.InspectionProfileImpl;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.profile.codeInspection.InspectionProfileManager;
|
||||
import com.intellij.util.JdomKt;
|
||||
import com.intellij.util.io.PathKt;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -93,20 +95,19 @@ public class InspectionProfileConvertor {
|
||||
}
|
||||
|
||||
private static void renameOldDefaultsProfile() {
|
||||
String directoryPath = PathManager.getConfigPath() + File.separator + InspectionProfileManager.INSPECTION_DIR;
|
||||
File profileDirectory = new File(directoryPath);
|
||||
if (!profileDirectory.exists()) {
|
||||
Path directoryPath = Paths.get(PathManager.getConfigPath(), InspectionProfileManager.INSPECTION_DIR);
|
||||
if (!PathKt.exists(directoryPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
File[] files = profileDirectory.listFiles(pathname -> pathname.getPath().endsWith(File.separator + DEFAULT_XML));
|
||||
File[] files = directoryPath.toFile().listFiles(pathname -> pathname.getPath().endsWith(File.separator + DEFAULT_XML));
|
||||
if (files == null || files.length != 1 || !files[0].isFile() || files[0].length() == 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Element root = JDOMUtil.load(files[0]);
|
||||
Element root = JdomKt.loadElement(files[0].toPath());
|
||||
if (root.getAttributeValue(VERSION_ATT) == null){
|
||||
JDOMUtil.writeParent(root, new FileOutputStream(new File(profileDirectory, OLD_DEFAUL_PROFILE + XML_EXTENSION)), "\n");
|
||||
JdomKt.write(root, directoryPath.resolve(OLD_DEFAUL_PROFILE + XML_EXTENSION));
|
||||
FileUtil.delete(files[0]);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -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.
|
||||
@@ -18,8 +18,8 @@ package com.intellij.profile.codeInspection;
|
||||
import com.intellij.codeInspection.ex.InspectionProfileImpl;
|
||||
import com.intellij.codeInspection.ex.InspectionToolRegistrar;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.JdomKt;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -46,7 +46,7 @@ public class InspectionProfileLoadUtil {
|
||||
public static InspectionProfileImpl load(@NotNull File file,
|
||||
@NotNull InspectionToolRegistrar registrar,
|
||||
@NotNull InspectionProfileManager profileManager) throws JDOMException, IOException, InvalidDataException {
|
||||
Element element = JDOMUtil.load(file);
|
||||
Element element = JdomKt.loadElement(file.getPath());
|
||||
InspectionProfileImpl profile = new InspectionProfileImpl(getProfileName(file, element), registrar,
|
||||
(BaseInspectionProfileManager)profileManager);
|
||||
final Element profileElement = element.getChild("profile");
|
||||
|
||||
@@ -50,7 +50,6 @@ public class BootstrapClassLoaderUtil extends ClassUtilCore {
|
||||
@NotNull
|
||||
public static ClassLoader initClassLoader(boolean updatePlugins) throws MalformedURLException {
|
||||
PathManager.loadProperties();
|
||||
PathManager.patchProperties();
|
||||
|
||||
Collection<URL> classpath = new LinkedHashSet<URL>();
|
||||
addParentClasspath(classpath, false);
|
||||
|
||||
+21
-12
@@ -18,6 +18,7 @@ package org.jetbrains.intellij.build.impl
|
||||
import com.intellij.openapi.util.MultiValuesMap
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.apache.tools.ant.types.FileSet
|
||||
import org.apache.tools.ant.types.resources.FileProvider
|
||||
import org.jetbrains.intellij.build.BuildContext
|
||||
import org.jetbrains.intellij.build.BuildOptions
|
||||
import org.jetbrains.intellij.build.BuildTasks
|
||||
@@ -32,7 +33,7 @@ import org.jetbrains.jps.util.JpsPathUtil
|
||||
|
||||
/**
|
||||
* Assembles output of modules to platform JARs (in {@link org.jetbrains.intellij.build.BuildPaths#distAll distAll}/lib directory),
|
||||
* bunlded plugins' JARs (in {@link org.jetbrains.intellij.build.BuildPaths#distAll distAll}/plugins directory) and zip archives with
|
||||
* bundled plugins' JARs (in {@link org.jetbrains.intellij.build.BuildPaths#distAll distAll}/plugins directory) and zip archives with
|
||||
* non-bundled plugins (in {@link org.jetbrains.intellij.build.BuildPaths#artifacts artifacts}/plugins directory).
|
||||
*
|
||||
* @author nik
|
||||
@@ -293,27 +294,31 @@ class DistributionJARsBuilder {
|
||||
def enabledModulesSet = buildContext.productProperties.productLayout.enabledPluginModules
|
||||
pluginsToInclude.each { plugin ->
|
||||
def actualModuleJars = plugin.getActualModules(enabledModulesSet)
|
||||
checkOutputOfPluginModules(plugin.mainModule, actualModuleJars.values())
|
||||
checkOutputOfPluginModules(plugin.mainModule, actualModuleJars.values(), plugin.moduleExcludes)
|
||||
buildByLayout(layoutBuilder, plugin, "$targetDirectory/$plugin.directoryName", actualModuleJars)
|
||||
}
|
||||
}
|
||||
|
||||
private void checkOutputOfPluginModules(String mainPluginModule, Collection<String> moduleNames) {
|
||||
def modulesWithPluginXml = moduleNames.findAll { containsFileInOutput(it, "META-INF/plugin.xml") }
|
||||
private void checkOutputOfPluginModules(String mainPluginModule, Collection<String> moduleNames, MultiValuesMap<String, String> moduleExcludes) {
|
||||
def modulesWithPluginXml = moduleNames.findAll { containsFileInOutput(it, "META-INF/plugin.xml", moduleExcludes.get(it)) }
|
||||
if (modulesWithPluginXml.size() > 1) {
|
||||
buildContext.messages.error("Multiple modules (${modulesWithPluginXml.join(", ")}) from '$mainPluginModule' plugin contain plugin.xml files so the plugin won't work properly")
|
||||
}
|
||||
|
||||
moduleNames.each {
|
||||
if (containsFileInOutput(it, "com/intellij/uiDesigner/core/GridLayoutManager.class")) {
|
||||
if (containsFileInOutput(it, "com/intellij/uiDesigner/core/GridLayoutManager.class", moduleExcludes.get(it))) {
|
||||
buildContext.messages.error("Runtime classes of GUI designer must not be packaged to '$mainPluginModule' plugin, because they are included into a platform JAR. " +
|
||||
"Make sure that 'Automatically copy form runtime classes to the output directory' is disabled in Settings | Editor | GUI Designer.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean containsFileInOutput(String moduleName, String filePath) {
|
||||
return new File(buildContext.projectBuilder.getModuleOutput(buildContext.findRequiredModule(moduleName), false), filePath).exists()
|
||||
private boolean containsFileInOutput(String moduleName, String filePath, Collection<String> excludes) {
|
||||
def moduleOutput = new File(buildContext.projectBuilder.getModuleOutput(buildContext.findRequiredModule(moduleName), false))
|
||||
def fileInOutput = new File(moduleOutput, filePath)
|
||||
return fileInOutput.exists() && (excludes == null || excludes.every {
|
||||
createFileSet(it, moduleOutput).iterator().every { !(it instanceof FileProvider && FileUtil.filesEqual(it.file, fileInOutput))}
|
||||
})
|
||||
}
|
||||
|
||||
private void buildByLayout(LayoutBuilder layoutBuilder, BaseLayout layout, String targetDirectory, MultiValuesMap<String, String> moduleJars) {
|
||||
@@ -419,22 +424,26 @@ class DistributionJARsBuilder {
|
||||
moduleExcludes.entrySet().each { entry ->
|
||||
String module = entry.key
|
||||
entry.value.each { pattern ->
|
||||
def fileSet = new FileSet()
|
||||
fileSet.setProject(buildContext.ant.antProject)
|
||||
def moduleOutput = new File(buildContext.projectBuilder.getModuleOutput(buildContext.findRequiredModule(module), false))
|
||||
if (!moduleOutput.exists()) {
|
||||
buildContext.messages.error("There are excludes defined for module '$module', but the module wasn't compiled; " +
|
||||
"most probably it means that '$module' isn't include into the product distribution so it makes no sense to define excludes for it.")
|
||||
}
|
||||
fileSet.setDir(moduleOutput)
|
||||
fileSet.createInclude().setName(pattern)
|
||||
if (fileSet.size() == 0) {
|
||||
if (createFileSet(pattern, moduleOutput).size() == 0) {
|
||||
buildContext.messages.error("Incorrect exludes for module '$module': nothing matches to $pattern in the module output")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FileSet createFileSet(String pattern, File baseDir) {
|
||||
def fileSet = new FileSet()
|
||||
fileSet.setProject(buildContext.ant.antProject)
|
||||
fileSet.setDir(baseDir)
|
||||
fileSet.createInclude().setName(pattern)
|
||||
return fileSet
|
||||
}
|
||||
|
||||
static String basePath(BuildContext buildContext, String moduleName) {
|
||||
JpsPathUtil.urlToPath(buildContext.findRequiredModule(moduleName).contentRootsList.urls.first())
|
||||
}
|
||||
|
||||
@@ -132,7 +132,8 @@ open class FileBasedStorage(file: Path,
|
||||
else {
|
||||
val charBuffer = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(file.contentsToByteArray()))
|
||||
lineSeparator = detectLineSeparators(charBuffer, if (isUseXmlProlog) null else LineSeparator.LF)
|
||||
return JDOMUtil.loadDocument(charBuffer).detachRootElement()
|
||||
@Suppress("DEPRECATION")
|
||||
return loadElement(charBuffer)
|
||||
}
|
||||
return null
|
||||
}
|
||||
@@ -242,7 +243,7 @@ private fun doWrite(requestor: Any, file: VirtualFile, content: Any, lineSeparat
|
||||
out.write(lineSeparator.separatorBytes)
|
||||
}
|
||||
if (content is Element) {
|
||||
JDOMUtil.writeParent(content, out, lineSeparator.separatorString)
|
||||
JDOMUtil.write(content, out, lineSeparator.separatorString)
|
||||
}
|
||||
else {
|
||||
(content as BufferExposingByteArrayOutputStream).writeTo(out)
|
||||
@@ -253,7 +254,7 @@ private fun doWrite(requestor: Any, file: VirtualFile, content: Any, lineSeparat
|
||||
|
||||
internal fun Parent.toBufferExposingByteArray(lineSeparator: String = "\n"): BufferExposingByteArrayOutputStream {
|
||||
val out = BufferExposingByteArrayOutputStream(512)
|
||||
JDOMUtil.writeParent(this, out, lineSeparator)
|
||||
JDOMUtil.write(this, out, lineSeparator)
|
||||
return out
|
||||
}
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ abstract class ProjectStoreBase(override final val project: ProjectImpl) : Compo
|
||||
wrapper.addContent(profile)
|
||||
val path = Paths.get(storageManager.expandMacro(PROJECT_CONFIG_DIR), if (isInspection) "inspectionProfiles" else "copyright",
|
||||
"${FileUtil.sanitizeFileName(schemeName, true)}.xml")
|
||||
JDOMUtil.writeParent(wrapper, path.outputStream(), "\n")
|
||||
JDOMUtil.write(wrapper, path.outputStream(), "\n")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ fun getNewByteIfDiffers(key: String, newState: Any, oldState: ByteArray): ByteAr
|
||||
|
||||
val logChangedComponents = SystemProperties.getBooleanProperty("idea.log.changed.components", false)
|
||||
if (ApplicationManager.getApplication().isUnitTestMode || logChangedComponents ) {
|
||||
fun stateToString(state: Any) = JDOMUtil.writeParent(state as? Element ?: unarchiveState(state as ByteArray), "\n")
|
||||
fun stateToString(state: Any) = JDOMUtil.write(state as? Element ?: unarchiveState(state as ByteArray), "\n")
|
||||
|
||||
val before = stateToString(oldState)
|
||||
val after = stateToString(newState)
|
||||
|
||||
@@ -634,7 +634,7 @@ internal class XmlSerializerTest {
|
||||
|
||||
private fun checkSmartSerialization(bean: Bean2, serialized: String) {
|
||||
val serializer = SmartSerializer()
|
||||
serializer.readExternal(bean, JDOMUtil.loadDocument(serialized).rootElement)
|
||||
serializer.readExternal(bean, JDOMUtil.load(serialized))
|
||||
val serializedState = Element("Bean2")
|
||||
serializer.writeExternal(bean, serializedState)
|
||||
assertThat(JDOMUtil.writeElement(serializedState)).isEqualTo(serialized)
|
||||
|
||||
@@ -164,14 +164,14 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
|
||||
PsiDocumentManager.getInstance(project).getLastCommittedText(document));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CommitTask doQueue(@NotNull Project project,
|
||||
private void doQueue(@NotNull Project project,
|
||||
@NotNull Document document,
|
||||
@NotNull List<Pair<PsiFileImpl, FileASTNode>> oldFileNodes,
|
||||
@NotNull Object reason,
|
||||
@NotNull ModalityState currentModalityState,
|
||||
@NotNull CharSequence lastCommittedText) {
|
||||
synchronized (lock) {
|
||||
if (!project.isInitialized()) return; // check the project is disposed under lock.
|
||||
CommitTask newTask = createNewTaskAndCancelSimilar(project, document, oldFileNodes, reason, currentModalityState,
|
||||
lastCommittedText);
|
||||
|
||||
@@ -179,7 +179,6 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
|
||||
log(project, "Queued", newTask, reason);
|
||||
|
||||
wakeUpQueue();
|
||||
return newTask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,10 +555,8 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
|
||||
if (task.reason.equals(SYNC_COMMIT_REASON)) {
|
||||
throw new PsiInvalidElementAccessException(file, "File " + file + " invalidated during sync commit");
|
||||
}
|
||||
else {
|
||||
commitAsynchronously(project, document, "File " + file + " invalidated during background commit; task: "+task,
|
||||
task.myCreationModalityState);
|
||||
}
|
||||
commitAsynchronously(project, document, "File " + file + " invalidated during background commit; task: "+task,
|
||||
task.myCreationModalityState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,6 +204,7 @@ public class TextMergeViewer implements MergeTool.MergeViewer {
|
||||
|
||||
myTextDiffProvider = new TextDiffProviderBase(getTextSettings(),
|
||||
myInnerDiffWorker::onSettingsChanged,
|
||||
this,
|
||||
ar(IgnorePolicy.DEFAULT),
|
||||
ar(HighlightPolicy.BY_LINE, HighlightPolicy.BY_WORD));
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
|
||||
myEditorSettingsAction = new SetEditorSettingsAction(getTextSettings(), getEditors());
|
||||
myEditorSettingsAction.applyDefaults();
|
||||
|
||||
myTextDiffProvider = DiffUtil.createNoIgnoreTextDiffProvider(getProject(), getRequest(), getTextSettings(), this::rediff);
|
||||
myTextDiffProvider = DiffUtil.createNoIgnoreTextDiffProvider(getProject(), getRequest(), getTextSettings(), this::rediff, this);
|
||||
|
||||
new MyOpenInEditorWithMouseAction().install(getEditors());
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
|
||||
myModifierProvider = new ModifierProvider();
|
||||
|
||||
myTextDiffProvider = DiffUtil.createTextDiffProvider(getProject(), getRequest(), getTextSettings(), this::rediff);
|
||||
myTextDiffProvider = DiffUtil.createTextDiffProvider(getProject(), getRequest(), getTextSettings(), this::rediff, this);
|
||||
|
||||
DiffUtil.registerAction(new ReplaceSelectedChangesAction(Side.LEFT, true), myPanel);
|
||||
DiffUtil.registerAction(new AppendSelectedChangesAction(Side.LEFT, true), myPanel);
|
||||
|
||||
@@ -56,7 +56,7 @@ public class SimpleOnesideDiffViewer extends OnesideTextDiffViewer {
|
||||
public SimpleOnesideDiffViewer(@NotNull DiffContext context, @NotNull DiffRequest request) {
|
||||
super(context, (ContentDiffRequest)request);
|
||||
|
||||
myTextDiffProvider = DiffUtil.createTextDiffProvider(getProject(), getRequest(), getTextSettings(), this::rediff);
|
||||
myTextDiffProvider = DiffUtil.createTextDiffProvider(getProject(), getRequest(), getTextSettings(), this::rediff, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewerEx {
|
||||
public SimpleThreesideDiffViewer(@NotNull DiffContext context, @NotNull DiffRequest request) {
|
||||
super(context, (ContentDiffRequest)request);
|
||||
|
||||
myTextDiffProvider = new SimpleThreesideTextDiffProvider(getTextSettings(), this::rediff);
|
||||
myTextDiffProvider = new SimpleThreesideTextDiffProvider(getTextSettings(), this::rediff, this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -17,12 +17,15 @@ package com.intellij.diff.tools.util.base
|
||||
|
||||
import com.intellij.diff.util.DiffPlaces
|
||||
import com.intellij.diff.util.DiffUtil
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.components.PersistentStateComponent
|
||||
import com.intellij.openapi.components.State
|
||||
import com.intellij.openapi.components.Storage
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.util.EventDispatcher
|
||||
import com.intellij.util.xmlb.annotations.MapAnnotation
|
||||
import com.intellij.util.xmlb.annotations.Transient
|
||||
import java.util.*
|
||||
|
||||
@State(
|
||||
@@ -61,12 +64,19 @@ class TextDiffSettingsHolder : PersistentStateComponent<TextDiffSettingsHolder.S
|
||||
|
||||
// Fragments settings
|
||||
var EXPAND_BY_DEFAULT: Boolean = true
|
||||
)
|
||||
) {
|
||||
@Transient
|
||||
val eventDispatcher: EventDispatcher<TextDiffSettings.Listener> = EventDispatcher.create(TextDiffSettings.Listener::class.java)
|
||||
}
|
||||
|
||||
class TextDiffSettings internal constructor(private val SHARED_SETTINGS: SharedSettings,
|
||||
private val PLACE_SETTINGS: PlaceSettings) {
|
||||
constructor() : this(SharedSettings(), PlaceSettings())
|
||||
|
||||
fun addListener(listener: Listener, disposable: Disposable) {
|
||||
PLACE_SETTINGS.eventDispatcher.addListener(listener, disposable)
|
||||
}
|
||||
|
||||
// Presentation settings
|
||||
|
||||
var isEnableSyncScroll: Boolean
|
||||
@@ -77,11 +87,13 @@ class TextDiffSettingsHolder : PersistentStateComponent<TextDiffSettingsHolder.S
|
||||
|
||||
var highlightPolicy: HighlightPolicy
|
||||
get() = PLACE_SETTINGS.HIGHLIGHT_POLICY
|
||||
set(value) { PLACE_SETTINGS.HIGHLIGHT_POLICY = value }
|
||||
set(value) { PLACE_SETTINGS.HIGHLIGHT_POLICY = value
|
||||
PLACE_SETTINGS.eventDispatcher.multicaster.highlightPolicyChanged() }
|
||||
|
||||
var ignorePolicy: IgnorePolicy
|
||||
get() = PLACE_SETTINGS.IGNORE_POLICY
|
||||
set(value) { PLACE_SETTINGS.IGNORE_POLICY = value }
|
||||
set(value) { PLACE_SETTINGS.IGNORE_POLICY = value
|
||||
PLACE_SETTINGS.eventDispatcher.multicaster.ignorePolicyChanged() }
|
||||
|
||||
//
|
||||
// Merge
|
||||
@@ -139,6 +151,11 @@ class TextDiffSettingsHolder : PersistentStateComponent<TextDiffSettingsHolder.S
|
||||
@JvmStatic fun getSettings(): TextDiffSettings = getSettings(null)
|
||||
@JvmStatic fun getSettings(place: String?): TextDiffSettings = service<TextDiffSettingsHolder>().getSettings(place)
|
||||
}
|
||||
|
||||
interface Listener : EventListener {
|
||||
fun highlightPolicyChanged() {}
|
||||
fun ignorePolicyChanged() {}
|
||||
}
|
||||
}
|
||||
|
||||
fun getSettings(place: String?): TextDiffSettings {
|
||||
|
||||
@@ -261,14 +261,11 @@ public class TextDiffViewerUtil {
|
||||
|
||||
public static class HighlightPolicySettingAction extends EnumPolicySettingAction<HighlightPolicy> {
|
||||
@NotNull protected final TextDiffSettings mySettings;
|
||||
@NotNull private final Runnable myRediffRunnable;
|
||||
|
||||
public HighlightPolicySettingAction(@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull HighlightPolicy... policies) {
|
||||
super(policies);
|
||||
mySettings = settings;
|
||||
myRediffRunnable = rediff;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -276,7 +273,6 @@ public class TextDiffViewerUtil {
|
||||
if (getValue() == option) return;
|
||||
UsageTrigger.trigger("diff.TextDiffSettings.HighlightPolicy." + option.name());
|
||||
mySettings.setHighlightPolicy(option);
|
||||
myRediffRunnable.run();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -306,14 +302,11 @@ public class TextDiffViewerUtil {
|
||||
|
||||
public static class IgnorePolicySettingAction extends EnumPolicySettingAction<IgnorePolicy> {
|
||||
@NotNull protected final TextDiffSettings mySettings;
|
||||
@NotNull private final Runnable myRediffRunnable;
|
||||
|
||||
public IgnorePolicySettingAction(@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull IgnorePolicy... policies) {
|
||||
super(policies);
|
||||
mySettings = settings;
|
||||
myRediffRunnable = rediff;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -321,7 +314,6 @@ public class TextDiffViewerUtil {
|
||||
if (getValue() == option) return;
|
||||
UsageTrigger.trigger("diff.TextDiffSettings.IgnorePolicy." + option.name());
|
||||
mySettings.setIgnorePolicy(option);
|
||||
myRediffRunnable.run();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+17
-13
@@ -21,7 +21,8 @@ import com.intellij.diff.fragments.LineFragment;
|
||||
import com.intellij.diff.tools.util.base.HighlightPolicy;
|
||||
import com.intellij.diff.tools.util.base.IgnorePolicy;
|
||||
import com.intellij.diff.tools.util.base.TextDiffSettingsHolder.TextDiffSettings;
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx;
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx.DiffComputer;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -32,7 +33,7 @@ import static com.intellij.diff.tools.util.base.HighlightPolicy.*;
|
||||
import static com.intellij.diff.tools.util.base.IgnorePolicy.*;
|
||||
|
||||
public class SimpleTextDiffProvider extends TwosideTextDiffProviderBase implements TwosideTextDiffProvider {
|
||||
static final DiffUserDataKeysEx.DiffComputer DEFAULT_COMPUTER = (text1, text2, policy, innerChanges, indicator) -> {
|
||||
static final DiffComputer DEFAULT_COMPUTER = (text1, text2, policy, innerChanges, indicator) -> {
|
||||
if (innerChanges) {
|
||||
return ComparisonManager.getInstance().compareLinesInner(text1, text2, policy, indicator);
|
||||
}
|
||||
@@ -44,25 +45,28 @@ public class SimpleTextDiffProvider extends TwosideTextDiffProviderBase implemen
|
||||
private static final IgnorePolicy[] IGNORE_POLICIES = {DEFAULT, TRIM_WHITESPACES, IGNORE_WHITESPACES, IGNORE_WHITESPACES_CHUNKS};
|
||||
private static final HighlightPolicy[] HIGHLIGHT_POLICIES = {BY_LINE, BY_WORD, BY_WORD_SPLIT, DO_NOT_HIGHLIGHT};
|
||||
|
||||
@NotNull private final DiffUserDataKeysEx.DiffComputer myDiffComputer;
|
||||
@NotNull private final DiffComputer myDiffComputer;
|
||||
|
||||
public SimpleTextDiffProvider(@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff) {
|
||||
this(settings, rediff, DEFAULT_COMPUTER);
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull Disposable disposable) {
|
||||
this(settings, rediff, disposable, DEFAULT_COMPUTER);
|
||||
}
|
||||
|
||||
public SimpleTextDiffProvider(@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull DiffUserDataKeysEx.DiffComputer diffComputer) {
|
||||
this(settings, rediff, diffComputer, IGNORE_POLICIES, HIGHLIGHT_POLICIES);
|
||||
@NotNull Disposable disposable,
|
||||
@NotNull DiffComputer diffComputer) {
|
||||
this(settings, rediff, disposable, diffComputer, IGNORE_POLICIES, HIGHLIGHT_POLICIES);
|
||||
}
|
||||
|
||||
private SimpleTextDiffProvider(@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull DiffUserDataKeysEx.DiffComputer diffComputer,
|
||||
@NotNull Disposable disposable,
|
||||
@NotNull DiffComputer diffComputer,
|
||||
@NotNull IgnorePolicy[] ignorePolicies,
|
||||
@NotNull HighlightPolicy[] highlightPolicies) {
|
||||
super(settings, rediff, ignorePolicies, highlightPolicies);
|
||||
super(settings, rediff, disposable, ignorePolicies, highlightPolicies);
|
||||
myDiffComputer = diffComputer;
|
||||
}
|
||||
|
||||
@@ -79,12 +83,12 @@ public class SimpleTextDiffProvider extends TwosideTextDiffProviderBase implemen
|
||||
|
||||
|
||||
public static class NoIgnore extends SimpleTextDiffProvider implements TwosideTextDiffProvider.NoIgnore {
|
||||
public NoIgnore(@NotNull TextDiffSettings settings, @NotNull Runnable rediff) {
|
||||
this(settings, rediff, DEFAULT_COMPUTER);
|
||||
public NoIgnore(@NotNull TextDiffSettings settings, @NotNull Runnable rediff, @NotNull Disposable disposable) {
|
||||
this(settings, rediff, disposable, DEFAULT_COMPUTER);
|
||||
}
|
||||
|
||||
public NoIgnore(@NotNull TextDiffSettings settings, @NotNull Runnable rediff, @NotNull DiffUserDataKeysEx.DiffComputer diffComputer) {
|
||||
super(settings, rediff, diffComputer, IGNORE_POLICIES, ArrayUtil.remove(HIGHLIGHT_POLICIES, DO_NOT_HIGHLIGHT));
|
||||
public NoIgnore(@NotNull TextDiffSettings settings, @NotNull Runnable rediff, @NotNull Disposable disposable, @NotNull DiffComputer diffComputer) {
|
||||
super(settings, rediff, disposable, diffComputer, IGNORE_POLICIES, ArrayUtil.remove(HIGHLIGHT_POLICIES, DO_NOT_HIGHLIGHT));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+4
-2
@@ -24,6 +24,7 @@ import com.intellij.diff.tools.util.base.TextDiffSettingsHolder.TextDiffSettings
|
||||
import com.intellij.diff.util.DiffUtil;
|
||||
import com.intellij.diff.util.MergeConflictType;
|
||||
import com.intellij.diff.util.ThreeSide;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -40,8 +41,9 @@ public class SimpleThreesideTextDiffProvider extends TextDiffProviderBase {
|
||||
private static final HighlightPolicy[] HIGHLIGHT_POLICIES = {BY_LINE, BY_WORD};
|
||||
|
||||
public SimpleThreesideTextDiffProvider(@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff) {
|
||||
super(settings, rediff, IGNORE_POLICIES, HIGHLIGHT_POLICIES);
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull Disposable disposable) {
|
||||
super(settings, rediff, disposable, IGNORE_POLICIES, HIGHLIGHT_POLICIES);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+13
-7
@@ -25,6 +25,7 @@ import com.intellij.diff.tools.util.base.HighlightPolicy;
|
||||
import com.intellij.diff.tools.util.base.IgnorePolicy;
|
||||
import com.intellij.diff.tools.util.base.TextDiffSettingsHolder.TextDiffSettings;
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
@@ -51,24 +52,26 @@ public class SmartTextDiffProvider extends TwosideTextDiffProviderBase implement
|
||||
public static TwosideTextDiffProvider create(@Nullable Project project,
|
||||
@NotNull ContentDiffRequest request,
|
||||
@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff) {
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull Disposable disposable) {
|
||||
DiffContent content1 = Side.LEFT.select(request.getContents());
|
||||
DiffContent content2 = Side.RIGHT.select(request.getContents());
|
||||
DiffIgnoredRangeProvider ignoredRangeProvider = getIgnoredRangeProvider(project, content1, content2);
|
||||
if (ignoredRangeProvider == null) return null;
|
||||
return new SmartTextDiffProvider(project, content1, content2, settings, rediff, ignoredRangeProvider);
|
||||
return new SmartTextDiffProvider(project, content1, content2, settings, rediff, disposable, ignoredRangeProvider);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TwosideTextDiffProvider.NoIgnore createNoIgnore(@Nullable Project project,
|
||||
@NotNull ContentDiffRequest request,
|
||||
@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff) {
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull Disposable disposable) {
|
||||
DiffContent content1 = Side.LEFT.select(request.getContents());
|
||||
DiffContent content2 = Side.RIGHT.select(request.getContents());
|
||||
DiffIgnoredRangeProvider ignoredRangeProvider = getIgnoredRangeProvider(project, content1, content2);
|
||||
if (ignoredRangeProvider == null) return null;
|
||||
return new SmartTextDiffProvider.NoIgnore(project, content1, content2, settings, rediff, ignoredRangeProvider);
|
||||
return new SmartTextDiffProvider.NoIgnore(project, content1, content2, settings, rediff, disposable, ignoredRangeProvider);
|
||||
}
|
||||
|
||||
private SmartTextDiffProvider(@Nullable Project project,
|
||||
@@ -76,8 +79,9 @@ public class SmartTextDiffProvider extends TwosideTextDiffProviderBase implement
|
||||
@NotNull DiffContent content2,
|
||||
@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull Disposable disposable,
|
||||
@NotNull DiffIgnoredRangeProvider ignoredRangeProvider) {
|
||||
this(project, content1, content2, settings, rediff, ignoredRangeProvider, IGNORE_POLICIES, HIGHLIGHT_POLICIES);
|
||||
this(project, content1, content2, settings, rediff, disposable, ignoredRangeProvider, IGNORE_POLICIES, HIGHLIGHT_POLICIES);
|
||||
}
|
||||
|
||||
private SmartTextDiffProvider(@Nullable Project project,
|
||||
@@ -85,10 +89,11 @@ public class SmartTextDiffProvider extends TwosideTextDiffProviderBase implement
|
||||
@NotNull DiffContent content2,
|
||||
@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull Disposable disposable,
|
||||
@NotNull DiffIgnoredRangeProvider ignoredRangeProvider,
|
||||
@NotNull IgnorePolicy[] ignorePolicies,
|
||||
@NotNull HighlightPolicy[] highlightPolicies) {
|
||||
super(settings, rediff, ignorePolicies, highlightPolicies);
|
||||
super(settings, rediff, disposable, ignorePolicies, highlightPolicies);
|
||||
myProject = project;
|
||||
myContent1 = content1;
|
||||
myContent2 = content2;
|
||||
@@ -151,8 +156,9 @@ public class SmartTextDiffProvider extends TwosideTextDiffProviderBase implement
|
||||
@NotNull DiffContent content2,
|
||||
@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull Disposable disposable,
|
||||
@NotNull DiffIgnoredRangeProvider ignoredRangeProvider) {
|
||||
super(project, content1, content2, settings, rediff, ignoredRangeProvider,
|
||||
super(project, content1, content2, settings, rediff, disposable, ignoredRangeProvider,
|
||||
IGNORE_POLICIES, ArrayUtil.remove(HIGHLIGHT_POLICIES, DO_NOT_HIGHLIGHT));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.diff.tools.util.base.IgnorePolicy;
|
||||
import com.intellij.diff.tools.util.base.TextDiffSettingsHolder.TextDiffSettings;
|
||||
import com.intellij.diff.tools.util.base.TextDiffViewerUtil.HighlightPolicySettingAction;
|
||||
import com.intellij.diff.tools.util.base.TextDiffViewerUtil.IgnorePolicySettingAction;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.Separator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -36,10 +37,12 @@ public class TextDiffProviderBase implements TextDiffProvider {
|
||||
|
||||
public TextDiffProviderBase(@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull Disposable disposable,
|
||||
@NotNull IgnorePolicy[] ignorePolicies,
|
||||
@NotNull HighlightPolicy[] highlightPolicies) {
|
||||
myIgnorePolicySettingAction = new MyIgnorePolicySettingAction(settings, rediff, ignorePolicies);
|
||||
myHighlightPolicySettingAction = new MyHighlightPolicySettingAction(settings, rediff, highlightPolicies);
|
||||
myIgnorePolicySettingAction = new MyIgnorePolicySettingAction(settings, ignorePolicies);
|
||||
myHighlightPolicySettingAction = new MyHighlightPolicySettingAction(settings, highlightPolicies);
|
||||
settings.addListener(new MyListener(rediff), disposable);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -86,9 +89,8 @@ public class TextDiffProviderBase implements TextDiffProvider {
|
||||
|
||||
private class MyIgnorePolicySettingAction extends IgnorePolicySettingAction {
|
||||
public MyIgnorePolicySettingAction(@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull IgnorePolicy[] ignorePolicies) {
|
||||
super(settings, rediff, ignorePolicies);
|
||||
super(settings, ignorePolicies);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -100,9 +102,8 @@ public class TextDiffProviderBase implements TextDiffProvider {
|
||||
|
||||
private class MyHighlightPolicySettingAction extends HighlightPolicySettingAction {
|
||||
public MyHighlightPolicySettingAction(@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull HighlightPolicy[] highlightPolicies) {
|
||||
super(settings, rediff, highlightPolicies);
|
||||
super(settings, highlightPolicies);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -111,4 +112,22 @@ public class TextDiffProviderBase implements TextDiffProvider {
|
||||
return notNullize(TextDiffProviderBase.this.getText(option), super.getText(option));
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyListener implements TextDiffSettings.Listener {
|
||||
@NotNull private final Runnable myRediff;
|
||||
|
||||
public MyListener(@NotNull Runnable rediff) {
|
||||
myRediff = rediff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void highlightPolicyChanged() {
|
||||
myRediff.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ignorePolicyChanged() {
|
||||
myRediff.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -21,6 +21,7 @@ import com.intellij.diff.fragments.LineFragment;
|
||||
import com.intellij.diff.tools.util.base.HighlightPolicy;
|
||||
import com.intellij.diff.tools.util.base.IgnorePolicy;
|
||||
import com.intellij.diff.tools.util.base.TextDiffSettingsHolder.TextDiffSettings;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -30,9 +31,10 @@ import java.util.List;
|
||||
abstract class TwosideTextDiffProviderBase extends TextDiffProviderBase implements TwosideTextDiffProvider {
|
||||
protected TwosideTextDiffProviderBase(@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull Disposable disposable,
|
||||
@NotNull IgnorePolicy[] ignorePolicies,
|
||||
@NotNull HighlightPolicy[] highlightPolicies) {
|
||||
super(settings, rediff, ignorePolicies, highlightPolicies);
|
||||
super(settings, rediff, disposable, ignorePolicies, highlightPolicies);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -600,28 +600,30 @@ public class DiffUtil {
|
||||
public static TwosideTextDiffProvider createTextDiffProvider(@Nullable Project project,
|
||||
@NotNull ContentDiffRequest request,
|
||||
@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff) {
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull Disposable disposable) {
|
||||
DiffUserDataKeysEx.DiffComputer diffComputer = request.getUserData(DiffUserDataKeysEx.CUSTOM_DIFF_COMPUTER);
|
||||
if (diffComputer != null) return new SimpleTextDiffProvider(settings, rediff, diffComputer);
|
||||
if (diffComputer != null) return new SimpleTextDiffProvider(settings, rediff, disposable, diffComputer);
|
||||
|
||||
TwosideTextDiffProvider smartProvider = SmartTextDiffProvider.create(project, request, settings, rediff);
|
||||
TwosideTextDiffProvider smartProvider = SmartTextDiffProvider.create(project, request, settings, rediff, disposable);
|
||||
if (smartProvider != null) return smartProvider;
|
||||
|
||||
return new SimpleTextDiffProvider(settings, rediff);
|
||||
return new SimpleTextDiffProvider(settings, rediff, disposable);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TwosideTextDiffProvider.NoIgnore createNoIgnoreTextDiffProvider(@Nullable Project project,
|
||||
@NotNull ContentDiffRequest request,
|
||||
@NotNull TextDiffSettings settings,
|
||||
@NotNull Runnable rediff) {
|
||||
@NotNull Runnable rediff,
|
||||
@NotNull Disposable disposable) {
|
||||
DiffUserDataKeysEx.DiffComputer diffComputer = request.getUserData(DiffUserDataKeysEx.CUSTOM_DIFF_COMPUTER);
|
||||
if (diffComputer != null) return new SimpleTextDiffProvider.NoIgnore(settings, rediff, diffComputer);
|
||||
if (diffComputer != null) return new SimpleTextDiffProvider.NoIgnore(settings, rediff, disposable, diffComputer);
|
||||
|
||||
TwosideTextDiffProvider.NoIgnore smartProvider = SmartTextDiffProvider.createNoIgnore(project, request, settings, rediff);
|
||||
TwosideTextDiffProvider.NoIgnore smartProvider = SmartTextDiffProvider.createNoIgnore(project, request, settings, rediff, disposable);
|
||||
if (smartProvider != null) return smartProvider;
|
||||
|
||||
return new SimpleTextDiffProvider.NoIgnore(settings, rediff);
|
||||
return new SimpleTextDiffProvider.NoIgnore(settings, rediff, disposable);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+342
-60
@@ -17,83 +17,365 @@ package com.intellij.diff.tools.fragmented
|
||||
|
||||
import com.intellij.diff.DiffTestCase
|
||||
import com.intellij.diff.comparison.ComparisonPolicy
|
||||
import com.intellij.diff.comparison.iterables.DiffIterable
|
||||
import com.intellij.diff.comparison.iterables.DiffIterableUtil
|
||||
import com.intellij.diff.fragments.LineFragment
|
||||
import com.intellij.diff.fragments.LineFragmentImpl
|
||||
import com.intellij.diff.util.LineRange
|
||||
import com.intellij.diff.util.Range
|
||||
import com.intellij.diff.util.Side
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl
|
||||
import com.intellij.openapi.progress.DumbProgressIndicator
|
||||
import junit.framework.TestCase
|
||||
import java.util.*
|
||||
|
||||
class UnifiedFragmentBuilderTest : DiffTestCase() {
|
||||
fun testEquals() {
|
||||
val builder = createBuilder("A\nB\nC", "A\nB\nC", Side.LEFT)
|
||||
fun testSimple() {
|
||||
Test("", "",
|
||||
".",
|
||||
" ")
|
||||
.run()
|
||||
|
||||
assertTrue(builder.isEqual)
|
||||
assertEquals(builder.text.toString(), "A\nB\nC\n")
|
||||
assertEmpty(builder.changedLines)
|
||||
assertEmpty(builder.blocks)
|
||||
Test("A_B_C", "A_B_C",
|
||||
"A_B_C",
|
||||
" _ _ ")
|
||||
.run()
|
||||
|
||||
// empty document has one line, so it's "modified" case (and not "deleted")
|
||||
Test("A", "",
|
||||
"A_.",
|
||||
"L_R")
|
||||
.run()
|
||||
|
||||
Test("", "A",
|
||||
"._A",
|
||||
"L_R")
|
||||
.run()
|
||||
|
||||
Test("A_", "",
|
||||
"A_.",
|
||||
"L_ ")
|
||||
.run()
|
||||
|
||||
Test("A_", "B",
|
||||
"A_._B",
|
||||
"L_L_R")
|
||||
.run()
|
||||
|
||||
Test("B_", "B",
|
||||
"B_.",
|
||||
" _L")
|
||||
.run()
|
||||
|
||||
Test("_B", "B",
|
||||
"._B",
|
||||
"L_ ")
|
||||
.run()
|
||||
|
||||
Test("A_A", "B",
|
||||
"A_A_B",
|
||||
"L_L_R")
|
||||
.run()
|
||||
|
||||
Test("A_B_C_D", "A_D",
|
||||
"A_B_C_D",
|
||||
" _L_L_ ")
|
||||
.run()
|
||||
|
||||
Test("X_B_C", "A_B_C",
|
||||
"X_A_B_C",
|
||||
"L_R_ _ ")
|
||||
.run()
|
||||
|
||||
Test("A_B_C", "A_B_Y",
|
||||
"A_B_C_Y",
|
||||
" _ _L_R")
|
||||
.run()
|
||||
|
||||
Test("A_B_C_D_E_F", "A_X_C_D_Y_F",
|
||||
"A_B_X_C_D_E_Y_F",
|
||||
" _L_R_ _ _L_R_ ")
|
||||
.run()
|
||||
|
||||
Test("A_B_C_D_E_F", "A_B_X_C_D_F",
|
||||
"A_B_X_C_D_E_F",
|
||||
" _ _R_ _ _L_ ")
|
||||
.run()
|
||||
|
||||
Test("A_B_C_D_E_F", "A_B_X_Y_E_F",
|
||||
"A_B_C_D_X_Y_E_F",
|
||||
" _ _L_L_R_R_ _ ")
|
||||
.run()
|
||||
|
||||
Test("", "",
|
||||
".",
|
||||
" ")
|
||||
.changes()
|
||||
.run()
|
||||
|
||||
Test("A", "B",
|
||||
"A_B",
|
||||
"L_R")
|
||||
.changes(mod(0, 0, 1, 1))
|
||||
.runLeft()
|
||||
|
||||
Test("A", "B",
|
||||
"A",
|
||||
" ")
|
||||
.changes()
|
||||
.runLeft()
|
||||
|
||||
Test("A", "B",
|
||||
"B",
|
||||
" ")
|
||||
.changes()
|
||||
.runRight()
|
||||
}
|
||||
|
||||
fun testWrongEndLineTypoBug() {
|
||||
val builder = createBuilder("A\nB\nC\nD", "A\nD", Side.RIGHT)
|
||||
fun testNonFair() {
|
||||
Test("A_B", "",
|
||||
"A_B",
|
||||
" _ ")
|
||||
.changes()
|
||||
.runLeft()
|
||||
|
||||
assertFalse(builder.isEqual)
|
||||
assertEquals(builder.text.toString(), "A\nB\nC\nD\n")
|
||||
assertEquals(builder.changedLines, listOf(LineRange(1, 3)))
|
||||
Test("A_B", "",
|
||||
".",
|
||||
" ")
|
||||
.changes()
|
||||
.runRight()
|
||||
|
||||
assertEquals(builder.blocks.size, 1)
|
||||
val block = builder.blocks[0]
|
||||
assertEquals(block.line1, 1)
|
||||
assertEquals(block.line2, 3)
|
||||
assertEquals(block.range1.start, 1)
|
||||
assertEquals(block.range1.end, 3)
|
||||
assertEquals(block.range2.start, 3)
|
||||
assertEquals(block.range2.end, 3)
|
||||
Test("A_B", "A_._B",
|
||||
"A_B",
|
||||
" _ ")
|
||||
.changes()
|
||||
.runLeft()
|
||||
|
||||
Test("A_B", "A_._B",
|
||||
"A_._B",
|
||||
" _ _ ")
|
||||
.changes()
|
||||
.runRight()
|
||||
|
||||
Test("_._A_._", "X",
|
||||
"._._A_X_._.",
|
||||
" _ _L_R_ _ ")
|
||||
.changes(mod(2, 0, 1, 1))
|
||||
.runLeft()
|
||||
|
||||
Test("_._A_._", "X",
|
||||
"A_X",
|
||||
"L_R")
|
||||
.changes(mod(2, 0, 1, 1))
|
||||
.runRight()
|
||||
|
||||
Test("A_B_C_D", "X_BC_Y",
|
||||
"A_X_BC_D_Y",
|
||||
"L_R_ _L_R")
|
||||
.changes(mod(0, 0, 1, 1), mod(3, 2, 1, 1))
|
||||
.runRight()
|
||||
|
||||
Test("A_B_C_D", "A_BC_Y",
|
||||
"A_BC_D_Y",
|
||||
" _ _L_R")
|
||||
.changes(mod(3, 2, 1, 1))
|
||||
.runRight()
|
||||
|
||||
Test("AB_C_DE", "A_B_D_E",
|
||||
"AB_C_DE",
|
||||
" _L_ ")
|
||||
.changes(del(1, 2, 1))
|
||||
.runLeft()
|
||||
|
||||
Test("AB_C_DE", "A_B_D_E",
|
||||
"A_B_C_D_E",
|
||||
" _ _L_ _ ")
|
||||
.changes(del(1, 2, 1))
|
||||
.runRight()
|
||||
|
||||
Test("AB_DE", "A_B_C_D_E",
|
||||
"AB_C_DE",
|
||||
" _R_ ")
|
||||
.changes(ins(1, 2, 1))
|
||||
.runLeft()
|
||||
|
||||
Test("AB_DE", "A_B_C_D_E",
|
||||
"A_B_C_D_E",
|
||||
" _ _R_ _ ")
|
||||
.changes(ins(1, 2, 1))
|
||||
.runRight()
|
||||
}
|
||||
|
||||
fun testFirstLineChange() {
|
||||
val builder = createBuilder("X\nB\nC", "A\nB\nC", Side.RIGHT)
|
||||
private inner class Test(val input1: String, val input2: String,
|
||||
val result: String,
|
||||
val lineMapping: String) {
|
||||
private var customFragments: List<LineFragment>? = null
|
||||
|
||||
assertFalse(builder.isEqual)
|
||||
assertEquals(builder.text.toString(), "X\nA\nB\nC\n")
|
||||
assertEquals(builder.changedLines, listOf(LineRange(0, 1), LineRange(1, 2)))
|
||||
fun runLeft() {
|
||||
doRun(Side.LEFT)
|
||||
}
|
||||
|
||||
assertEquals(builder.blocks.size, 1)
|
||||
val block = builder.blocks[0]
|
||||
assertEquals(block.line1, 0)
|
||||
assertEquals(block.line2, 2)
|
||||
assertEquals(block.range1.start, 0)
|
||||
assertEquals(block.range1.end, 1)
|
||||
assertEquals(block.range2.start, 1)
|
||||
assertEquals(block.range2.end, 2)
|
||||
fun runRight() {
|
||||
doRun(Side.RIGHT)
|
||||
}
|
||||
|
||||
fun run() {
|
||||
doRun(Side.LEFT, Side.RIGHT)
|
||||
}
|
||||
|
||||
private fun doRun(vararg sides: Side) {
|
||||
sides.forEach { side ->
|
||||
assert(result.length == lineMapping.length)
|
||||
|
||||
val text1 = processText(input1)
|
||||
val text2 = processText(input2)
|
||||
|
||||
val fragments = if (customFragments != null) customFragments!!
|
||||
else MANAGER.compareLines(text1, text2, ComparisonPolicy.DEFAULT, INDICATOR)
|
||||
|
||||
val builder = UnifiedFragmentBuilder(fragments, DocumentImpl(text1), DocumentImpl(text2), side)
|
||||
builder.exec()
|
||||
|
||||
|
||||
val lineCount1 = input1.count({ it == '_' }) + 1
|
||||
val lineCount2 = input2.count({ it == '_' }) + 1
|
||||
val resultLineCount = result.count({ it == '_' }) + 1
|
||||
val lineIterable = DiffIterableUtil.create(fragments.map { Range(it.startLine1, it.endLine1, it.startLine2, it.endLine2) },
|
||||
lineCount1, lineCount2)
|
||||
|
||||
val expectedText = processText(result)
|
||||
val actualText = processActualText(builder)
|
||||
|
||||
val expectedMapping = processExpectedLineMapping(lineMapping)
|
||||
val actualMapping = processActualLineMapping(builder.blocks, resultLineCount)
|
||||
|
||||
val expectedChangedLines = processExpectedChangedLines(lineMapping)
|
||||
val actualChangedLines = processActualChangedLines(builder.changedLines)
|
||||
|
||||
val expectedMappedLines1 = processExpectedMappedLines(lineIterable, Side.LEFT)
|
||||
val expectedMappedLines2 = processExpectedMappedLines(lineIterable, Side.RIGHT)
|
||||
val actualMappedLines1 = processActualMappedLines(builder.convertor1, resultLineCount)
|
||||
val actualMappedLines2 = processActualMappedLines(builder.convertor2, resultLineCount)
|
||||
|
||||
assertEquals(expectedText, actualText)
|
||||
assertEquals(expectedMapping, actualMapping)
|
||||
assertEquals(expectedChangedLines, actualChangedLines)
|
||||
|
||||
if (customFragments == null) {
|
||||
assertEquals(expectedMappedLines1, actualMappedLines1)
|
||||
assertEquals(expectedMappedLines2, actualMappedLines2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun changes(vararg ranges: Range): Test {
|
||||
customFragments = ranges.map {
|
||||
LineFragmentImpl(it.start1, it.end1, it.start2, it.end2,
|
||||
-1, -1, -1, -1)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun processText(text: String): String {
|
||||
return text.filterNot { it == '.' }.replace('_', '\n')
|
||||
}
|
||||
|
||||
private fun processActualText(builder: UnifiedFragmentBuilder): String {
|
||||
return builder.text.toString().removeSuffix("\n")
|
||||
}
|
||||
|
||||
private fun processExpectedLineMapping(lineMapping: String): LineMapping {
|
||||
val leftSet = BitSet()
|
||||
val rightSet = BitSet()
|
||||
val unchangedSet = BitSet()
|
||||
|
||||
lineMapping.split('_').forEachIndexed { index, line ->
|
||||
if (!line.isEmpty()) {
|
||||
val left = line.all { it == 'L' }
|
||||
val right = line.all { it == 'R' }
|
||||
val unchanged = line.all { it == ' ' }
|
||||
|
||||
if (left) leftSet.set(index)
|
||||
else if (right) rightSet.set(index)
|
||||
else if (unchanged) unchangedSet.set(index)
|
||||
else TestCase.fail()
|
||||
}
|
||||
}
|
||||
|
||||
return LineMapping(leftSet, rightSet, unchangedSet)
|
||||
}
|
||||
|
||||
private fun processActualLineMapping(blocks: List<ChangedBlock>, lineCount: Int): LineMapping {
|
||||
val leftSet = BitSet()
|
||||
val rightSet = BitSet()
|
||||
val unchangedSet = BitSet()
|
||||
|
||||
blocks.forEach {
|
||||
leftSet.set(it.range1.start, it.range1.end)
|
||||
rightSet.set(it.range2.start, it.range2.end)
|
||||
}
|
||||
|
||||
unchangedSet.set(0, lineCount)
|
||||
unchangedSet.andNot(leftSet)
|
||||
unchangedSet.andNot(rightSet)
|
||||
|
||||
return LineMapping(leftSet, rightSet, unchangedSet)
|
||||
}
|
||||
|
||||
private fun processExpectedChangedLines(lineMapping: String): BitSet {
|
||||
val expectedMapping = processExpectedLineMapping(lineMapping)
|
||||
val result = BitSet()
|
||||
result.or(expectedMapping.left)
|
||||
result.or(expectedMapping.right)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun processActualChangedLines(changedRanges: List<LineRange>): BitSet {
|
||||
val result = BitSet()
|
||||
changedRanges.forEach {
|
||||
result.set(it.start, it.end)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun processExpectedMappedLines(iterable: DiffIterable, side: Side): BitSet {
|
||||
val result = BitSet()
|
||||
DiffIterableUtil.iterateAll(iterable).forEach { pair ->
|
||||
val range = pair.first
|
||||
val start = side.select(range.start1, range.start2)
|
||||
val end = side.select(range.end1, range.end2)
|
||||
result.set(start, end)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun processActualMappedLines(convertor: LineNumberConvertor, lineCount: Int): BitSet {
|
||||
val result = BitSet()
|
||||
for (i in -5..lineCount + 5) {
|
||||
val line = convertor.convert(i)
|
||||
if (line != -1) {
|
||||
if (result[line]) TestCase.fail()
|
||||
result.set(line)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
fun testDeletion() {
|
||||
val builder = createBuilder("A\n", "", Side.LEFT)
|
||||
|
||||
assertFalse(builder.isEqual)
|
||||
assertEquals(builder.text.toString(), "A\n\n")
|
||||
assertEquals(builder.changedLines, listOf(LineRange(0, 1)))
|
||||
|
||||
assertEquals(builder.blocks.size, 1)
|
||||
val block = builder.blocks[0]
|
||||
assertEquals(block.line1, 0)
|
||||
assertEquals(block.line2, 1)
|
||||
assertEquals(block.range1.start, 0)
|
||||
assertEquals(block.range1.end, 1)
|
||||
assertEquals(block.range2.start, 1)
|
||||
assertEquals(block.range2.end, 1)
|
||||
private fun mod(line1: Int, line2: Int, count1: Int, count2: Int): Range {
|
||||
assert(count1 != 0)
|
||||
assert(count2 != 0)
|
||||
return Range(line1, line1 + count1, line2, line2 + count2)
|
||||
}
|
||||
|
||||
|
||||
private fun createBuilder(text1: String, text2: String, side: Side): UnifiedFragmentBuilder {
|
||||
val document1 = DocumentImpl(text1)
|
||||
val document2 = DocumentImpl(text2)
|
||||
|
||||
val fragments = MANAGER.compareLinesInner(document1.charsSequence, document2.charsSequence,
|
||||
ComparisonPolicy.DEFAULT, DumbProgressIndicator.INSTANCE)
|
||||
|
||||
val builder = UnifiedFragmentBuilder(fragments, document1, document2, side)
|
||||
builder.exec()
|
||||
|
||||
return builder
|
||||
private fun del(line1: Int, line2: Int, count1: Int): Range {
|
||||
assert(count1 != 0)
|
||||
return Range(line1, line1 + count1, line2, line2)
|
||||
}
|
||||
|
||||
private fun ins(line1: Int, line2: Int, count2: Int): Range {
|
||||
assert(count2 != 0)
|
||||
return Range(line1, line1, line2, line2 + count2)
|
||||
}
|
||||
|
||||
private data class LineMapping(val left: BitSet, val right: BitSet, val unchanged: BitSet)
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public interface PrePushHandler {
|
||||
String getPresentableName();
|
||||
|
||||
/**
|
||||
* Check synchronously if the push operation should be performed or canceled for specified {@link PushDetail}s
|
||||
* Check synchronously if the push operation should be performed or canceled for specified {@link PushInfo}s
|
||||
* <p>
|
||||
* Note: it is permissible for a handler to show it's own modal dialogs with specifying
|
||||
* the supplied {@code indicator}'s {@link ProgressIndicator#getModalityState() modality} state.
|
||||
@@ -70,6 +70,6 @@ public interface PrePushHandler {
|
||||
*/
|
||||
@CalledInAny
|
||||
@NotNull
|
||||
Result handle(@NotNull List<PushDetail> pushDetails, @NotNull ProgressIndicator indicator);
|
||||
Result handle(@NotNull List<PushInfo> pushDetails, @NotNull ProgressIndicator indicator);
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user