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:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,21 +22,16 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public class InstructionParser {
|
||||
private final byte[] myCode;
|
||||
private final long myCurrentInstructionIndex;
|
||||
private final long myStopOffset;
|
||||
|
||||
public InstructionParser(byte[] code, long instructionIndex) {
|
||||
public InstructionParser(byte[] code, long stopOffset) {
|
||||
myCode = code;
|
||||
myCurrentInstructionIndex = instructionIndex;
|
||||
myStopOffset = stopOffset;
|
||||
}
|
||||
|
||||
public void parse() {
|
||||
final int codeEnd = myCode.length;
|
||||
int v = 0;
|
||||
int instructionIndex = 0;
|
||||
while (v < codeEnd) {
|
||||
if (instructionIndex++ >= myCurrentInstructionIndex) {
|
||||
break;
|
||||
}
|
||||
while (v < myStopOffset) {
|
||||
int opcode = myCode[v] & 0xFF;
|
||||
final byte opcodeType = opcode == Bytecodes.IMPDEP1 || opcode == Bytecodes.IMPDEP2? Bytecodes.NOARG_INSN : Bytecodes.TYPE[opcode];
|
||||
switch (opcodeType) {
|
||||
|
||||
@@ -242,9 +242,8 @@ public class FrameVariablesTree extends DebuggerTree {
|
||||
final byte[] bytecodes = method.bytecodes();
|
||||
if (bytecodes != null && bytecodes.length > 0) {
|
||||
final int firstLocalVariableSlot = ArgumentValueDescriptorImpl.getFirstLocalsSlot(method);
|
||||
final long instructionIndex = location.codeIndex();
|
||||
final TIntObjectHashMap<DecompiledLocalVariable> usedVars = new TIntObjectHashMap<DecompiledLocalVariable>();
|
||||
new InstructionParser(bytecodes, instructionIndex) {
|
||||
new InstructionParser(bytecodes, location.codeIndex()) {
|
||||
@Override
|
||||
protected void localVariableInstructionFound(int opcode, int slot, String typeSignature) {
|
||||
if (slot >= firstLocalVariableSlot) {
|
||||
|
||||
+10
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -161,9 +161,15 @@ public class ArgumentValueDescriptorImpl extends ValueDescriptorImpl{
|
||||
}
|
||||
|
||||
public void visitSynchronizedStatement(PsiSynchronizedStatement statement) {
|
||||
appendName("<monitor>");
|
||||
myCurrentSlotIndex++;
|
||||
super.visitSynchronizedStatement(statement);
|
||||
myIndexStack.push(myCurrentSlotIndex);
|
||||
try {
|
||||
appendName("<monitor>");
|
||||
myCurrentSlotIndex++;
|
||||
super.visitSynchronizedStatement(statement);
|
||||
}
|
||||
finally {
|
||||
myCurrentSlotIndex = myIndexStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
private void appendName(String varName) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -542,65 +542,60 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM
|
||||
notifyAfterAnnotationChanging(listOwner, annotationFQName, false);
|
||||
return;
|
||||
}
|
||||
CommandProcessor.getInstance().executeCommand(myPsiManager.getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final XmlDocument document = xmlFile.getDocument();
|
||||
if (document != null) {
|
||||
final XmlTag rootTag = document.getRootTag();
|
||||
final String externalName = getExternalName(listOwner, false);
|
||||
if (externalName == null) {
|
||||
LOG.info("member without external name: " + listOwner);
|
||||
}
|
||||
if (rootTag != null && externalName != null) {
|
||||
XmlTag anchor = null;
|
||||
for (XmlTag item : rootTag.getSubTags()) {
|
||||
int compare = Comparing.compare(externalName, StringUtil.unescapeXml(item.getAttributeValue("name")));
|
||||
try {
|
||||
final XmlDocument document = xmlFile.getDocument();
|
||||
if (document != null) {
|
||||
final XmlTag rootTag = document.getRootTag();
|
||||
final String externalName = getExternalName(listOwner, false);
|
||||
if (externalName == null) {
|
||||
LOG.info("member without external name: " + listOwner);
|
||||
}
|
||||
if (rootTag != null && externalName != null) {
|
||||
XmlTag anchor = null;
|
||||
for (XmlTag item : rootTag.getSubTags()) {
|
||||
int compare = Comparing.compare(externalName, StringUtil.unescapeXml(item.getAttributeValue("name")));
|
||||
if (compare == 0) {
|
||||
anchor = null;
|
||||
for (XmlTag annotation : item.getSubTags()) {
|
||||
compare = Comparing.compare(annotationFQName, annotation.getAttributeValue("name"));
|
||||
if (compare == 0) {
|
||||
anchor = null;
|
||||
for (XmlTag annotation : item.getSubTags()) {
|
||||
compare = Comparing.compare(annotationFQName, annotation.getAttributeValue("name"));
|
||||
if (compare == 0) {
|
||||
annotation.delete();
|
||||
break;
|
||||
}
|
||||
anchor = annotation;
|
||||
}
|
||||
XmlTag newTag = XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText(
|
||||
createAnnotationTag(annotationFQName, values));
|
||||
item.addAfter(newTag, anchor);
|
||||
commitChanges(xmlFile);
|
||||
notifyAfterAnnotationChanging(listOwner, annotationFQName, true);
|
||||
return;
|
||||
annotation.delete();
|
||||
break;
|
||||
}
|
||||
if (compare < 0) break;
|
||||
anchor = item;
|
||||
anchor = annotation;
|
||||
}
|
||||
@NonNls String text =
|
||||
"<item name=\'" + StringUtil.escapeXml(externalName) + "\'>\n";
|
||||
text += createAnnotationTag(annotationFQName, values);
|
||||
text += "</item>";
|
||||
rootTag.addAfter(XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText(text), anchor);
|
||||
XmlTag newTag = XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText(
|
||||
createAnnotationTag(annotationFQName, values));
|
||||
item.addAfter(newTag, anchor);
|
||||
commitChanges(xmlFile);
|
||||
notifyAfterAnnotationChanging(listOwner, annotationFQName, true);
|
||||
return;
|
||||
}
|
||||
if (compare < 0) break;
|
||||
anchor = item;
|
||||
}
|
||||
notifyAfterAnnotationChanging(listOwner, annotationFQName, false);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
notifyAfterAnnotationChanging(listOwner, annotationFQName, false);
|
||||
}
|
||||
finally {
|
||||
dropCache();
|
||||
if (codeUsageFile.getVirtualFile().isInLocalFileSystem()) {
|
||||
UndoUtil.markPsiFileForUndo(codeUsageFile);
|
||||
}
|
||||
@NonNls String text =
|
||||
"<item name=\'" + StringUtil.escapeXml(externalName) + "\'>\n";
|
||||
text += createAnnotationTag(annotationFQName, values);
|
||||
text += "</item>";
|
||||
rootTag.addAfter(XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText(text), anchor);
|
||||
commitChanges(xmlFile);
|
||||
notifyAfterAnnotationChanging(listOwner, annotationFQName, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, ExternalAnnotationsManagerImpl.class.getName(), null);
|
||||
notifyAfterAnnotationChanging(listOwner, annotationFQName, false);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
notifyAfterAnnotationChanging(listOwner, annotationFQName, false);
|
||||
}
|
||||
finally {
|
||||
dropCache();
|
||||
if (codeUsageFile.getVirtualFile().isInLocalFileSystem()) {
|
||||
UndoUtil.markPsiFileForUndo(codeUsageFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void sortItems(@NotNull XmlFile xmlFile) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -100,6 +100,17 @@ public abstract class PsiElementFinder {
|
||||
return PsiClass.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filter to exclude classes, for example derived classes.
|
||||
*
|
||||
* @param scope the scope in which classes are searched.
|
||||
* @return the filter to use, or null if no additional filtering is necessary
|
||||
*/
|
||||
@Nullable
|
||||
public Condition<PsiClass> getClassesFilter(@NotNull GlobalSearchScope scope) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of files belonging to the specified package which are not located in any of the package directories.
|
||||
*
|
||||
|
||||
@@ -115,34 +115,23 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
if (myArgumentList == null || !PsiUtil.isLanguageLevel8OrHigher(myArgumentList)) {
|
||||
return getApplicabilityLevel();
|
||||
}
|
||||
@ApplicabilityLevelConstant int level;
|
||||
final PsiSubstitutor substitutor = getSubstitutor(false);
|
||||
Map<PsiElement, CurrentCandidateProperties> map = CURRENT_CANDIDATE.get();
|
||||
if (map == null) {
|
||||
map = ContainerUtil.createConcurrentWeakMap();
|
||||
CURRENT_CANDIDATE.set(map);
|
||||
}
|
||||
final PsiMethod method = getElement();
|
||||
final CurrentCandidateProperties properties = new CurrentCandidateProperties(method, substitutor, isVarargs(), true);
|
||||
final CurrentCandidateProperties alreadyThere = map.put(getMarkerList(), properties);
|
||||
try {
|
||||
PsiType[] argumentTypes = getArgumentTypes();
|
||||
if (argumentTypes == null) {
|
||||
return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
@ApplicabilityLevelConstant int level = computeForOverloadedCandidate(new Computable<Integer>() {
|
||||
@Override
|
||||
public Integer compute() {
|
||||
PsiType[] argumentTypes = getArgumentTypes();
|
||||
if (argumentTypes == null) {
|
||||
return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
|
||||
level = PsiUtil.getApplicabilityLevel(method, substitutor, argumentTypes, myLanguageLevel);
|
||||
if (!isVarargs() && level < ApplicabilityLevel.FIXED_ARITY) {
|
||||
return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
int level = PsiUtil.getApplicabilityLevel(method, substitutor, argumentTypes, myLanguageLevel);
|
||||
if (!isVarargs() && level < ApplicabilityLevel.FIXED_ARITY) {
|
||||
return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
return level;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (alreadyThere == null) {
|
||||
map.remove(getMarkerList());
|
||||
} else {
|
||||
map.put(getMarkerList(), alreadyThere);
|
||||
}
|
||||
}
|
||||
}, substitutor);
|
||||
if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable(new Computable<PsiSubstitutor>() {
|
||||
@Override
|
||||
public PsiSubstitutor compute() {
|
||||
@@ -154,6 +143,34 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
return level;
|
||||
}
|
||||
|
||||
public PsiType[] getPertinentArgumentTypes() {
|
||||
return computeForOverloadedCandidate(new Computable<PsiType[]>() {
|
||||
public PsiType[] compute() {
|
||||
return getArgumentTypes();
|
||||
}
|
||||
}, getSubstitutor(false));
|
||||
}
|
||||
|
||||
private <T> T computeForOverloadedCandidate(final Computable<T> computable, final PsiSubstitutor substitutor) {
|
||||
Map<PsiElement, CurrentCandidateProperties> map = CURRENT_CANDIDATE.get();
|
||||
if (map == null) {
|
||||
map = ContainerUtil.createConcurrentWeakMap();
|
||||
CURRENT_CANDIDATE.set(map);
|
||||
}
|
||||
final CurrentCandidateProperties alreadyThere = map.put(getMarkerList(),
|
||||
new CurrentCandidateProperties(getElement(), substitutor, isVarargs(), true));
|
||||
try {
|
||||
return computable.compute();
|
||||
}
|
||||
finally {
|
||||
if (alreadyThere == null) {
|
||||
map.remove(getMarkerList());
|
||||
} else {
|
||||
map.put(getMarkerList(), alreadyThere);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiSubstitutor getSiteSubstitutor() {
|
||||
PsiSubstitutor incompleteSubstitutor = super.getSubstitutor();
|
||||
|
||||
@@ -735,7 +735,12 @@ public class ControlFlowUtil {
|
||||
if (lastInstruction instanceof GoToInstruction &&
|
||||
((GoToInstruction)lastInstruction).role == BranchingInstruction.Role.END &&
|
||||
!((GoToInstruction)lastInstruction).isReturn) {
|
||||
lastOffset--;
|
||||
if (((GoToInstruction)lastInstruction).offset == startOffset) {
|
||||
lastOffset = -1;
|
||||
}
|
||||
else {
|
||||
lastOffset--;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastOffset >= 0) {
|
||||
|
||||
@@ -35,11 +35,11 @@ import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.ConcurrencyUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.util.*;
|
||||
@@ -95,9 +95,14 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (PsiElementFinder finder : finders()) {
|
||||
PsiElementFinder[] finders = finders();
|
||||
Condition<PsiClass> classesFilter = getFilterFromFinders(scope, finders);
|
||||
|
||||
for (PsiElementFinder finder : finders) {
|
||||
PsiClass aClass = finder.findClass(qualifiedName, scope);
|
||||
if (aClass != null) return aClass;
|
||||
if (aClass != null && (classesFilter == null || classesFilter.value(aClass))) {
|
||||
return aClass;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -131,13 +136,30 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
|
||||
return findClassesInDumbMode(qualifiedName, scope);
|
||||
}
|
||||
|
||||
List<PsiClass> classes = new SmartList<PsiClass>();
|
||||
for (PsiElementFinder finder : finders()) {
|
||||
PsiElementFinder[] finders = finders();
|
||||
Condition<PsiClass> classesFilter = getFilterFromFinders(scope, finders);
|
||||
|
||||
List<PsiClass> result = null;
|
||||
for (PsiElementFinder finder : finders) {
|
||||
PsiClass[] finderClasses = finder.findClasses(qualifiedName, scope);
|
||||
ContainerUtil.addAll(classes, finderClasses);
|
||||
if (finderClasses.length != 0) {
|
||||
if (result == null) result = new ArrayList<PsiClass>(finderClasses.length);
|
||||
filterClassesAndAppend(classesFilter, finderClasses, result);
|
||||
}
|
||||
}
|
||||
|
||||
return classes.toArray(new PsiClass[classes.size()]);
|
||||
return result == null || result.isEmpty() ? PsiClass.EMPTY_ARRAY : result.toArray(new PsiClass[result.size()]);
|
||||
}
|
||||
|
||||
private static Condition<PsiClass> getFilterFromFinders(@NotNull GlobalSearchScope scope, @NotNull PsiElementFinder[] finders) {
|
||||
Condition<PsiClass> filter = null;
|
||||
for (PsiElementFinder finder : finders) {
|
||||
Condition<PsiClass> finderFilter = finder.getClassesFilter(scope);
|
||||
if (finderFilter != null) {
|
||||
filter = filter == null ? finderFilter : Conditions.and(filter, finderFilter);
|
||||
}
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
private boolean shouldUseSlowResolve() {
|
||||
@@ -231,17 +253,35 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
|
||||
|
||||
@NotNull
|
||||
public PsiClass[] getClasses(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
PsiElementFinder[] finders = filteredFinders();
|
||||
Condition<PsiClass> classesFilter = getFilterFromFinders(scope, finders);
|
||||
|
||||
List<PsiClass> result = null;
|
||||
for (PsiElementFinder finder : filteredFinders()) {
|
||||
for (PsiElementFinder finder : finders) {
|
||||
PsiClass[] classes = finder.getClasses(psiPackage, scope);
|
||||
if (classes.length == 0) continue;
|
||||
if (result == null) result = new ArrayList<PsiClass>();
|
||||
ContainerUtil.addAll(result, classes);
|
||||
if (result == null) result = new ArrayList<PsiClass>(classes.length);
|
||||
filterClassesAndAppend(classesFilter, classes, result);
|
||||
}
|
||||
|
||||
return result == null ? PsiClass.EMPTY_ARRAY : result.toArray(new PsiClass[result.size()]);
|
||||
}
|
||||
|
||||
private static void filterClassesAndAppend(@Nullable Condition<PsiClass> classesFilter,
|
||||
@NotNull PsiClass[] classes,
|
||||
@NotNull List<PsiClass> result) {
|
||||
if (classesFilter == null) {
|
||||
ContainerUtil.addAll(result, classes);
|
||||
}
|
||||
else {
|
||||
for (PsiClass psiClass : classes) {
|
||||
if (classesFilter.value(psiClass)) {
|
||||
result.add(psiClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiFile[] getPackageFiles(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
Condition<PsiFile> filter = null;
|
||||
|
||||
@@ -50,6 +50,7 @@ import com.intellij.util.containers.MostlySingularMultiMap;
|
||||
import com.intellij.util.indexing.IndexingDataKeys;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -314,7 +315,12 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
final PsiElement resolved = statement.resolve();
|
||||
if (resolved instanceof PsiClass) {
|
||||
processor.handleEvent(JavaScopeProcessorEvent.SET_CURRENT_FILE_CONTEXT, statement);
|
||||
if (!processor.execute(resolved, state)) return false;
|
||||
final PsiClass containingClass = ((PsiClass)resolved).getContainingClass();
|
||||
if (containingClass != null && containingClass.hasTypeParameters()) {
|
||||
if (!processor.execute(resolved, state.put(PsiSubstitutor.KEY,
|
||||
createRawSubstitutor(containingClass)))) return false;
|
||||
}
|
||||
else if (!processor.execute(resolved, state)) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -385,6 +391,11 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiSubstitutor createRawSubstitutor(PsiClass containingClass) {
|
||||
return JavaPsiFacade.getElementFactory(containingClass.getProject()).createRawSubstitutor(containingClass);
|
||||
}
|
||||
|
||||
private static boolean processOnDemandTarget(PsiElement target, PsiScopeProcessor processor, ResolveState substitutor, PsiElement place) {
|
||||
if (target instanceof PsiPackage) {
|
||||
if (!target.processDeclarations(processor, substitutor, null, place)) {
|
||||
@@ -393,6 +404,10 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
}
|
||||
else if (target instanceof PsiClass) {
|
||||
PsiClass[] inners = ((PsiClass)target).getInnerClasses();
|
||||
if (((PsiClass)target).hasTypeParameters()) {
|
||||
substitutor = substitutor.put(PsiSubstitutor.KEY, createRawSubstitutor((PsiClass)target));
|
||||
}
|
||||
|
||||
for (PsiClass inner : inners) {
|
||||
if (!processor.execute(inner, substitutor)) return false;
|
||||
}
|
||||
@@ -494,8 +509,18 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
|
||||
@Override
|
||||
public boolean process(SymbolCollectingProcessor.ResultWithContext result) {
|
||||
myProcessor.handleEvent(JavaScopeProcessorEvent.SET_CURRENT_FILE_CONTEXT, result.getFileContext());
|
||||
return myProcessor.execute(result.getElement(), myState);
|
||||
final PsiElement context = result.getFileContext();
|
||||
myProcessor.handleEvent(JavaScopeProcessorEvent.SET_CURRENT_FILE_CONTEXT, context);
|
||||
final PsiNamedElement element = result.getElement();
|
||||
|
||||
if (element instanceof PsiClass && context instanceof PsiImportStatement) {
|
||||
final PsiClass containingClass = ((PsiClass)element).getContainingClass();
|
||||
if (containingClass != null && containingClass.hasTypeParameters()) {
|
||||
return myProcessor.execute(element, myState.put(PsiSubstitutor.KEY, createRawSubstitutor(containingClass)));
|
||||
}
|
||||
}
|
||||
|
||||
return myProcessor.execute(element, myState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-18
@@ -422,16 +422,6 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
(method.getCurrentFileResolveScope() instanceof PsiImportStaticStatement ? 0 : 1);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiType[] getActualParameterTypes() {
|
||||
PsiType[] types = myActualParameterTypes;
|
||||
if (types == null) {
|
||||
LOG.assertTrue(myArgumentsList instanceof PsiExpressionList, myArgumentsList);
|
||||
myActualParameterTypes = types = getArgumentTypes();
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
private int getActualParametersLength() {
|
||||
if (myActualParameterTypes == null) {
|
||||
LOG.assertTrue(myArgumentsList instanceof PsiExpressionList, myArgumentsList);
|
||||
@@ -440,11 +430,6 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return myActualParameterTypes.length;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected PsiType[] getArgumentTypes() {
|
||||
return ((PsiExpressionList)myArgumentsList).getExpressionTypes();
|
||||
}
|
||||
|
||||
private enum Specifics {
|
||||
FIRST,
|
||||
SECOND,
|
||||
@@ -509,20 +494,23 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
boolean sameBoxing = true;
|
||||
int[] boxingHappened = new int[2];
|
||||
final PsiType[] argTypes1 = myActualParameterTypes != null ? myActualParameterTypes : info1.getPertinentArgumentTypes();
|
||||
final PsiType[] argTypes2 = myActualParameterTypes != null ? myActualParameterTypes : info2.getPertinentArgumentTypes();
|
||||
for (int i = 0; i < types1.length; i++) {
|
||||
ProgressManager.checkCanceled();
|
||||
PsiType type1 = classSubstitutor1.substitute(types1[i]);
|
||||
PsiType type2 = classSubstitutor2.substitute(types2[i]);
|
||||
PsiType argType = i < getActualParameterTypes().length ? getActualParameterTypes()[i] : null;
|
||||
final PsiType argType1 = i < getActualParametersLength() ? argTypes1[i] : null;
|
||||
final PsiType argType2 = i < getActualParametersLength() ? argTypes2[i] : null;
|
||||
|
||||
boolean boxingInFirst = false;
|
||||
if (isBoxingHappened(argType, type1, languageLevel)) {
|
||||
if (isBoxingHappened(argType1, type1, languageLevel)) {
|
||||
boxingHappened[0] += 1;
|
||||
boxingInFirst = true;
|
||||
}
|
||||
|
||||
boolean boxingInSecond = false;
|
||||
if (isBoxingHappened(argType, type2, languageLevel)) {
|
||||
if (isBoxingHappened(argType2, type2, languageLevel)) {
|
||||
boxingHappened[1] += 1;
|
||||
boxingInSecond = true;
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package p;
|
||||
|
||||
import p2.GenericClass;
|
||||
|
||||
public class Class1 extends GenericClass<Integer> {
|
||||
public void map(InnerClass context) {
|
||||
Class2.test(context);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package p;
|
||||
|
||||
import p2.GenericClass.InnerClass;
|
||||
|
||||
public class Class2 {
|
||||
|
||||
public static boolean test(InnerClass context) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package p2;
|
||||
|
||||
public class GenericClass<T> {
|
||||
public class InnerClass {
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package p;
|
||||
|
||||
import p2.GenericClass;
|
||||
|
||||
public class Class1 extends GenericClass<Integer> {
|
||||
public void map(InnerClass context) {
|
||||
Class2.test(context);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package p;
|
||||
|
||||
import p2.GenericClass.*;
|
||||
|
||||
public class Class2 {
|
||||
|
||||
public static boolean test(InnerClass context) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package p2;
|
||||
|
||||
public class GenericClass<T> {
|
||||
public class InnerClass {
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
class Test {
|
||||
public static final void main(String[] args) throws Exception {
|
||||
Reader r = new StringReader("Elvis lives!");
|
||||
Callable<Integer > c1 = () -> {
|
||||
while (true) {
|
||||
r.read();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import java.lang.String;
|
||||
|
||||
abstract class Test {
|
||||
abstract <T> T get();
|
||||
|
||||
void foo() {
|
||||
String.valueOf(get());
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
Cleaning output files:
|
||||
out/production/ChangeLambdaSAMMethodSignature/ppp/Client.class
|
||||
out/production/ChangeLambdaSAMMethodSignature/ppp/DataProvider.class
|
||||
out/production/ChangeLambdaSAMMethodSignature/ppp/Repository.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/ppp/Client.java
|
||||
src/ppp/DataProvider.java
|
||||
src/ppp/Repository.java
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/ChangeLambdaSAMMethodSignature/ppp/Main.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/ppp/Main.java
|
||||
End of files
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ppp;
|
||||
public class Client {
|
||||
public void execute(DataProvider data) {
|
||||
for (String s : data.getData()) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ppp;
|
||||
public class Client {
|
||||
public void execute(DataProvider data) {
|
||||
for (String s : data.getData(10)) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package ppp;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface DataProvider {
|
||||
Collection<String> getData();
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package ppp;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface DataProvider {
|
||||
Collection<String> getData(int param);
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package ppp;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Repository repo = new Repository();
|
||||
Client client = new Client();
|
||||
client.execute(()-> repo.getStorages());
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package ppp;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Repository {
|
||||
public List<String> getStorages() {
|
||||
return Arrays.asList("a", "b", "c");
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package ppp;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Repository {
|
||||
public List<String> getStorages(int param) {
|
||||
return Arrays.asList("a", "b", "c");
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
Cleaning output files:
|
||||
out/production/ChangeLambdaTargetReturnType/ppp/Repository.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/ppp/Repository.java
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/ChangeLambdaTargetReturnType/ppp/Main.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/ppp/Main.java
|
||||
End of files
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ppp;
|
||||
public class Client {
|
||||
public void execute(DataProvider data) {
|
||||
for (String s : data.getData()) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package ppp;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface DataProvider {
|
||||
Collection<String> getData();
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package ppp;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Repository repo = new Repository();
|
||||
Client client = new Client();
|
||||
client.execute(()-> repo.getStorages());
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package ppp;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Repository {
|
||||
public List<String> getStorages() {
|
||||
return Arrays.asList("a", "b", "c");
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package ppp;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
public class Repository {
|
||||
public Collection<String> getStorages() {
|
||||
return Arrays.asList("a", "b", "c");
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
Cleaning output files:
|
||||
out/production/ChangeMethodRefReturnType/ppp/Repository.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/ppp/Repository.java
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/ChangeMethodRefReturnType/ppp/Main.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/ppp/Main.java
|
||||
End of files
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ppp;
|
||||
public class Client {
|
||||
public void execute(DataProvider data) {
|
||||
for (String s : data.getData()) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package ppp;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface DataProvider {
|
||||
Collection<String> getData();
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package ppp;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Repository repo = new Repository();
|
||||
Client client = new Client();
|
||||
client.execute(repo::getStorages);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package ppp;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Repository {
|
||||
public List<String> getStorages() {
|
||||
return Arrays.asList("a", "b", "c");
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package ppp;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
public class Repository {
|
||||
public Collection<String> getStorages() {
|
||||
return Arrays.asList("a", "b", "c");
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
Cleaning output files:
|
||||
out/production/ChangeSAMMethodSignature/ppp/Client.class
|
||||
out/production/ChangeSAMMethodSignature/ppp/DataProvider.class
|
||||
out/production/ChangeSAMMethodSignature/ppp/Repository.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/ppp/Client.java
|
||||
src/ppp/DataProvider.java
|
||||
src/ppp/Repository.java
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/ChangeSAMMethodSignature/ppp/Main.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/ppp/Main.java
|
||||
End of files
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ppp;
|
||||
public class Client {
|
||||
public void execute(DataProvider data) {
|
||||
for (String s : data.getData()) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ppp;
|
||||
public class Client {
|
||||
public void execute(DataProvider data) {
|
||||
for (String s : data.getData(10)) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package ppp;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface DataProvider {
|
||||
Collection<String> getData();
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package ppp;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface DataProvider {
|
||||
Collection<String> getData(int param);
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package ppp;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Repository repo = new Repository();
|
||||
Client client = new Client();
|
||||
client.execute(repo::getStorages);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package ppp;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Repository {
|
||||
public List<String> getStorages() {
|
||||
return Arrays.asList("a", "b", "c");
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package ppp;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Repository {
|
||||
public List<String> getStorages(int param) {
|
||||
return Arrays.asList("a", "b", "c");
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,14 @@ public class AdvHighlightingJdk7Test extends DaemonAnalyzerTestCase {
|
||||
doTest(BASE_PATH + "staticImportConflict/UsageMixed.java", BASE_PATH + "/staticImportConflict", false, false);
|
||||
}
|
||||
|
||||
public void testRawInnerClassImport() throws Exception {
|
||||
doTest(BASE_PATH + "raw/p/Class1.java", BASE_PATH + "/raw", false, false);
|
||||
}
|
||||
|
||||
public void testRawInnerClassImportOnDemand() throws Exception {
|
||||
doTest(BASE_PATH + "rawOnDemand/p/Class1.java", BASE_PATH + "/rawOnDemand", false, false);
|
||||
}
|
||||
|
||||
//ambiguous method calls
|
||||
private void doTestAmbiguous() throws Exception {
|
||||
doTestAmbiguous(JavaSdkVersion.JDK_1_7);
|
||||
|
||||
+4
@@ -185,6 +185,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInfiniteLoopAndValueCompatibility() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
+4
@@ -98,6 +98,10 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase {
|
||||
}).assertTiming();
|
||||
}
|
||||
|
||||
public void testMultipleOverloadsWithNestedGeneric() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,23 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.search;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.find.impl.FindInProjectUtil;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiClass;
|
||||
@@ -9,31 +26,15 @@ import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.testFramework.PsiTestCase;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.CommonProcessors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.*;
|
||||
|
||||
public class SearchInLibsTest extends PsiTestCase {
|
||||
public void testSearchInProject() throws Exception {
|
||||
doTest("ProjectClass", new String[]{"ProjectClass.java"}, GlobalSearchScope.projectScope(myProject));
|
||||
doTest("LibraryClass1", new String[]{"ProjectClass.java"}, GlobalSearchScope.projectScope(myProject));
|
||||
doTest("LibraryClass2", new String[]{}, GlobalSearchScope.projectScope(myProject));
|
||||
}
|
||||
|
||||
public void testSearchInLibs() throws Exception {
|
||||
doTest("ProjectClass", new String[]{"ProjectClass.java"}, GlobalSearchScope.allScope(myProject));
|
||||
doTest("LibraryClass1", new String[]{"LibraryClass2.java", "ProjectClass.java"}, GlobalSearchScope.allScope(myProject));
|
||||
doTest("LibraryClass2", new String[]{"LibraryClass1.java"}, GlobalSearchScope.allScope(myProject));
|
||||
}
|
||||
|
||||
public void testInnerSourceRoot() throws Exception {
|
||||
doTest("ProjectClass2", new String[]{"ProjectClass2.java"}, GlobalSearchScope.projectScope(myProject));
|
||||
}
|
||||
|
||||
private void doTest(String classNameToSearch, String[] expectedFileNames, SearchScope scope) throws Exception {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
String root = JavaTestUtil.getJavaTestDataPath() + "/psi/search/searchInLibs";
|
||||
VirtualFile rootFile = PsiTestUtil.createTestProjectStructure(myProject, myModule, root, myFilesToDelete, false);
|
||||
|
||||
@@ -52,15 +53,59 @@ public class SearchInLibsTest extends PsiTestCase {
|
||||
PsiTestUtil.addSourceRoot(myModule, projectRoot);
|
||||
PsiTestUtil.addSourceRoot(myModule, innerSourceRoot);
|
||||
ModuleRootModificationUtil.addModuleLibrary(myModule, "lib", Collections.singletonList(libClassesRoot.getUrl()), Collections.singletonList(libSrcRoot.getUrl()));
|
||||
}
|
||||
|
||||
public void testFindUsagesInProject() throws Exception {
|
||||
doTest("ProjectClass", new String[]{"ProjectClass.java"}, GlobalSearchScope.projectScope(myProject));
|
||||
}
|
||||
public void testFindUsagesInProject1() throws Exception {
|
||||
doTest("LibraryClass1", new String[]{"ProjectClass.java"}, GlobalSearchScope.projectScope(myProject));
|
||||
}
|
||||
public void testFindUsagesInProject2() throws Exception {
|
||||
doTest("LibraryClass2", new String[]{}, GlobalSearchScope.projectScope(myProject));
|
||||
}
|
||||
|
||||
public void testFindUsagesInLibs() throws Exception {
|
||||
doTest("ProjectClass", new String[]{"ProjectClass.java"}, GlobalSearchScope.allScope(myProject));
|
||||
}
|
||||
public void testFindUsagesInLibs1() throws Exception {
|
||||
doTest("LibraryClass1", new String[]{"LibraryClass2.java", "ProjectClass.java"}, GlobalSearchScope.allScope(myProject));
|
||||
}
|
||||
public void testFindUsagesInLibs2() throws Exception {
|
||||
doTest("LibraryClass2", new String[]{"LibraryClass1.java"}, GlobalSearchScope.allScope(myProject));
|
||||
}
|
||||
|
||||
public void testFindInPathInLibraryDirActuallySearchesInTheirSourcesToo() throws Exception {
|
||||
FindModel model = new FindModel();
|
||||
final PsiClass aClass = myJavaFacade.findClass("LibraryClass1");
|
||||
assertNotNull(aClass);
|
||||
model.setDirectoryName(aClass.getContainingFile().getContainingDirectory().getVirtualFile().getPath());
|
||||
model.setCaseSensitive(true);
|
||||
model.setCustomScope(false);
|
||||
model.setStringToFind("LibraryClass1");
|
||||
model.setProjectScope(false);
|
||||
|
||||
List<UsageInfo> usages = new ArrayList<UsageInfo>();
|
||||
FindInProjectUtil.findUsages(model, aClass.getContainingFile().getContainingDirectory(), getProject(),
|
||||
new CommonProcessors.CollectProcessor<UsageInfo>(
|
||||
usages), FindInProjectUtil
|
||||
.setupProcessPresentation(getProject(), false, FindInProjectUtil.setupViewPresentation(false, model)));
|
||||
|
||||
assertEquals(2, usages.size());
|
||||
}
|
||||
|
||||
public void testInnerSourceRoot() throws Exception {
|
||||
doTest("ProjectClass2", new String[]{"ProjectClass2.java"}, GlobalSearchScope.projectScope(myProject));
|
||||
}
|
||||
|
||||
private void doTest(String classNameToSearch, String[] expectedFileNames, SearchScope scope) throws Exception {
|
||||
final PsiClass aClass = myJavaFacade.findClass(classNameToSearch);
|
||||
assertNotNull(aClass);
|
||||
|
||||
PsiReference[] refs = ReferencesSearch.search(aClass, scope, false).toArray(new PsiReference[0]);
|
||||
|
||||
ArrayList<PsiFile> files = new ArrayList<PsiFile>();
|
||||
for (int i = 0; i < refs.length; i++) {
|
||||
PsiReference ref = refs[i];
|
||||
for (PsiReference ref : refs) {
|
||||
PsiFile file = ref.getElement().getContainingFile();
|
||||
if (!files.contains(file)) {
|
||||
files.add(file);
|
||||
@@ -69,19 +114,17 @@ public class SearchInLibsTest extends PsiTestCase {
|
||||
|
||||
assertEquals("files count", expectedFileNames.length, files.size());
|
||||
|
||||
Collections.sort(files, new Comparator() {
|
||||
Collections.sort(files, new Comparator<PsiFile>() {
|
||||
@Override
|
||||
public int compare(Object o1, Object o2) {
|
||||
PsiFile file1 = (PsiFile) o1;
|
||||
PsiFile file2 = (PsiFile) o2;
|
||||
return file1.getName().compareTo(file2.getName());
|
||||
public int compare(PsiFile o1, PsiFile o2) {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
}
|
||||
});
|
||||
Arrays.sort(expectedFileNames);
|
||||
|
||||
for (int i = 0; i < expectedFileNames.length; i++) {
|
||||
String name = expectedFileNames[i];
|
||||
PsiFile file = (PsiFile) files.get(i);
|
||||
PsiFile file = files.get(i);
|
||||
assertEquals(name, file.getName());
|
||||
}
|
||||
}
|
||||
|
||||
+113
-22
@@ -19,6 +19,7 @@ import com.intellij.openapi.util.Pair;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
import org.jetbrains.org.objectweb.asm.signature.SignatureReader;
|
||||
import org.jetbrains.org.objectweb.asm.signature.SignatureVisitor;
|
||||
@@ -34,6 +35,7 @@ import java.util.Set;
|
||||
*/
|
||||
|
||||
class ClassfileAnalyzer {
|
||||
public static final String LAMBDA_FACTORY_CLASS = "java/lang/invoke/LambdaMetafactory";
|
||||
private final DependencyContext myContext;
|
||||
|
||||
ClassfileAnalyzer(DependencyContext context) {
|
||||
@@ -390,11 +392,11 @@ class ClassfileAnalyzer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldVisitor visitField(int access, String n, String desc, String signature, Object value) {
|
||||
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
|
||||
processSignature(signature);
|
||||
|
||||
if ((access & Opcodes.ACC_SYNTHETIC) == 0) {
|
||||
myFields.add(new FieldRepr(myContext, access, myContext.get(n), myContext.get(desc), myContext.get(signature), value));
|
||||
myFields.add(new FieldRepr(myContext, access, myContext.get(name), myContext.get(desc), myContext.get(signature), value));
|
||||
}
|
||||
|
||||
return new FieldVisitor(Opcodes.ASM5) {
|
||||
@@ -504,34 +506,118 @@ class ClassfileAnalyzer {
|
||||
|
||||
@Override
|
||||
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
|
||||
final int fieldName = myContext.get(name);
|
||||
final int fieldOwner = myContext.get(owner);
|
||||
final int descr = myContext.get(desc);
|
||||
|
||||
if (opcode == Opcodes.PUTFIELD || opcode == Opcodes.PUTSTATIC) {
|
||||
myUsages.add(UsageRepr.createFieldAssignUsage(myContext, fieldName, fieldOwner, descr));
|
||||
}
|
||||
|
||||
if (opcode == Opcodes.GETFIELD || opcode == Opcodes.GETSTATIC) {
|
||||
addClassUsage(TypeRepr.getType(myContext, descr));
|
||||
}
|
||||
|
||||
myUsages.add(UsageRepr.createFieldUsage(myContext, fieldName, fieldOwner, descr));
|
||||
registerFieldUsage(opcode, owner, name, desc);
|
||||
super.visitFieldInsn(opcode, owner, name, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
|
||||
final int methodName = myContext.get(name);
|
||||
final int methodOwner = myContext.get(owner);
|
||||
|
||||
myUsages.add(UsageRepr.createMethodUsage(myContext, methodName, methodOwner, desc));
|
||||
myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, methodOwner));
|
||||
addClassUsage(TypeRepr.getType(myContext, Type.getReturnType(desc)));
|
||||
|
||||
registerMethodUsage(owner, name, desc);
|
||||
super.visitMethodInsn(opcode, owner, name, desc, itf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInvokeDynamicInsn(String methodName, String desc, Handle bsm, Object... bsmArgs) {
|
||||
final Type returnType = Type.getReturnType(desc);
|
||||
addClassUsage(TypeRepr.getType(myContext, returnType));
|
||||
|
||||
// common args processing
|
||||
for (Object arg : bsmArgs) {
|
||||
if (arg instanceof Type) {
|
||||
final Type type = (Type)arg;
|
||||
if (type.getSort() == Type.METHOD) {
|
||||
for (Type argType : type.getArgumentTypes()) {
|
||||
addClassUsage(TypeRepr.getType(myContext, argType));
|
||||
}
|
||||
addClassUsage(TypeRepr.getType(myContext, type.getReturnType()));
|
||||
}
|
||||
else {
|
||||
addClassUsage(TypeRepr.getType(myContext, type));
|
||||
}
|
||||
}
|
||||
else if (arg instanceof Handle) {
|
||||
processMethodHandle((Handle)arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (LAMBDA_FACTORY_CLASS.equals(bsm.getOwner())) {
|
||||
// This invokeDynamic implements a lambda or method reference usage.
|
||||
// Need to register method usage for the corresponding SAM-type.
|
||||
// First three arguments to the bootstrap methods are provided automatically by VM.
|
||||
// Arguments in args array are expected to be as following:
|
||||
// [0]: Type: Signature and return type of method to be implemented by the function object.
|
||||
// [1]: Handle: implementation method handle
|
||||
// [2]: Type: The signature and return type that should be enforced dynamically at invocation time. May be the same as samMethodType, or may be a specialization of it
|
||||
// [...]: optional additional arguments
|
||||
|
||||
if (returnType.getSort() == Type.OBJECT && bsmArgs.length >= 3) {
|
||||
if (bsmArgs[0] instanceof Type) {
|
||||
final Type samMethodType = (Type)bsmArgs[0];
|
||||
if (samMethodType.getSort() == Type.METHOD) {
|
||||
registerMethodUsage(returnType.getInternalName(), methodName, samMethodType.getDescriptor());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.visitInvokeDynamicInsn(methodName, desc, bsm, bsmArgs);
|
||||
}
|
||||
|
||||
private void processMethodHandle(Handle handle) {
|
||||
final String memberOwner = handle.getOwner();
|
||||
if (myContext.get(memberOwner) != myName) {
|
||||
// do not register access to own class members
|
||||
final String memberName = handle.getName();
|
||||
final String memberDescriptor = handle.getDesc();
|
||||
if (isFieldAccessHandle(handle)) {
|
||||
final int tag = handle.getTag();
|
||||
int opCode;
|
||||
if (tag == Opcodes.H_GETFIELD) {
|
||||
opCode = Opcodes.GETFIELD;
|
||||
}
|
||||
else if (tag == Opcodes.H_GETSTATIC) {
|
||||
opCode = Opcodes.GETSTATIC;
|
||||
}
|
||||
else if (tag == Opcodes.H_PUTFIELD) {
|
||||
opCode = Opcodes.PUTFIELD;
|
||||
}
|
||||
else if (tag == Opcodes.H_PUTSTATIC) {
|
||||
opCode = Opcodes.PUTSTATIC;
|
||||
}
|
||||
else {
|
||||
opCode = Opcodes.H_GETFIELD;
|
||||
}
|
||||
registerFieldUsage(opCode, memberOwner, memberName, memberDescriptor);
|
||||
}
|
||||
else {
|
||||
registerMethodUsage(memberOwner, memberName, memberDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerFieldUsage(int opcode, String owner, String fName, String desc) {
|
||||
final int fieldName = myContext.get(fName);
|
||||
final int fieldOwner = myContext.get(owner);
|
||||
final int descr = myContext.get(desc);
|
||||
if (opcode == Opcodes.PUTFIELD || opcode == Opcodes.PUTSTATIC) {
|
||||
myUsages.add(UsageRepr.createFieldAssignUsage(myContext, fieldName, fieldOwner, descr));
|
||||
}
|
||||
if (opcode == Opcodes.GETFIELD || opcode == Opcodes.GETSTATIC) {
|
||||
addClassUsage(TypeRepr.getType(myContext, descr));
|
||||
}
|
||||
myUsages.add(UsageRepr.createFieldUsage(myContext, fieldName, fieldOwner, descr));
|
||||
}
|
||||
|
||||
private void registerMethodUsage(String owner, String name, @Nullable String desc) {
|
||||
final int methodOwner = myContext.get(owner);
|
||||
final int methodName = myContext.get(name);
|
||||
myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, methodOwner));
|
||||
if (desc != null) {
|
||||
myUsages.add(UsageRepr.createMethodUsage(myContext, methodName, methodOwner, desc));
|
||||
addClassUsage(TypeRepr.getType(myContext, Type.getReturnType(desc)));
|
||||
}
|
||||
}
|
||||
|
||||
private void addClassUsage(final TypeRepr.AbstractType type) {
|
||||
TypeRepr.ClassType classType = null;
|
||||
if (type instanceof TypeRepr.ClassType) {
|
||||
@@ -551,6 +637,11 @@ class ClassfileAnalyzer {
|
||||
};
|
||||
}
|
||||
|
||||
private boolean isFieldAccessHandle(Handle handle) {
|
||||
final int tag = handle.getTag();
|
||||
return tag == Opcodes.H_GETFIELD || tag == Opcodes.H_GETSTATIC || tag == Opcodes.H_PUTFIELD || tag == Opcodes.H_PUTSTATIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInnerClass(String name, String outerName, String innerName, int access) {
|
||||
if (outerName != null) {
|
||||
|
||||
@@ -37,7 +37,9 @@ import org.jetbrains.jps.model.module.JpsModule;
|
||||
import org.jetbrains.jps.model.serialization.PathMacroUtil;
|
||||
import org.jetbrains.jps.util.JpsPathUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author db
|
||||
@@ -212,6 +214,20 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase {
|
||||
module.addSourceRoot(getUrl(testRootRelativePath), JavaSourceRootType.TEST_SOURCE);
|
||||
}
|
||||
|
||||
protected static boolean isRunningOnAtLeastJava(int javaVersion) {
|
||||
final String versionString = System.getProperty("java.version");
|
||||
final String prefix = "1.";
|
||||
final int startIndex = versionString.startsWith(prefix) ? prefix.length() : 0;
|
||||
final int dotIndex = versionString.indexOf('.', startIndex);
|
||||
try {
|
||||
int version = Integer.parseInt(versionString.substring(startIndex, dotIndex > startIndex? dotIndex : versionString.length()));
|
||||
return version >= javaVersion;
|
||||
}
|
||||
catch (NumberFormatException ignored) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class StringProjectBuilderLogger extends ProjectBuilderLoggerBase {
|
||||
private final String myRoot;
|
||||
private StringBuilder myLog;
|
||||
|
||||
@@ -32,6 +32,42 @@ public class MethodPropertyTest extends IncrementalTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testChangeMethodRefReturnType() throws Exception {
|
||||
if (isRunningOnAtLeastJava(8)) {
|
||||
doTest();
|
||||
}
|
||||
else {
|
||||
System.err.println("Skipping test " + getTestName(true) + ": java version 8 or higher required to run it");
|
||||
}
|
||||
}
|
||||
|
||||
public void testChangeLambdaTargetReturnType() throws Exception {
|
||||
if (isRunningOnAtLeastJava(8)) {
|
||||
doTest();
|
||||
}
|
||||
else {
|
||||
System.err.println("Skipping test " + getTestName(true) + ": java version 8 or higher required to run it");
|
||||
}
|
||||
}
|
||||
|
||||
public void testChangeSAMMethodSignature() throws Exception {
|
||||
if (isRunningOnAtLeastJava(8)) {
|
||||
doTest();
|
||||
}
|
||||
else {
|
||||
System.err.println("Skipping test " + getTestName(true) + ": java version 8 or higher required to run it");
|
||||
}
|
||||
}
|
||||
|
||||
public void testChangeLambdaSAMMethodSignature() throws Exception {
|
||||
if (isRunningOnAtLeastJava(8)) {
|
||||
doTest();
|
||||
}
|
||||
else {
|
||||
System.err.println("Skipping test " + getTestName(true) + ": java version 8 or higher required to run it");
|
||||
}
|
||||
}
|
||||
|
||||
public void testChangeReturnType1() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@@ -19,9 +19,7 @@ package com.intellij.analysis;
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.daemon.ProblemHighlightFilter;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
@@ -177,6 +175,9 @@ public class AnalysisScope {
|
||||
protected PsiElementVisitor createFileSearcher() {
|
||||
final FileIndex fileIndex = getFileIndex();
|
||||
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (indicator != null) {
|
||||
indicator.setText(AnalysisScopeBundle.message("scanning.scope.progress.title"));
|
||||
}
|
||||
|
||||
return new PsiElementVisitor() {
|
||||
@Override
|
||||
@@ -191,12 +192,6 @@ public class AnalysisScope {
|
||||
}
|
||||
if (!shouldHighlightFile(file)) return;
|
||||
myFilesSet.add(virtualFile);
|
||||
if (indicator != null) {
|
||||
indicator.setText(AnalysisScopeBundle.message("scanning.scope.progress.title"));
|
||||
Project project = file.getProject();
|
||||
String text = displayProjectRelativePath(virtualFile, project);
|
||||
indicator.setText2(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -247,7 +242,7 @@ public class AnalysisScope {
|
||||
}
|
||||
else if (myType == DIRECTORY || myType == PROJECT || myType == MODULES || myType == MODULE || myType == CUSTOM) {
|
||||
myFilesSet = new HashSet<VirtualFile>();
|
||||
accept(createFileSearcher());
|
||||
accept(createFileSearcher(), false);
|
||||
}
|
||||
else if (myType == VIRTUAL_FILES) {
|
||||
myFilesSet = new HashSet<VirtualFile>();
|
||||
@@ -275,16 +270,23 @@ public class AnalysisScope {
|
||||
|
||||
|
||||
public void accept(@NotNull final PsiElementVisitor visitor) {
|
||||
accept(visitor, !ApplicationManager.getApplication().isReadAccessAllowed());
|
||||
accept(visitor, true);
|
||||
}
|
||||
|
||||
protected void accept(@NotNull final PsiElementVisitor visitor, final boolean needReadAction) {
|
||||
private void accept(@NotNull final PsiElementVisitor visitor, final boolean clearResolveCache) {
|
||||
final boolean needReadAction = !ApplicationManager.getApplication().isReadAccessAllowed();
|
||||
final PsiManager psiManager = PsiManager.getInstance(myProject);
|
||||
final FileIndex fileIndex = getFileIndex();
|
||||
accept(new Processor<VirtualFile>() {
|
||||
@Override
|
||||
public boolean process(VirtualFile file) {
|
||||
return processFile(file, visitor, fileIndex, psiManager, needReadAction);
|
||||
if (file.isDirectory()) return true;
|
||||
if (ProjectCoreUtil.isProjectOrWorkspaceFile(file)) return true;
|
||||
if (fileIndex.isInContent(file) && (myIncludeTestSource || !fileIndex.isInTestSourceContent(file))
|
||||
&& !isInGeneratedSources(file, myProject)) {
|
||||
return processFile(file, visitor, psiManager, needReadAction, clearResolveCache);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -375,20 +377,6 @@ public class AnalysisScope {
|
||||
});
|
||||
}
|
||||
|
||||
private boolean processFile(@NotNull final VirtualFile fileOrDir,
|
||||
@NotNull final PsiElementVisitor visitor,
|
||||
@NotNull final FileIndex fileIndex,
|
||||
@NotNull final PsiManager psiManager,
|
||||
final boolean needReadAction) {
|
||||
if (fileOrDir.isDirectory()) return true;
|
||||
if (ProjectCoreUtil.isProjectOrWorkspaceFile(fileOrDir)) return true;
|
||||
if (fileIndex.isInContent(fileOrDir) && (myIncludeTestSource || !fileIndex.isInTestSourceContent(fileOrDir))
|
||||
&& !isInGeneratedSources(fileOrDir, psiManager.getProject())) {
|
||||
return processFile(fileOrDir, visitor, psiManager, needReadAction);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isInGeneratedSources(@NotNull VirtualFile file, @NotNull Project project) {
|
||||
for (GeneratedSourcesFilter filter : GeneratedSourcesFilter.EP_NAME.getExtensions()) {
|
||||
if (filter.isGeneratedSource(file, project)) {
|
||||
@@ -398,32 +386,15 @@ public class AnalysisScope {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean processFile(@NotNull final VirtualFile fileOrDir,
|
||||
private static boolean processFile(@NotNull final VirtualFile vFile,
|
||||
@NotNull final PsiElementVisitor visitor,
|
||||
@NotNull final PsiManager psiManager,
|
||||
final boolean needReadAction) {
|
||||
final PsiFile file;
|
||||
|
||||
AccessToken accessToken = ReadAction.start();
|
||||
try {
|
||||
if (!fileOrDir.isValid()) return false;
|
||||
|
||||
file = psiManager.findFile(fileOrDir);
|
||||
if (file == null) {
|
||||
//skip .class files under src directory
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!shouldHighlightFile(file)) return true;
|
||||
}
|
||||
finally {
|
||||
accessToken.finish();
|
||||
}
|
||||
|
||||
final boolean needReadAction,
|
||||
final boolean clearResolveCache) {
|
||||
final Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doProcessFile(visitor, psiManager, file);
|
||||
doProcessFile(visitor, psiManager, vFile, clearResolveCache);
|
||||
}
|
||||
};
|
||||
if (needReadAction && !ApplicationManager.getApplication().isDispatchThread()) {
|
||||
@@ -471,10 +442,18 @@ public class AnalysisScope {
|
||||
}
|
||||
}
|
||||
|
||||
private static void doProcessFile(@NotNull PsiElementVisitor visitor, @NotNull PsiManager psiManager, @NotNull PsiFile file) {
|
||||
file.accept(visitor);
|
||||
psiManager.dropResolveCaches();
|
||||
InjectedLanguageManager.getInstance(file.getProject()).dropFileCaches(file);
|
||||
private static void doProcessFile(@NotNull PsiElementVisitor visitor, @NotNull PsiManager psiManager, @NotNull VirtualFile vFile,
|
||||
boolean clearResolveCache) {
|
||||
if (!vFile.isValid()) return;
|
||||
|
||||
PsiFile psiFile = psiManager.findFile(vFile);
|
||||
if (psiFile == null || !shouldHighlightFile(psiFile)) return;
|
||||
|
||||
psiFile.accept(visitor);
|
||||
if (clearResolveCache) {
|
||||
psiManager.dropResolveCaches();
|
||||
InjectedLanguageManager.getInstance(psiManager.getProject()).dropFileCaches(psiFile);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean accept(@NotNull final PsiDirectory dir, @NotNull final Processor<VirtualFile> processor) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -57,6 +57,18 @@ public class GlobalSearchScopesCore {
|
||||
return new DirectoryScope(project, directory, withSubdirectories);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static GlobalSearchScope directoriesScope(@NotNull Project project, boolean withSubdirectories, @NotNull VirtualFile... directories) {
|
||||
if (directories.length ==1) {
|
||||
return directoryScope(project, directories[0], withSubdirectories);
|
||||
}
|
||||
BitSet withSubdirectoriesBS = new BitSet(directories.length);
|
||||
if (withSubdirectories) {
|
||||
withSubdirectoriesBS.set(0, directories.length-1);
|
||||
}
|
||||
return new DirectoriesScope(project, directories, withSubdirectoriesBS);
|
||||
}
|
||||
|
||||
public static GlobalSearchScope filterScope(@NotNull Project project, @NotNull NamedScope set) {
|
||||
return new FilterScopeAdapter(project, set);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.folding;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
|
||||
public class CodeFoldingSettings {
|
||||
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_IMPORTS = true;
|
||||
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_METHODS = false;
|
||||
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_FILE_HEADER = true;
|
||||
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_DOC_COMMENTS = false;
|
||||
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_CUSTOM_FOLDING_REGIONS = false;
|
||||
public boolean COLLAPSE_IMPORTS = true;
|
||||
public boolean COLLAPSE_METHODS = false;
|
||||
public boolean COLLAPSE_FILE_HEADER = true;
|
||||
public boolean COLLAPSE_DOC_COMMENTS = false;
|
||||
public boolean COLLAPSE_CUSTOM_FOLDING_REGIONS = false;
|
||||
|
||||
public static CodeFoldingSettings getInstance() {
|
||||
return ServiceManager.getService(CodeFoldingSettings.class);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,7 +29,7 @@ import java.util.Map;
|
||||
* @author peter
|
||||
*/
|
||||
public class CharsetUtil {
|
||||
@SuppressWarnings("MismatchedQueryAndUpdenateOfCollection")
|
||||
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
|
||||
private static final Map<LanguageFileType, Boolean> ourSupportsCharsetDetection = new ConcurrentFactoryMap<LanguageFileType, Boolean>() {
|
||||
@Nullable
|
||||
@Override
|
||||
|
||||
@@ -21,6 +21,8 @@ import com.intellij.diff.DiffRequestFactory;
|
||||
import com.intellij.diff.requests.DiffRequest;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.diff.DiffBundle;
|
||||
import com.intellij.openapi.project.DefaultProjectFactory;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -59,6 +61,7 @@ public class DiffApplication extends ApplicationStarterBase {
|
||||
file2.refresh(false, true);
|
||||
DiffRequest request = DiffRequestFactory.getInstance().createFromFiles(null, file1, file2);
|
||||
|
||||
DiffManagerEx.getInstance().showDiffBuiltin(null, request, DiffDialogHints.MODAL);
|
||||
Project project = DefaultProjectFactory.getInstance().getDefaultProject();
|
||||
DiffManagerEx.getInstance().showDiffBuiltin(project, request, DiffDialogHints.MODAL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,5 +334,25 @@ public class DiffIterableUtil {
|
||||
this.val1 = val1;
|
||||
this.val2 = val2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
IntPair pair = (IntPair)o;
|
||||
|
||||
if (val1 != pair.val1) return false;
|
||||
if (val2 != pair.val2) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = val1;
|
||||
result = 31 * result + val2;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.intellij.diff.util.DiffUserDataKeys;
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx;
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy;
|
||||
import com.intellij.diff.util.DiffUtil;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.impl.DataManagerImpl;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
@@ -242,7 +243,7 @@ public abstract class DiffRequestProcessor implements Disposable {
|
||||
IdRunnable task = new IdRunnable(this) {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myApplyData == null) return;
|
||||
if (myApplyData == null || myDisposed) return;
|
||||
doApplyRequest(myApplyData.request, myApplyData.force, myApplyData.scrollToChangePolicy);
|
||||
myApplyData = null;
|
||||
}
|
||||
@@ -429,7 +430,9 @@ public abstract class DiffRequestProcessor implements Disposable {
|
||||
protected void buildToolbar(@Nullable List<AnAction> viewerActions) {
|
||||
ActionGroup group = collectToolbarActions(viewerActions);
|
||||
ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.DIFF_TOOLBAR, group, true);
|
||||
toolbar.setTargetComponent(myMainPanel);
|
||||
|
||||
DataManager.registerDataProvider(toolbar.getComponent(), myMainPanel);
|
||||
toolbar.setTargetComponent(toolbar.getComponent());
|
||||
|
||||
myToolbarPanel.setContent(toolbar.getComponent());
|
||||
for (AnAction action : group.getChildren(null)) {
|
||||
|
||||
@@ -19,8 +19,7 @@ import com.intellij.diff.DiffDialogHints;
|
||||
import com.intellij.diff.util.DiffUserDataKeys;
|
||||
import com.intellij.diff.util.DiffUtil;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CustomShortcutSet;
|
||||
import com.intellij.openapi.keymap.KeymapManager;
|
||||
import com.intellij.openapi.actionSystem.CommonShortcuts;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.WindowWrapper;
|
||||
@@ -73,8 +72,7 @@ public abstract class DiffWindowBase {
|
||||
public void actionPerformed(final AnActionEvent e) {
|
||||
myWrapper.close();
|
||||
}
|
||||
}.registerCustomShortcutSet(new CustomShortcutSet(KeymapManager.getInstance().getActiveKeymap().getShortcuts("CloseContent")),
|
||||
myProcessor.getComponent());
|
||||
}.registerCustomShortcutSet(CommonShortcuts.getCloseActiveWindow(), myProcessor.getComponent());
|
||||
}
|
||||
|
||||
public void show() {
|
||||
|
||||
@@ -38,6 +38,8 @@ import com.intellij.openapi.diff.impl.dir.DirDiffFrame;
|
||||
import com.intellij.openapi.diff.impl.dir.DirDiffPanel;
|
||||
import com.intellij.openapi.diff.impl.dir.DirDiffTableModel;
|
||||
import com.intellij.openapi.diff.impl.dir.DirDiffWindow;
|
||||
import com.intellij.openapi.project.DefaultProjectFactory;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -63,7 +65,11 @@ class DirDiffViewer implements FrameDiffTool.DiffViewer {
|
||||
List<DiffContent> contents = request.getContents();
|
||||
DiffElement element1 = createDiffElement(contents.get(0));
|
||||
DiffElement element2 = createDiffElement(contents.get(1));
|
||||
DirDiffTableModel model = new DirDiffTableModel(context.getProject(), element1, element2, new DirDiffSettings());
|
||||
|
||||
Project project = context.getProject();
|
||||
if (project == null) project = DefaultProjectFactory.getInstance().getDefaultProject();
|
||||
|
||||
DirDiffTableModel model = new DirDiffTableModel(project, element1, element2, new DirDiffSettings());
|
||||
|
||||
myDirDiffPanel = new DirDiffPanel(model, new DirDiffWindow((DirDiffFrame)null) {
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ public class OnesideFragmentBuilder {
|
||||
processEquals(fragment.getStartLine1() - 1, fragment.getStartLine2() - 1);
|
||||
processChanged(fragment);
|
||||
}
|
||||
processEquals(getLineCount(myDocument1) - 1, getLineCount(myDocument1) - 2);
|
||||
processEquals(getLineCount(myDocument1) - 1, getLineCount(myDocument2) - 1);
|
||||
}
|
||||
|
||||
private void processEquals(int endLine1, int endLine2) {
|
||||
|
||||
@@ -82,7 +82,7 @@ public class DirDiffTableModel extends AbstractTableModel implements DirDiffMode
|
||||
public static final String EMPTY_STRING = " ";
|
||||
private DirDiffPanel myPanel;
|
||||
|
||||
public DirDiffTableModel(Project project, DiffElement src, DiffElement trg, DirDiffSettings settings) {
|
||||
public DirDiffTableModel(@NotNull Project project, DiffElement src, DiffElement trg, DirDiffSettings settings) {
|
||||
myProject = project;
|
||||
mySettings = settings;
|
||||
mySrc = src;
|
||||
|
||||
@@ -15,8 +15,12 @@
|
||||
*/
|
||||
package com.intellij.diff.comparison;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.intellij.util.text.CharSequenceSubSequence;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
@@ -68,4 +72,37 @@ public abstract class AutoTestCase extends UsefulTestCase {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String textToReadableFormat(@Nullable Document text) {
|
||||
if (text == null) return "null";
|
||||
return "'" + text.getCharsSequence().toString().replace('\n', '*').replace('\t', '+') + "'";
|
||||
}
|
||||
|
||||
public static void assertEqualsCharSequences(@NotNull CharSequence chunk1, @NotNull CharSequence chunk2,
|
||||
boolean ignoreSpaces, boolean skipLastNewline) {
|
||||
if (ignoreSpaces) {
|
||||
assertTrue(StringUtil.equalsIgnoreWhitespaces(chunk1, chunk2));
|
||||
}
|
||||
else {
|
||||
if (skipLastNewline) {
|
||||
CharSequence chunk12 = StringUtil.endsWithChar(chunk1, '\n') ? trimLastChar(chunk1) : null;
|
||||
CharSequence chunk22 = StringUtil.endsWithChar(chunk2, '\n') ? trimLastChar(chunk2) : null;
|
||||
|
||||
if (StringUtil.equals(chunk1, chunk2)) return;
|
||||
if (StringUtil.equals(chunk12, chunk2)) return;
|
||||
if (StringUtil.equals(chunk1, chunk22)) return;
|
||||
|
||||
assertTrue(false);
|
||||
}
|
||||
else {
|
||||
assertTrue(StringUtil.equals(chunk1, chunk2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static CharSequence trimLastChar(@NotNull CharSequence text) {
|
||||
return new CharSequenceSubSequence(text, 0, text.length() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,11 +22,8 @@ import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
import com.intellij.openapi.progress.DumbProgressIndicator;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.text.CharSequenceSubSequence;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -37,8 +34,8 @@ public class ComparisonUtilAutoTest extends AutoTestCase {
|
||||
private static DumbProgressIndicator INDICATOR = DumbProgressIndicator.INSTANCE;
|
||||
private static ComparisonManager myComparisonManager = new ComparisonManagerImpl();
|
||||
|
||||
private static int CHAR_COUNT = 12;
|
||||
private static Map<Integer, Character> CHAR_TABLE = initCharMap();
|
||||
private static final int CHAR_COUNT = 12;
|
||||
private static final Map<Integer, Character> CHAR_TABLE = initCharMap();
|
||||
|
||||
private boolean myOldRegistryValue;
|
||||
|
||||
@@ -173,8 +170,8 @@ public class ComparisonUtilAutoTest extends AutoTestCase {
|
||||
System.out.println("Policy: " + policy);
|
||||
System.out.println("I: " + i);
|
||||
System.out.println("Current seed: " + getLastSeed());
|
||||
System.out.println("Text1: " + normalize(text1));
|
||||
System.out.println("Text2: " + normalize(text2));
|
||||
System.out.println("Text1: " + textToReadableFormat(text1));
|
||||
System.out.println("Text2: " + textToReadableFormat(text2));
|
||||
System.out.println("Debug Data: " + debugData.get());
|
||||
if (e instanceof Error) throw (Error)e;
|
||||
if (e instanceof Exception) throw (Exception)e;
|
||||
@@ -320,41 +317,14 @@ public class ComparisonUtilAutoTest extends AutoTestCase {
|
||||
CharSequence chunk1 = text1.subSequence(last1, fragment.getStartOffset1());
|
||||
CharSequence chunk2 = text2.subSequence(last2, fragment.getStartOffset2());
|
||||
|
||||
check(chunk1, chunk2, ignoreSpaces, skipNewline);
|
||||
assertEqualsCharSequences(chunk1, chunk2, ignoreSpaces, skipNewline);
|
||||
|
||||
last1 = fragment.getEndOffset1();
|
||||
last2 = fragment.getEndOffset2();
|
||||
}
|
||||
CharSequence chunk1 = text1.subSequence(last1, text1.length());
|
||||
CharSequence chunk2 = text2.subSequence(last2, text2.length());
|
||||
check(chunk1, chunk2, ignoreSpaces, skipNewline);
|
||||
}
|
||||
|
||||
private static void check(@NotNull CharSequence chunk1, @NotNull CharSequence chunk2,
|
||||
boolean ignoreSpaces, boolean skipNewline) {
|
||||
if (ignoreSpaces) {
|
||||
assertTrue(StringUtil.equalsIgnoreWhitespaces(chunk1, chunk2));
|
||||
}
|
||||
else {
|
||||
if (skipNewline) {
|
||||
CharSequence chunk12 = StringUtil.endsWithChar(chunk1, '\n') ? trimLastChar(chunk1) : null;
|
||||
CharSequence chunk22 = StringUtil.endsWithChar(chunk2, '\n') ? trimLastChar(chunk2) : null;
|
||||
|
||||
if (StringUtil.equals(chunk1, chunk2)) return;
|
||||
if (StringUtil.equals(chunk12, chunk2)) return;
|
||||
if (StringUtil.equals(chunk1, chunk22)) return;
|
||||
|
||||
assertTrue(false);
|
||||
}
|
||||
else {
|
||||
assertTrue(StringUtil.equals(chunk1, chunk2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static CharSequence trimLastChar(@NotNull CharSequence text) {
|
||||
return new CharSequenceSubSequence(text, 0, text.length() - 1);
|
||||
assertEqualsCharSequences(chunk1, chunk2, ignoreSpaces, skipNewline);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -383,12 +353,6 @@ public class ComparisonUtilAutoTest extends AutoTestCase {
|
||||
return map;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String normalize(@Nullable Document text) {
|
||||
if (text == null) return "null";
|
||||
return "'" + text.getCharsSequence().toString().replace('\n', '*').replace('\t', '+') + "'";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static CharSequence subsequence(@NotNull Document document, int start, int end) {
|
||||
return document.getCharsSequence().subSequence(start, end);
|
||||
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.diff.tools.fragmented;
|
||||
|
||||
import com.intellij.diff.comparison.AutoTestCase;
|
||||
import com.intellij.diff.comparison.ComparisonManager;
|
||||
import com.intellij.diff.comparison.ComparisonManagerImpl;
|
||||
import com.intellij.diff.comparison.ComparisonPolicy;
|
||||
import com.intellij.diff.comparison.iterables.DiffIterableUtil;
|
||||
import com.intellij.diff.fragments.LineFragment;
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
import com.intellij.openapi.progress.DumbProgressIndicator;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class OnesideFragmentBuilderAutoTest extends AutoTestCase {
|
||||
private static ComparisonManager myComparisonManager = new ComparisonManagerImpl();
|
||||
|
||||
private static final int CHAR_COUNT = 12;
|
||||
private static final Map<Integer, Character> CHAR_TABLE = initCharMap();
|
||||
|
||||
public void test() throws Exception {
|
||||
doTest(System.currentTimeMillis(), 30, 30);
|
||||
}
|
||||
|
||||
public void doTest(long seed, int runs, int maxLength) throws Exception {
|
||||
myRng.setSeed(seed);
|
||||
|
||||
ComparisonPolicy policy = null;
|
||||
Side masterSide = null;
|
||||
|
||||
for (int i = 0; i < runs; i++) {
|
||||
if (i % 1000 == 0) System.out.println(i);
|
||||
Document text1 = null;
|
||||
Document text2 = null;
|
||||
try {
|
||||
rememberSeed();
|
||||
|
||||
text1 = generateText(maxLength);
|
||||
text2 = generateText(maxLength);
|
||||
|
||||
for (Side side : Side.values()) {
|
||||
for (ComparisonPolicy comparisonPolicy : ComparisonPolicy.values()) {
|
||||
policy = comparisonPolicy;
|
||||
masterSide = side;
|
||||
doTest(text1, text2, policy, masterSide);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
System.out.println("Seed: " + seed);
|
||||
System.out.println("Runs: " + runs);
|
||||
System.out.println("MaxLength: " + maxLength);
|
||||
System.out.println("Policy: " + policy);
|
||||
System.out.println("Current side: " + masterSide);
|
||||
System.out.println("I: " + i);
|
||||
System.out.println("Current seed: " + getLastSeed());
|
||||
System.out.println("Text1: " + textToReadableFormat(text1));
|
||||
System.out.println("Text2: " + textToReadableFormat(text2));
|
||||
if (e instanceof Error) throw (Error)e;
|
||||
if (e instanceof Exception) throw (Exception)e;
|
||||
throw new Exception(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void doTest(@NotNull Document document1, @NotNull Document document2, @NotNull ComparisonPolicy policy, @NotNull Side masterSide) {
|
||||
CharSequence sequence1 = document1.getCharsSequence();
|
||||
CharSequence sequence2 = document2.getCharsSequence();
|
||||
|
||||
List<LineFragment> fragments = myComparisonManager.compareLinesInner(sequence1, sequence2,
|
||||
policy, DumbProgressIndicator.INSTANCE);
|
||||
|
||||
OnesideFragmentBuilder builder = new OnesideFragmentBuilder(fragments, document1, document2, true, masterSide);
|
||||
builder.exec();
|
||||
|
||||
boolean ignoreWhitespaces = policy != ComparisonPolicy.DEFAULT;
|
||||
CharSequence text = builder.getText();
|
||||
List<ChangedBlock> blocks = builder.getBlocks();
|
||||
LineNumberConvertor convertor = builder.getConvertor();
|
||||
List<DiffIterableUtil.IntPair> changedLines = builder.getChangedLines();
|
||||
List<HighlightRange> ranges = builder.getRanges();
|
||||
|
||||
// both documents - before and after - should be subsequence of result text.
|
||||
assertTrue(isSubsequence(text, sequence1, ignoreWhitespaces));
|
||||
assertTrue(isSubsequence(text, sequence2, ignoreWhitespaces));
|
||||
|
||||
// all changes should be inside ChangedLines
|
||||
for (LineFragment fragment : fragments) {
|
||||
int startLine1 = fragment.getStartLine1();
|
||||
int endLine1 = fragment.getEndLine1();
|
||||
int startLine2 = fragment.getStartLine2();
|
||||
int endLine2 = fragment.getEndLine2();
|
||||
|
||||
for (int i = startLine1; i < endLine1; i++) {
|
||||
int targetLine = convertor.convertInv1(i);
|
||||
assertTrue(targetLine != -1);
|
||||
assertTrue(isLineChanged(targetLine, changedLines));
|
||||
}
|
||||
for (int i = startLine2; i < endLine2; i++) {
|
||||
int targetLine = convertor.convertInv2(i);
|
||||
assertTrue(targetLine != -1);
|
||||
assertTrue(isLineChanged(targetLine, changedLines));
|
||||
}
|
||||
}
|
||||
|
||||
// changed fragments and changed blocks should have same content
|
||||
assertEquals(blocks.size(), fragments.size());
|
||||
for (int i = 0; i < fragments.size(); i++) {
|
||||
LineFragment fragment = fragments.get(i);
|
||||
ChangedBlock block = blocks.get(i);
|
||||
|
||||
CharSequence fragment1 = sequence1.subSequence(fragment.getStartOffset1(), fragment.getEndOffset1());
|
||||
CharSequence fragment2 = sequence2.subSequence(fragment.getStartOffset2(), fragment.getEndOffset2());
|
||||
|
||||
CharSequence block1 = text.subSequence(block.getStartOffset1(), block.getEndOffset1());
|
||||
CharSequence block2 = text.subSequence(block.getStartOffset2(), block.getEndOffset2());
|
||||
|
||||
assertEqualsCharSequences(fragment1, block1, ignoreWhitespaces, true);
|
||||
assertEqualsCharSequences(fragment2, block2, ignoreWhitespaces, true);
|
||||
}
|
||||
|
||||
// ranges should have exact same content
|
||||
for (HighlightRange range : ranges) {
|
||||
CharSequence sideSequence = range.getSide().select(sequence1, sequence2);
|
||||
CharSequence baseRange = text.subSequence(range.getBase().getStartOffset(), range.getBase().getEndOffset());
|
||||
CharSequence sideRange = sideSequence.subSequence(range.getChanged().getStartOffset(), range.getChanged().getEndOffset());
|
||||
assertTrue(StringUtil.equals(baseRange, sideRange));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSubsequence(@NotNull CharSequence text, @NotNull CharSequence sequence, boolean ignoreWhitespaces) {
|
||||
int index1 = 0;
|
||||
int index2 = 0;
|
||||
|
||||
while (index2 < sequence.length()) {
|
||||
char c2 = sequence.charAt(index2);
|
||||
if (c2 == '\n' ||
|
||||
StringUtil.isWhiteSpace(c2) && ignoreWhitespaces) {
|
||||
index2++;
|
||||
continue;
|
||||
}
|
||||
|
||||
assertTrue(index1 < text.length());
|
||||
char c1 = text.charAt(index1);
|
||||
if (c1 == '\n' ||
|
||||
StringUtil.isWhiteSpace(c1) && ignoreWhitespaces) {
|
||||
index1++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c1 == c2) {
|
||||
index1++;
|
||||
index2++;
|
||||
}
|
||||
else {
|
||||
index1++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isLineChanged(int line, @NotNull List<DiffIterableUtil.IntPair> changedLines) {
|
||||
for (DiffIterableUtil.IntPair changedLine : changedLines) {
|
||||
if (changedLine.val1 <= line && changedLine.val2 > line) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Document generateText(int maxLength) {
|
||||
return new DocumentImpl(generateText(maxLength, CHAR_COUNT, CHAR_TABLE));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<Integer, Character> initCharMap() {
|
||||
Map<Integer, Character> map = new HashMap<Integer, Character>();
|
||||
|
||||
List<Character> characters = new ArrayList<Character>();
|
||||
characters.add('\n');
|
||||
characters.add('\n');
|
||||
characters.add('\t');
|
||||
characters.add(' ');
|
||||
characters.add(' ');
|
||||
characters.add('.');
|
||||
characters.add('<');
|
||||
characters.add('!');
|
||||
|
||||
for (int i = 0; i < characters.size(); i++) {
|
||||
map.put(i, characters.get(i));
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.diff.tools.fragmented;
|
||||
|
||||
import com.intellij.diff.comparison.ComparisonManager;
|
||||
import com.intellij.diff.comparison.ComparisonManagerImpl;
|
||||
import com.intellij.diff.comparison.ComparisonPolicy;
|
||||
import com.intellij.diff.comparison.iterables.DiffIterableUtil;
|
||||
import com.intellij.diff.fragments.LineFragment;
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
import com.intellij.openapi.progress.DumbProgressIndicator;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class OnesideFragmentBuilderTest extends UsefulTestCase {
|
||||
private static ComparisonManager myComparisonManager = new ComparisonManagerImpl();
|
||||
|
||||
public void testEquals() {
|
||||
Document document1 = new DocumentImpl("A\nB\nC");
|
||||
Document document2 = new DocumentImpl("A\nB\nC");
|
||||
|
||||
List<LineFragment> fragments = myComparisonManager.compareLinesInner(document1.getCharsSequence(), document2.getCharsSequence(),
|
||||
ComparisonPolicy.DEFAULT, DumbProgressIndicator.INSTANCE);
|
||||
|
||||
OnesideFragmentBuilder builder = new OnesideFragmentBuilder(fragments, document1, document2, true, Side.LEFT);
|
||||
builder.exec();
|
||||
|
||||
assertTrue(builder.isEqual());
|
||||
assertEquals(builder.getText().toString(), "A\nB\nC\n");
|
||||
assertEmpty(builder.getChangedLines());
|
||||
assertEmpty(builder.getBlocks());
|
||||
}
|
||||
|
||||
public void testWrongEndLineTypoBug() {
|
||||
Document document1 = new DocumentImpl("A\nB\nC\nD");
|
||||
Document document2 = new DocumentImpl("A\nD");
|
||||
|
||||
List<LineFragment> fragments = myComparisonManager.compareLinesInner(document1.getCharsSequence(), document2.getCharsSequence(),
|
||||
ComparisonPolicy.DEFAULT, DumbProgressIndicator.INSTANCE);
|
||||
|
||||
OnesideFragmentBuilder builder = new OnesideFragmentBuilder(fragments, document1, document2, true, Side.RIGHT);
|
||||
builder.exec();
|
||||
|
||||
assertFalse(builder.isEqual());
|
||||
assertEquals(builder.getText().toString(), "A\nB\nC\nD\n");
|
||||
assertEquals(builder.getChangedLines(), Collections.singletonList(new DiffIterableUtil.IntPair(1, 3)));
|
||||
|
||||
assertEquals(builder.getBlocks().size(), 1);
|
||||
ChangedBlock block = builder.getBlocks().get(0);
|
||||
assertEquals(block.getLine1(), 1);
|
||||
assertEquals(block.getLine2(), 3);
|
||||
assertEquals(block.getStartOffset1(), 2);
|
||||
assertEquals(block.getEndOffset1(), 6);
|
||||
assertEquals(block.getStartOffset2(), 6);
|
||||
assertEquals(block.getEndOffset2(), 6);
|
||||
}
|
||||
}
|
||||
@@ -261,11 +261,7 @@ public class PushLog extends JPanel implements DataProvider {
|
||||
@Override
|
||||
public void linkSelected(LinkLabel aSource, String aLinkData) {
|
||||
if (linkLabel.isEnabled()) {
|
||||
mySyncStrategy = true;
|
||||
DefaultMutableTreeNode nodeToEdit = getFirstNodeToEdit();
|
||||
if (nodeToEdit != null) {
|
||||
myTree.startEditingAtPath(TreeUtil.getPathFromRoot(nodeToEdit));
|
||||
}
|
||||
startSyncEditing();
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
@@ -282,6 +278,13 @@ public class PushLog extends JPanel implements DataProvider {
|
||||
return labelPanel;
|
||||
}
|
||||
|
||||
private void startSyncEditing() {
|
||||
mySyncStrategy = true;
|
||||
DefaultMutableTreeNode nodeToEdit = getFirstNodeToEdit();
|
||||
if (nodeToEdit != null) {
|
||||
myTree.startEditingAtPath(TreeUtil.getPathFromRoot(nodeToEdit));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<Change> collectAllChanges(@NotNull List<CommitNode> commitNodes) {
|
||||
@@ -418,11 +421,7 @@ public class PushLog extends JPanel implements DataProvider {
|
||||
return true;
|
||||
}
|
||||
if (myAllowSyncStrategy && e.getKeyCode() == KeyEvent.VK_F2 && e.getModifiers() == InputEvent.ALT_MASK && pressed) {
|
||||
mySyncStrategy = true;
|
||||
DefaultMutableTreeNode node = getFirstNodeToEdit();
|
||||
if (node != null) {
|
||||
myTree.startEditingAtPath(TreeUtil.getPathFromRoot(node));
|
||||
}
|
||||
startSyncEditing();
|
||||
return true;
|
||||
}
|
||||
return super.processKeyBinding(ks, e, condition, pressed);
|
||||
|
||||
@@ -162,7 +162,8 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
@NotNull final String text,
|
||||
final short searchContext,
|
||||
final boolean caseSensitively) {
|
||||
boolean result = processElementsWithWord(processor, searchScope, text, searchContext, caseSensitively, shouldProcessInjectedPsi(searchScope));
|
||||
boolean result = processElementsWithWord(processor, searchScope, text, searchContext, caseSensitively,
|
||||
shouldProcessInjectedPsi(searchScope));
|
||||
return AsyncUtil.wrapBoolean(result);
|
||||
}
|
||||
|
||||
@@ -576,7 +577,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
refProcessor = second;
|
||||
}
|
||||
|
||||
boolean uniteWith(@NotNull final RequestWithProcessor another) {
|
||||
private boolean uniteWith(@NotNull final RequestWithProcessor another) {
|
||||
if (request.equals(another.request)) {
|
||||
final Processor<PsiReference> myProcessor = refProcessor;
|
||||
if (myProcessor != another.refProcessor) {
|
||||
@@ -891,11 +892,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
registerRequest(locals, primitive, processor);
|
||||
}
|
||||
else {
|
||||
final List<String> words = getWordsToSearch(primitive.word);
|
||||
final Set<IdIndexEntry> key = new HashSet<IdIndexEntry>(words.size() * 2);
|
||||
for (String word : words) {
|
||||
key.add(new IdIndexEntry(word, primitive.caseSensitive));
|
||||
}
|
||||
Set<IdIndexEntry> key = new HashSet<IdIndexEntry>(getWordEntries(primitive.word, primitive.caseSensitive));
|
||||
registerRequest(singles.getModifiable(key), primitive, processor);
|
||||
}
|
||||
}
|
||||
@@ -923,18 +920,6 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> getWordsToSearch(String word) {
|
||||
List<String> words = StringUtil.getWordsInStringLongestFirst(word);
|
||||
if (!words.isEmpty()) {
|
||||
return words;
|
||||
}
|
||||
String trimmed = word.trim();
|
||||
if (StringUtil.isNotEmpty(trimmed)) {
|
||||
return Collections.singletonList(trimmed);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static void registerRequest(@NotNull Collection<RequestWithProcessor> collection,
|
||||
@NotNull PsiSearchRequest primitive,
|
||||
@NotNull Processor<PsiReference> processor) {
|
||||
@@ -1006,14 +991,21 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<IdIndexEntry> getWordEntries(@NotNull String name, boolean caseSensitively) {
|
||||
List<String> words = getWordsToSearch(name);
|
||||
if (words.isEmpty()) return Collections.emptyList();
|
||||
List<IdIndexEntry> keys = new ArrayList<IdIndexEntry>(words.size());
|
||||
for (String word : words) {
|
||||
keys.add(new IdIndexEntry(word, caseSensitively));
|
||||
private static List<IdIndexEntry> getWordEntries(@NotNull String name, final boolean caseSensitively) {
|
||||
List<String> words = StringUtil.getWordsInStringLongestFirst(name);
|
||||
if (words.isEmpty()) {
|
||||
String trimmed = name.trim();
|
||||
if (StringUtil.isNotEmpty(trimmed)) {
|
||||
words = Collections.singletonList(trimmed);
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
if (words.isEmpty()) return Collections.emptyList();
|
||||
return ContainerUtil.map2List(words, new Function<String, IdIndexEntry>() {
|
||||
@Override
|
||||
public IdIndexEntry fun(String word) {
|
||||
return new IdIndexEntry(word, caseSensitively);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean processTextOccurrences(@NotNull final PsiElement element,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
public abstract class TemplateContextType {
|
||||
public static final ExtensionPointName<TemplateContextType> EP_NAME = ExtensionPointName.create("com.intellij.liveTemplateContext");
|
||||
|
||||
@NotNull
|
||||
private final String myContextId;
|
||||
@NotNull
|
||||
private final String myPresentableName;
|
||||
private final Class<? extends TemplateContextType> myBaseContextType;
|
||||
|
||||
@@ -48,10 +50,12 @@ public abstract class TemplateContextType {
|
||||
myBaseContextType = baseContextType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getPresentableName() {
|
||||
return myPresentableName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getContextId() {
|
||||
return myContextId;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.autodetect.IndentOptionsInDocumentKeeper;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.intellij.util.containers.ClassMap;
|
||||
@@ -622,8 +623,15 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
|
||||
if (file != null && file.isValid() && file.isWritable()) {
|
||||
boolean isFullReformat = isFileFullyCoveredByRange(file, formatRange);
|
||||
if (!ignoreDocOptions && !isFullReformat) {
|
||||
IndentOptions docOptions = IndentOptions.retrieveFromAssociatedDocument(file);
|
||||
if (docOptions != null) return docOptions;
|
||||
Pair<IndentOptions, FileIndentOptionsProvider> pair = IndentOptionsInDocumentKeeper.retrieveFromUnderlyingDocument(file);
|
||||
IndentOptions indentOptions = pair != null ? pair.first : null;
|
||||
if (indentOptions != null) {
|
||||
FileIndentOptionsProvider indentProvider = pair.second;
|
||||
if (indentProvider != null && providerProcessor != null) {
|
||||
providerProcessor.process(indentProvider);
|
||||
}
|
||||
return indentOptions;
|
||||
}
|
||||
}
|
||||
FileIndentOptionsProvider[] providers = Extensions.getExtensions(FileIndentOptionsProvider.EP_NAME);
|
||||
for (FileIndentOptionsProvider provider : providers) {
|
||||
|
||||
@@ -20,12 +20,11 @@ import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.DefaultJDOMExternalizer;
|
||||
import com.intellij.openapi.util.DifferenceFilter;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.autodetect.IndentOptionsInDocumentKeeper;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -142,8 +141,16 @@ public class CodeStyleSettingsManager implements PersistentStateComponent<Elemen
|
||||
if (documentManager != null) {
|
||||
PsiFile file = documentManager.getPsiFile(document);
|
||||
if (file != null) {
|
||||
CommonCodeStyleSettings.IndentOptions indentOptions = getSettings(project).getIndentOptionsByFile(file, null, true, null);
|
||||
indentOptions.associateWithDocument(document);
|
||||
final Ref<FileIndentOptionsProvider> providerRef = new Ref<FileIndentOptionsProvider>();
|
||||
CommonCodeStyleSettings.IndentOptions indentOptions =
|
||||
getSettings(project).getIndentOptionsByFile(file, null, true, new Processor<FileIndentOptionsProvider>() {
|
||||
@Override
|
||||
public boolean process(FileIndentOptionsProvider provider) {
|
||||
providerRef.set(provider);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
IndentOptionsInDocumentKeeper.storeIntoDocument(document, indentOptions, providerRef.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,8 @@
|
||||
package com.intellij.psi.codeStyle;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.arrangement.ArrangementSettings;
|
||||
import com.intellij.psi.codeStyle.arrangement.ArrangementUtil;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
@@ -903,8 +899,6 @@ public class CommonCodeStyleSettings {
|
||||
public boolean USE_RELATIVE_INDENTS = false;
|
||||
public boolean KEEP_INDENTS_ON_EMPTY_LINES = false;
|
||||
|
||||
private final static Key<CommonCodeStyleSettings.IndentOptions> INDENT_OPTIONS_KEY = Key.create("INDENT_OPTIONS");
|
||||
|
||||
@Override
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
DefaultJDOMExternalizer.readExternal(this, element);
|
||||
@@ -984,19 +978,5 @@ public class CommonCodeStyleSettings {
|
||||
public void copyFrom(IndentOptions other) {
|
||||
copyPublicFields(other, this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static IndentOptions retrieveFromAssociatedDocument(@NotNull PsiFile file) {
|
||||
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(file.getProject());
|
||||
if (documentManager != null) {
|
||||
Document document = documentManager.getDocument(file);
|
||||
if (document != null) return document.getUserData(INDENT_OPTIONS_KEY);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void associateWithDocument(@NotNull Document document) {
|
||||
document.putUserData(INDENT_OPTIONS_KEY, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.codeStyle.autodetect;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.FileIndentOptionsProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class IndentOptionsInDocumentKeeper {
|
||||
|
||||
public static final Key<Pair<CommonCodeStyleSettings.IndentOptions, FileIndentOptionsProvider>> INDENT_OPTIONS_KEY = Key.create("INDENT_OPTIONS_KEY");
|
||||
|
||||
public static void storeIntoDocument(@NotNull Document document,
|
||||
@NotNull CommonCodeStyleSettings.IndentOptions options,
|
||||
@Nullable FileIndentOptionsProvider provider) {
|
||||
document.putUserData(INDENT_OPTIONS_KEY, Pair.create(options, provider));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Pair<CommonCodeStyleSettings.IndentOptions, FileIndentOptionsProvider> retrieveFromUnderlyingDocument(@NotNull PsiFile file) {
|
||||
Project project = file.getProject();
|
||||
Document document = PsiDocumentManager.getInstance(project).getDocument(file);
|
||||
return document != null ? retrieveFromDocument(document) : null;
|
||||
}
|
||||
|
||||
public static Pair<CommonCodeStyleSettings.IndentOptions, FileIndentOptionsProvider> retrieveFromDocument(@NotNull Document document) {
|
||||
return document.getUserData(INDENT_OPTIONS_KEY);
|
||||
}
|
||||
}
|
||||
+18
-10
@@ -21,13 +21,13 @@ import com.intellij.codeInsight.hint.ElementLocationUtil;
|
||||
import com.intellij.codeInsight.hint.HintManagerImpl;
|
||||
import com.intellij.codeInsight.hint.HintUtil;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.BrowserUtil;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.actions.BaseNavigateToSourceAction;
|
||||
import com.intellij.ide.actions.ExternalJavaDocAction;
|
||||
import com.intellij.lang.documentation.CompositeDocumentationProvider;
|
||||
import com.intellij.lang.documentation.DocumentationProvider;
|
||||
import com.intellij.lang.documentation.ExternalDocumentationHandler;
|
||||
import com.intellij.lang.documentation.ExternalDocumentationProvider;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionButton;
|
||||
@@ -39,6 +39,7 @@ import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
|
||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||
import com.intellij.openapi.options.FontSize;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -54,6 +55,7 @@ import com.intellij.ui.SideBorder;
|
||||
import com.intellij.ui.components.JBLayeredPane;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.ui.GraphicsUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
@@ -696,6 +698,12 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
}
|
||||
}
|
||||
|
||||
private static final Condition<String> BROWSABLE_URL = new Condition<String>() {
|
||||
@Override
|
||||
public boolean value(String s) {
|
||||
return BrowserUtil.canBeBrowsed(s);
|
||||
}
|
||||
};
|
||||
|
||||
private class ExternalDocAction extends AnAction implements HintManagerImpl.ActionToIgnore {
|
||||
public ExternalDocAction() {
|
||||
@@ -722,10 +730,10 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
if (!processed) {
|
||||
final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(e.getDataContext());
|
||||
final List<String> urls;
|
||||
if (!StringUtil.isEmptyOrSpaces(myEffectiveExternalUrl)) {
|
||||
if (!StringUtil.isEmptyOrSpaces(myEffectiveExternalUrl) && BROWSABLE_URL.value(myEffectiveExternalUrl)) {
|
||||
urls = Collections.singletonList(myEffectiveExternalUrl);
|
||||
} else {
|
||||
urls = provider.getUrlFor(element, originalElement);
|
||||
urls = getBrowsableUrls(provider.getUrlFor(element, originalElement));
|
||||
assert urls != null : provider;
|
||||
assert !urls.isEmpty() : provider;
|
||||
}
|
||||
@@ -742,15 +750,15 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
final PsiElement element = myElement.getElement();
|
||||
final DocumentationProvider provider = DocumentationManager.getProviderFromElement(element);
|
||||
final PsiElement originalElement = DocumentationManager.getOriginalElement(element);
|
||||
if (provider instanceof ExternalDocumentationProvider) {
|
||||
presentation.setEnabled(element != null && ((ExternalDocumentationProvider)provider).hasDocumentationFor(element, originalElement));
|
||||
}
|
||||
else {
|
||||
final List<String> urls = provider.getUrlFor(element, originalElement);
|
||||
presentation.setEnabled(element != null && urls != null && !urls.isEmpty());
|
||||
}
|
||||
List<String> urls = getBrowsableUrls(provider.getUrlFor(element, originalElement));
|
||||
presentation.setEnabled(element != null && urls != null && !urls.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private List<String> getBrowsableUrls(@Nullable List<String> urls) {
|
||||
return urls == null ? null : ContainerUtil.filter(urls, BROWSABLE_URL);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerActions() {
|
||||
|
||||
@@ -513,7 +513,7 @@ public class ConsoleHistoryController {
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = new SafeFileOutputStream(file);
|
||||
XmlSerializer serializer = XmlPullParserFactory.newInstance().newSerializer();
|
||||
XmlSerializer serializer = XmlPullParserFactory.newInstance("org.xmlpull.mxp1.MXParserFactory", null).newSerializer();
|
||||
try {
|
||||
serializer.setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-indentation", " ");
|
||||
}
|
||||
|
||||
@@ -466,7 +466,11 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getData(@NonNls String dataId) {
|
||||
if (OpenFileDescriptor.NAVIGATE_IN_EDITOR.is(dataId)) {
|
||||
Object data = super.getData(dataId);
|
||||
if (data != null) {
|
||||
return data;
|
||||
}
|
||||
else if (OpenFileDescriptor.NAVIGATE_IN_EDITOR.is(dataId)) {
|
||||
return myConsoleEditor;
|
||||
}
|
||||
else if (getProject().isInitialized()) {
|
||||
|
||||
@@ -52,6 +52,7 @@ import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Collections;
|
||||
@@ -59,6 +60,7 @@ import java.util.List;
|
||||
|
||||
public class ExecutionManagerImpl extends ExecutionManager implements Disposable {
|
||||
public static final Key<Object> EXECUTION_SESSION_ID_KEY = Key.create("EXECUTION_SESSION_ID_KEY");
|
||||
public static final Key<Boolean> EXECUTION_SKIP_RUN = Key.create("EXECUTION_SKIP_RUN");
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(ExecutionManagerImpl.class);
|
||||
private static final ProcessHandler[] EMPTY_PROCESS_HANDLERS = new ProcessHandler[0];
|
||||
@@ -69,8 +71,9 @@ public class ExecutionManagerImpl extends ExecutionManager implements Disposable
|
||||
private final Alarm awaitingTerminationAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
private final List<Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor>> myRunningConfigurations =
|
||||
ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
private volatile boolean myForceCompilationInTests;
|
||||
|
||||
ExecutionManagerImpl(@NotNull Project project) {
|
||||
protected ExecutionManagerImpl(@NotNull Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
@@ -159,16 +162,29 @@ public class ExecutionManagerImpl extends ExecutionManager implements Disposable
|
||||
return;
|
||||
}
|
||||
}
|
||||
// important! Do not use DumbService.smartInvokeLater here because it depends on modality state
|
||||
// and execution of startRunnable could be skipped if modality state check fails
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!myProject.isDisposed()) {
|
||||
DumbService.getInstance(myProject).runWhenSmart(startRunnable);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
doRun(environment, startRunnable);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected void doRun(@NotNull final ExecutionEnvironment environment, @NotNull final Runnable startRunnable) {
|
||||
Boolean allowSkipRun = environment.getUserData(EXECUTION_SKIP_RUN);
|
||||
if (allowSkipRun != null && allowSkipRun) {
|
||||
environment.getProject().getMessageBus().syncPublisher(EXECUTION_TOPIC).processNotStarted(environment.getExecutor().getId(),
|
||||
environment);
|
||||
}
|
||||
else {
|
||||
// important! Do not use DumbService.smartInvokeLater here because it depends on modality state
|
||||
// and execution of startRunnable could be skipped if modality state check fails
|
||||
//noinspection SSBasedInspection
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!myProject.isDisposed()) {
|
||||
DumbService.getInstance(myProject).runWhenSmart(startRunnable);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -236,7 +252,7 @@ public class ExecutionManagerImpl extends ExecutionManager implements Disposable
|
||||
}
|
||||
};
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode() && !myForceCompilationInTests) {
|
||||
startRunnable.run();
|
||||
}
|
||||
else {
|
||||
@@ -370,6 +386,11 @@ public class ExecutionManagerImpl extends ExecutionManager implements Disposable
|
||||
}, 50);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public void setForceCompilationInTests(boolean forceCompilationInTests) {
|
||||
myForceCompilationInTests = forceCompilationInTests;
|
||||
}
|
||||
|
||||
private static void start(@NotNull ExecutionEnvironment environment) {
|
||||
RunnerAndConfigurationSettings settings = environment.getRunnerAndConfigurationSettings();
|
||||
ProgramRunnerUtil.executeConfiguration(environment, settings != null && settings.isEditBeforeRun(), true);
|
||||
|
||||
+17
-4
@@ -31,6 +31,7 @@ import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
@@ -183,9 +184,9 @@ extends BeforeRunTaskProvider<RunConfigurationBeforeRunProvider.RunConfigurableB
|
||||
if (builder == null) {
|
||||
return false;
|
||||
}
|
||||
final ExecutionEnvironment environment = builder.build();
|
||||
final ExecutionEnvironment environment = builder.target(env.getExecutionTarget()).build();
|
||||
environment.setExecutionId(env.getExecutionId());
|
||||
if (!ExecutionTargetManager.canRun(settings, env.getExecutionTarget())) {
|
||||
if (!ExecutionTargetManager.canRun(settings, environment.getExecutionTarget())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -193,6 +194,8 @@ extends BeforeRunTaskProvider<RunConfigurationBeforeRunProvider.RunConfigurableB
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
beforeRun(environment);
|
||||
|
||||
final Semaphore targetDone = new Semaphore();
|
||||
final Ref<Boolean> result = new Ref<Boolean>(false);
|
||||
final Disposable disposable = Disposer.newDisposable();
|
||||
@@ -208,6 +211,10 @@ extends BeforeRunTaskProvider<RunConfigurationBeforeRunProvider.RunConfigurableB
|
||||
@Override
|
||||
public void processNotStarted(final String executorIdLocal, @NotNull final ExecutionEnvironment environmentLocal) {
|
||||
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
|
||||
Boolean skipRun = environment.getUserData(ExecutionManagerImpl.EXECUTION_SKIP_RUN);
|
||||
if (skipRun != null && skipRun) {
|
||||
result.set(true);
|
||||
}
|
||||
targetDone.up();
|
||||
}
|
||||
}
|
||||
@@ -255,7 +262,13 @@ extends BeforeRunTaskProvider<RunConfigurationBeforeRunProvider.RunConfigurableB
|
||||
}
|
||||
}
|
||||
|
||||
class RunConfigurableBeforeRunTask extends BeforeRunTask<RunConfigurableBeforeRunTask> {
|
||||
private static void beforeRun(@NotNull ExecutionEnvironment environment) {
|
||||
for (RunConfigurationBeforeRunProviderDelegate delegate : Extensions.getExtensions(RunConfigurationBeforeRunProviderDelegate.EP_NAME)) {
|
||||
delegate.beforeRun(environment);
|
||||
}
|
||||
}
|
||||
|
||||
public class RunConfigurableBeforeRunTask extends BeforeRunTask<RunConfigurableBeforeRunTask> {
|
||||
private String myConfigurationName;
|
||||
private String myConfigurationType;
|
||||
private boolean myInitialized = false;
|
||||
@@ -305,7 +318,7 @@ extends BeforeRunTaskProvider<RunConfigurationBeforeRunProvider.RunConfigurableB
|
||||
}
|
||||
}
|
||||
|
||||
void setSettings(RunnerAndConfigurationSettings settings) {
|
||||
public void setSettings(RunnerAndConfigurationSettings settings) {
|
||||
mySettings = settings;
|
||||
myInitialized = true;
|
||||
}
|
||||
|
||||
+8
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,27 +13,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang
|
||||
package com.intellij.execution.impl;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.ClassKind
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by Max Medvedev on 28/05/14
|
||||
*/
|
||||
enum GrCreateClassKind implements ClassKind {
|
||||
CLASS ("class"),
|
||||
INTERFACE ("interface"),
|
||||
TRAIT ("trait"),
|
||||
ENUM ("enum"),
|
||||
ANNOTATION("annotation");
|
||||
public interface RunConfigurationBeforeRunProviderDelegate {
|
||||
ExtensionPointName<RunConfigurationBeforeRunProviderDelegate> EP_NAME = ExtensionPointName.create("com.intellij.runConfigurationBeforeRunProviderDelegate");
|
||||
|
||||
private final String myDescription;
|
||||
|
||||
public GrCreateClassKind(final String description) {
|
||||
myDescription = description;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return myDescription;
|
||||
}
|
||||
void beforeRun(@NotNull ExecutionEnvironment environment);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -390,6 +390,7 @@ class FindInProjectTask {
|
||||
PsiFile file = element.getContainingFile();
|
||||
if (file != null) {
|
||||
ContainerUtil.addIfNotNull(files, file.getVirtualFile());
|
||||
ContainerUtil.addIfNotNull(files, file.getNavigationElement().getContainingFile().getVirtualFile());
|
||||
}
|
||||
}
|
||||
return files;
|
||||
@@ -432,7 +433,7 @@ class FindInProjectTask {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
GlobalSearchScope scope = toGlobal(FindInProjectUtil.getScopeFromModel(myProject, myFindModel));
|
||||
final GlobalSearchScope scope = toGlobal(FindInProjectUtil.getScopeFromModel(myProject, myFindModel));
|
||||
|
||||
final Set<VirtualFile> resultFiles = new LinkedHashSet<VirtualFile>();
|
||||
|
||||
@@ -448,12 +449,10 @@ class FindInProjectTask {
|
||||
|
||||
if (!keys.isEmpty()) {
|
||||
final List<VirtualFile> hits = new ArrayList<VirtualFile>();
|
||||
final GlobalSearchScope finalScope = scope;
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
FileBasedIndex.getInstance().getFilesWithKey(TrigramIndex.INDEX_ID, keys, new CommonProcessors.CollectProcessor<VirtualFile>(hits),
|
||||
finalScope);
|
||||
FileBasedIndex.getInstance().getFilesWithKey(TrigramIndex.INDEX_ID, keys, new CommonProcessors.CollectProcessor<VirtualFile>(hits), scope);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,14 +39,14 @@ import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.DumbServiceImpl;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.OrderEntry;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Factory;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileProvider;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.vfs.ex.VirtualFileManagerEx;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.*;
|
||||
@@ -65,7 +65,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class FindInProjectUtil {
|
||||
@@ -439,6 +442,24 @@ public class FindInProjectUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static void addSourceDirectoriesFromLibraries(@NotNull Project project,
|
||||
@NotNull VirtualFile file,
|
||||
@NotNull Collection<VirtualFile> outSourceRoots) {
|
||||
ProjectFileIndex index = ProjectFileIndex.SERVICE.getInstance(project);
|
||||
VirtualFile classRoot = index.getClassRootForFile(file);
|
||||
if (classRoot == null) return;
|
||||
String relativePath = VfsUtil.getRelativePath(file, classRoot);
|
||||
if (relativePath == null) return;
|
||||
for (OrderEntry orderEntry : index.getOrderEntriesForFile(file)) {
|
||||
for (VirtualFile sourceRoot : orderEntry.getFiles(OrderRootType.SOURCES)) {
|
||||
VirtualFile sourceFile = sourceRoot.findFileByRelativePath(relativePath);
|
||||
if (sourceFile != null) {
|
||||
outSourceRoots.add(sourceFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static SearchScope getScopeFromModel(@NotNull Project project, @NotNull FindModel findModel) {
|
||||
SearchScope customScope = findModel.getCustomScope();
|
||||
@@ -448,9 +469,20 @@ public class FindInProjectUtil {
|
||||
return findModel.isCustomScope() && customScope != null ? customScope :
|
||||
// we don't have to check for myProjectFileIndex.isExcluded(file) here like FindInProjectTask.collectFilesInScope() does
|
||||
// because all found usages are guaranteed to be not in excluded dir
|
||||
directory != null ? GlobalSearchScopesCore.directoryScope(project, directory, findModel.isWithSubdirectories()) :
|
||||
directory != null ? forDirectory(project, findModel.isWithSubdirectories(), directory) :
|
||||
module != null ? module.getModuleContentScope() :
|
||||
findModel.isProjectScope() ? ProjectScope.getContentScope(project) :
|
||||
GlobalSearchScope.allScope(project);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static GlobalSearchScope forDirectory(@NotNull Project project,
|
||||
boolean withSubdirectories,
|
||||
@NotNull VirtualFile directory) {
|
||||
Set<VirtualFile> result = new LinkedHashSet<VirtualFile>();
|
||||
result.add(directory);
|
||||
addSourceDirectoriesFromLibraries(project, directory, result);
|
||||
VirtualFile[] array = result.toArray(new VirtualFile[result.size()]);
|
||||
return GlobalSearchScopesCore.directoriesScope(project, withSubdirectories, array);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -881,6 +881,7 @@ public abstract class ChooseByNameBase {
|
||||
(10, (paneHeight - (y + preferredTextFieldPanelSize.height)) / (preferredTextFieldPanelSize.height / 2) - 1);
|
||||
|
||||
ComponentPopupBuilder builder = JBPopupFactory.getInstance().createComponentPopupBuilder(myTextFieldPanel, myTextField);
|
||||
builder.setLocateWithinScreenBounds(false);
|
||||
builder.setCancelCallback(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -340,6 +340,11 @@ public class EditorWindowImpl extends UserDataHolderBase implements EditorWindow
|
||||
myDelegate.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(@NotNull PropertyChangeListener listener, @NotNull Disposable parentDisposable) {
|
||||
myDelegate.addPropertyChangeListener(listener, parentDisposable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(@NotNull final PropertyChangeListener listener) {
|
||||
myDelegate.removePropertyChangeListener(listener);
|
||||
|
||||
+9
-3
@@ -12,6 +12,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.platform.templates.github.GeneratorException;
|
||||
import com.intellij.platform.templates.github.GithubTagInfo;
|
||||
import com.intellij.platform.templates.github.ZipUtil;
|
||||
import com.intellij.util.NullableFunction;
|
||||
import com.intellij.util.PlatformUtils;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -39,10 +40,10 @@ public abstract class AbstractGithubTagDownloadedProjectGenerator extends WebPro
|
||||
protected abstract String getDisplayName();
|
||||
|
||||
@NotNull
|
||||
protected abstract String getGithubUserName();
|
||||
public abstract String getGithubUserName();
|
||||
|
||||
@NotNull
|
||||
protected abstract String getGithubRepositoryName();
|
||||
public abstract String getGithubRepositoryName();
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
@@ -128,7 +129,12 @@ public abstract class AbstractGithubTagDownloadedProjectGenerator extends WebPro
|
||||
);
|
||||
LOG.info("Content of " + url + " has been successfully downloaded to " + zipArchiveFile.getAbsolutePath()
|
||||
+ ", size " + zipArchiveFile.length() + " bytes");
|
||||
ZipUtil.unzipWithProgressSynchronously(project, getTitle(), zipArchiveFile, extractToDir, true);
|
||||
ZipUtil.unzipWithProgressSynchronously(project, getTitle(), zipArchiveFile, extractToDir, getPathConvertor(), true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected NullableFunction<String, String> getPathConvertor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+4
-1
@@ -30,7 +30,10 @@ public class UniqueNameEditorTabTitleProvider implements EditorTabTitleProvider
|
||||
if (!UISettings.getInstance().SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES || DumbService.isDumb(project)) {
|
||||
return null;
|
||||
}
|
||||
final String uniqueName = UniqueVFilePathBuilder.getInstance().getUniqueVirtualFilePathWithinOpenedFileEditors(project, file);
|
||||
// Even though this is a 'tab title provider' it is used also when tabs are not shown, namely for building IDE frame title.
|
||||
final String uniqueName = UISettings.getInstance().EDITOR_TAB_PLACEMENT == UISettings.TABS_NONE ?
|
||||
UniqueVFilePathBuilder.getInstance().getUniqueVirtualFilePath(project, file) :
|
||||
UniqueVFilePathBuilder.getInstance().getUniqueVirtualFilePathWithinOpenedFileEditors(project, file);
|
||||
return uniqueName.equals(file.getName()) ? null : uniqueName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,17 @@ public class ZipUtil {
|
||||
@NotNull final File zipArchive,
|
||||
@NotNull final File extractToDir,
|
||||
final boolean unwrapSingleTopLevelFolder) throws GeneratorException
|
||||
{
|
||||
unzipWithProgressSynchronously(project, progressTitle, zipArchive, extractToDir, null, unwrapSingleTopLevelFolder);
|
||||
}
|
||||
|
||||
public static void unzipWithProgressSynchronously(
|
||||
@Nullable Project project,
|
||||
@NotNull String progressTitle,
|
||||
@NotNull final File zipArchive,
|
||||
@NotNull final File extractToDir,
|
||||
@Nullable final NullableFunction<String, String> pathConvertor,
|
||||
final boolean unwrapSingleTopLevelFolder) throws GeneratorException
|
||||
{
|
||||
final Outcome<Boolean> outcome = DownloadUtil.provideDataWithProgressSynchronously(
|
||||
project, progressTitle, "Unpacking ...",
|
||||
@@ -47,7 +58,7 @@ public class ZipUtil {
|
||||
@Override
|
||||
public Boolean call() throws IOException {
|
||||
ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
|
||||
unzip(progress, extractToDir, zipArchive, null, null, unwrapSingleTopLevelFolder);
|
||||
unzip(progress, extractToDir, zipArchive, pathConvertor, null, unwrapSingleTopLevelFolder);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
+6
-2
@@ -34,7 +34,7 @@ import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.psi.codeStyle.EditorNotificationInfo.*;
|
||||
import static com.intellij.psi.codeStyle.EditorNotificationInfo.ActionLabelData;
|
||||
|
||||
/**
|
||||
* @author Rustam Vishnyakov
|
||||
@@ -42,6 +42,7 @@ import static com.intellij.psi.codeStyle.EditorNotificationInfo.*;
|
||||
public class DetectedIndentOptionsNotificationProvider extends EditorNotifications.Provider<EditorNotificationPanel> {
|
||||
private static final Key<EditorNotificationPanel> KEY = Key.create("indent.options.notification.provider");
|
||||
private static final Key<Boolean> NOTIFIED_FLAG = Key.create("indent.options.notification.provider.status");
|
||||
protected static final Key<Boolean> DETECT_INDENT_NOTIFICATION_SHOWN_KEY = Key.create("indent.options.notification.provider.status.test.notification.shown");
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -93,6 +94,9 @@ public class DetectedIndentOptionsNotificationProvider extends EditorNotificatio
|
||||
};
|
||||
panel.createActionLabel(actionLabelData.label, onClickAction);
|
||||
}
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
file.putUserData(DETECT_INDENT_NOTIFICATION_SHOWN_KEY, Boolean.TRUE);
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
@@ -102,7 +106,7 @@ public class DetectedIndentOptionsNotificationProvider extends EditorNotificatio
|
||||
}
|
||||
|
||||
public static void updateIndentNotification(@NotNull PsiFile file, boolean enforce) {
|
||||
if (!(ApplicationManager.getApplication().isHeadlessEnvironment() || ApplicationManager.getApplication().isUnitTestMode())) {
|
||||
if (!ApplicationManager.getApplication().isHeadlessEnvironment() || ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
FileEditor fileEditor = FileEditorManager.getInstance(file.getProject()).getSelectedEditor(file.getVirtualFile());
|
||||
if (fileEditor != null) {
|
||||
Boolean notifiedFlag = fileEditor.getUserData(NOTIFIED_FLAG);
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.codeStyle.autodetect;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.testFramework.PlatformTestCase;
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
|
||||
|
||||
public class DetectedIndentNotificationTest extends LightPlatformCodeInsightFixtureTestCase {
|
||||
|
||||
static {
|
||||
PlatformTestCase.initPlatformLangPrefix();
|
||||
}
|
||||
|
||||
private CodeStyleSettings mySettings;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mySettings = CodeStyleSettingsManager.getInstance(getProject()).getCurrentSettings();
|
||||
mySettings.AUTODETECT_INDENTS = true;
|
||||
DetectableIndentOptionsProvider optionsProvider = DetectableIndentOptionsProvider.getInstance();
|
||||
if (optionsProvider != null) {
|
||||
optionsProvider.setEnabledInTest(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
mySettings.AUTODETECT_INDENTS = false;
|
||||
DetectableIndentOptionsProvider optionsProvider = DetectableIndentOptionsProvider.getInstance();
|
||||
if (optionsProvider != null) {
|
||||
optionsProvider.setEnabledInTest(false);
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testNotificationShownOnEnter_WhenIndentDetected() throws Exception {
|
||||
myFixture.configureByText("Test.java",
|
||||
"class Test {\n" +
|
||||
" public void main() {\n" +
|
||||
" int a;<caret>\n" +
|
||||
" int b;\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
|
||||
PsiFile file = myFixture.getFile();
|
||||
VirtualFile vFile = file.getVirtualFile();
|
||||
|
||||
Boolean notificationShown = vFile.getUserData(DetectedIndentOptionsNotificationProvider.DETECT_INDENT_NOTIFICATION_SHOWN_KEY);
|
||||
assert notificationShown == null;
|
||||
|
||||
myFixture.type('\n');
|
||||
|
||||
notificationShown = vFile.getUserData(DetectedIndentOptionsNotificationProvider.DETECT_INDENT_NOTIFICATION_SHOWN_KEY);
|
||||
assert notificationShown != null && notificationShown;
|
||||
}
|
||||
|
||||
public void testNoNotification_WhenNothingDetected() throws Exception {
|
||||
myFixture.configureByText("Test.java",
|
||||
"class Test {\n" +
|
||||
" public void main() {\n" +
|
||||
" int a;<caret>\n" +
|
||||
" int b;\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
|
||||
PsiFile file = myFixture.getFile();
|
||||
VirtualFile vFile = file.getVirtualFile();
|
||||
|
||||
Boolean notificationShown = vFile.getUserData(DetectedIndentOptionsNotificationProvider.DETECT_INDENT_NOTIFICATION_SHOWN_KEY);
|
||||
assert notificationShown == null;
|
||||
|
||||
myFixture.type('\n');
|
||||
|
||||
notificationShown = vFile.getUserData(DetectedIndentOptionsNotificationProvider.DETECT_INDENT_NOTIFICATION_SHOWN_KEY);
|
||||
assert notificationShown == null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -57,6 +57,10 @@ public class BrowserUtil {
|
||||
public static boolean isAbsoluteURL(String url) {
|
||||
return ourExternalPrefix.matcher(url.toLowerCase(Locale.ENGLISH)).find();
|
||||
}
|
||||
|
||||
public static boolean canBeBrowsed(String url) {
|
||||
return url != null && !url.startsWith("jar:");
|
||||
}
|
||||
|
||||
public static String getDocURL(String url) {
|
||||
Matcher anchorMatcher = ourAnchorSuffix.matcher(url);
|
||||
|
||||
@@ -16,5 +16,5 @@
|
||||
package com.intellij.openapi.wm;
|
||||
|
||||
public enum ToolWindowType {
|
||||
DOCKED, FLOATING, SLIDING
|
||||
DOCKED, FLOATING, SLIDING, WINDOWED
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ public interface WindowInfo {
|
||||
|
||||
boolean isFloating();
|
||||
|
||||
boolean isWindowed();
|
||||
|
||||
boolean isSliding();
|
||||
|
||||
ToolWindowContentUiType getContentUiType();
|
||||
|
||||
@@ -69,6 +69,7 @@ public class LightToolWindow extends JPanel {
|
||||
private final TogglePinnedModeAction myToggleAutoHideModeAction = new TogglePinnedModeAction();
|
||||
private final ToggleDockModeAction myToggleDockModeAction = new ToggleDockModeAction();
|
||||
private final ToggleFloatingModeAction myToggleFloatingModeAction = new ToggleFloatingModeAction();
|
||||
private final ToggleWindowedModeAction myToggleWindowedModeAction = new ToggleWindowedModeAction();
|
||||
private final ToggleSideModeAction myToggleSideModeAction = new ToggleSideModeAction();
|
||||
|
||||
private final ComponentListener myWidthListener = new ComponentAdapter() {
|
||||
@@ -331,15 +332,18 @@ public class LightToolWindow extends JPanel {
|
||||
group.add(myToggleAutoHideModeAction);
|
||||
group.add(myToggleDockModeAction);
|
||||
group.add(myToggleFloatingModeAction);
|
||||
group.add(myToggleWindowedModeAction);
|
||||
group.add(myToggleSideModeAction);
|
||||
}
|
||||
else if (type == ToolWindowType.FLOATING) {
|
||||
else if (type == ToolWindowType.FLOATING || type == ToolWindowType.WINDOWED) {
|
||||
group.add(myToggleAutoHideModeAction);
|
||||
group.add(myToggleFloatingModeAction);
|
||||
group.add(myToggleWindowedModeAction);
|
||||
}
|
||||
else if (type == ToolWindowType.SLIDING) {
|
||||
group.add(myToggleDockModeAction);
|
||||
group.add(myToggleFloatingModeAction);
|
||||
group.add(myToggleWindowedModeAction);
|
||||
}
|
||||
|
||||
return group;
|
||||
@@ -411,14 +415,9 @@ public class LightToolWindow extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private class ToggleDockModeAction extends ToggleAction {
|
||||
private class ToggleDockModeAction extends ToggleTypeModeAction {
|
||||
public ToggleDockModeAction() {
|
||||
copyFrom(ActionManager.getInstance().getAction(InternalDecorator.TOGGLE_DOCK_MODE_ACTION_ID));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myManager.getToolWindow().getType() == ToolWindowType.DOCKED;
|
||||
super(ToolWindowType.DOCKED, InternalDecorator.TOGGLE_DOCK_MODE_ACTION_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -435,25 +434,45 @@ public class LightToolWindow extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private class ToggleFloatingModeAction extends ToggleAction {
|
||||
private class ToggleFloatingModeAction extends ToggleTypeModeAction {
|
||||
public ToggleFloatingModeAction() {
|
||||
copyFrom(ActionManager.getInstance().getAction(InternalDecorator.TOGGLE_FLOATING_MODE_ACTION_ID));
|
||||
super(ToolWindowType.FLOATING, InternalDecorator.TOGGLE_FLOATING_MODE_ACTION_ID);
|
||||
}
|
||||
}
|
||||
|
||||
private class ToggleWindowedModeAction extends ToggleTypeModeAction {
|
||||
public ToggleWindowedModeAction() {
|
||||
super(ToolWindowType.WINDOWED, InternalDecorator.TOGGLE_WINDOWED_MODE_ACTION_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull AnActionEvent e) {
|
||||
e.getPresentation().setEnabledAndVisible(!SystemInfo.isMac);
|
||||
}
|
||||
}
|
||||
|
||||
private class ToggleTypeModeAction extends ToggleAction {
|
||||
private final ToolWindowType myType;
|
||||
|
||||
public ToggleTypeModeAction(ToolWindowType type, String id) {
|
||||
myType = type;
|
||||
copyFrom(ActionManager.getInstance().getAction(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myManager.getToolWindow().getType() == ToolWindowType.FLOATING;
|
||||
return myManager.getToolWindow().getType() == myType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
ToolWindow window = myManager.getToolWindow();
|
||||
ToolWindowType type = window.getType();
|
||||
if (type == ToolWindowType.FLOATING) {
|
||||
if (type == myType) {
|
||||
window.setType(((ToolWindowEx)window).getInternalType(), null);
|
||||
}
|
||||
else {
|
||||
window.setType(ToolWindowType.FLOATING, null);
|
||||
window.setType(myType, null);
|
||||
}
|
||||
myManager.setEditorMode(null);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class GotoLineAction extends AnAction implements DumbAware {
|
||||
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final Project project = e.getData(CommonDataKeys.PROJECT);
|
||||
final Editor editor = e.getData(CommonDataKeys.EDITOR);
|
||||
final Editor editor = e.getData(CommonDataKeys.EDITOR_EVEN_IF_INACTIVE);
|
||||
if (Boolean.TRUE.equals(e.getData(PlatformDataKeys.IS_MODAL_CONTEXT))) {
|
||||
GotoLineNumberDialog dialog = new GotoLineNumberDialog(project, editor);
|
||||
dialog.show();
|
||||
@@ -60,7 +60,7 @@ public class GotoLineAction extends AnAction implements DumbAware {
|
||||
presentation.setVisible(false);
|
||||
return;
|
||||
}
|
||||
Editor editor = event.getData(CommonDataKeys.EDITOR);
|
||||
Editor editor = event.getData(CommonDataKeys.EDITOR_EVEN_IF_INACTIVE);
|
||||
presentation.setEnabled(editor != null);
|
||||
presentation.setVisible(editor != null);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.ToolWindowType;
|
||||
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
|
||||
import com.intellij.openapi.wm.impl.DesktopLayout;
|
||||
|
||||
@@ -51,7 +52,7 @@ public class HideAllToolWindowsAction extends AnAction implements DumbAware {
|
||||
boolean hasVisible = false;
|
||||
for (String id : ids) {
|
||||
ToolWindow toolWindow = toolWindowManager.getToolWindow(id);
|
||||
if (toolWindow.isVisible()) {
|
||||
if (toolWindow.isVisible() && toolWindow.getType() != ToolWindowType.WINDOWED) {
|
||||
toolWindow.hide(null);
|
||||
hasVisible = true;
|
||||
}
|
||||
@@ -81,7 +82,8 @@ public class HideAllToolWindowsAction extends AnAction implements DumbAware {
|
||||
ToolWindowManagerEx toolWindowManager = ToolWindowManagerEx.getInstanceEx(project);
|
||||
String[] ids = toolWindowManager.getToolWindowIds();
|
||||
for (String id : ids) {
|
||||
if (toolWindowManager.getToolWindow(id).isVisible()) {
|
||||
ToolWindow toolWindow = toolWindowManager.getToolWindow(id);
|
||||
if (toolWindow.isVisible() && toolWindow.getType() != ToolWindowType.WINDOWED) {
|
||||
presentation.setEnabled(true);
|
||||
presentation.setText(IdeBundle.message("action.hide.all.windows"), true);
|
||||
return;
|
||||
|
||||
@@ -99,7 +99,7 @@ public abstract class ResizeToolWindowAction extends AnAction implements DumbAwa
|
||||
window = mgr.getToolWindow(mgr.getActiveToolWindowId());
|
||||
}
|
||||
|
||||
if (window == null || !window.isAvailable() || !window.isVisible() || window.getType() == ToolWindowType.FLOATING || !window.isActive()) {
|
||||
if (window == null || !window.isAvailable() || !window.isVisible() || window.getType() == ToolWindowType.FLOATING || window.getType() == ToolWindowType.WINDOWED || !window.isActive()) {
|
||||
setDisabled(e);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -74,6 +74,8 @@ public class ToggleDockModeAction extends ToggleAction implements DumbAware {
|
||||
return;
|
||||
}
|
||||
ToolWindow toolWindow=mgr.getToolWindow(id);
|
||||
presentation.setEnabled(toolWindow.isAvailable()&&ToolWindowType.FLOATING!=toolWindow.getType());
|
||||
presentation.setEnabled(toolWindow.isAvailable()
|
||||
&& toolWindow.getType() != ToolWindowType.FLOATING
|
||||
&& toolWindow.getType() != ToolWindowType.WINDOWED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.ide.actions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.actionSystem.ToggleAction;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.openapi.wm.ToolWindowType;
|
||||
import com.intellij.openapi.wm.ex.ToolWindowEx;
|
||||
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
|
||||
|
||||
public class ToggleWindowedModeAction extends ToggleAction implements DumbAware {
|
||||
|
||||
public boolean isSelected(AnActionEvent event) {
|
||||
Project project = CommonDataKeys.PROJECT.getData(event.getDataContext());
|
||||
if (project == null) {
|
||||
return false;
|
||||
}
|
||||
ToolWindowManager windowManager = ToolWindowManager.getInstance(project);
|
||||
String id = windowManager.getActiveToolWindowId();
|
||||
if (id == null) {
|
||||
return false;
|
||||
}
|
||||
return ToolWindowType.WINDOWED == windowManager.getToolWindow(id).getType();
|
||||
}
|
||||
|
||||
public void setSelected(AnActionEvent event, boolean flag) {
|
||||
Project project = CommonDataKeys.PROJECT.getData(event.getDataContext());
|
||||
if (project == null) {
|
||||
return;
|
||||
}
|
||||
String id = ToolWindowManager.getInstance(project).getActiveToolWindowId();
|
||||
if (id == null) {
|
||||
return;
|
||||
}
|
||||
ToolWindowManagerEx mgr = ToolWindowManagerEx.getInstanceEx(project);
|
||||
ToolWindowEx toolWindow = (ToolWindowEx)mgr.getToolWindow(id);
|
||||
ToolWindowType type = toolWindow.getType();
|
||||
if (ToolWindowType.WINDOWED == type) {
|
||||
toolWindow.setType(toolWindow.getInternalType(), null);
|
||||
}
|
||||
else {
|
||||
toolWindow.setType(ToolWindowType.WINDOWED, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void update(AnActionEvent event) {
|
||||
super.update(event);
|
||||
Presentation presentation = event.getPresentation();
|
||||
if (SystemInfo.isMac) {
|
||||
presentation.setEnabledAndVisible(false);
|
||||
return;
|
||||
}
|
||||
Project project = CommonDataKeys.PROJECT.getData(event.getDataContext());
|
||||
if (project == null) {
|
||||
presentation.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
ToolWindowManager mgr = ToolWindowManager.getInstance(project);
|
||||
String id = mgr.getActiveToolWindowId();
|
||||
presentation.setEnabled(id != null && mgr.getToolWindow(id).isAvailable());
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.editor.LogicalPosition;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -49,6 +50,7 @@ public class GotoLineNumberDialog extends DialogWrapper {
|
||||
myEditor.getCaretModel().moveToOffset(offset);
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
|
||||
myEditor.getSelectionModel().removeSelection();
|
||||
IdeFocusManager.getGlobalInstance().requestFocus(myEditor.getContentComponent(), true);
|
||||
super.doOKAction();
|
||||
}
|
||||
return;
|
||||
@@ -65,6 +67,7 @@ public class GotoLineNumberDialog extends DialogWrapper {
|
||||
myEditor.getCaretModel().moveToLogicalPosition(new LogicalPosition(Math.max(0, lineNumber - 1), Math.max(0, columnNumber - 1)));
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
|
||||
myEditor.getSelectionModel().removeSelection();
|
||||
IdeFocusManager.getGlobalInstance().requestFocus(myEditor.getContentComponent(), true);
|
||||
super.doOKAction();
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user