Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ilya.Kazakevich
2015-03-23 19:10:49 +03:00
175 changed files with 3076 additions and 919 deletions
@@ -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) {
@@ -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);
}
}
}
@@ -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;
}
@@ -0,0 +1,9 @@
package p;
import p2.GenericClass;
public class Class1 extends GenericClass<Integer> {
public void map(InnerClass context) {
Class2.test(context);
}
}
@@ -0,0 +1,10 @@
package p;
import p2.GenericClass.InnerClass;
public class Class2 {
public static boolean test(InnerClass context) {
return true;
}
}
@@ -0,0 +1,6 @@
package p2;
public class GenericClass<T> {
public class InnerClass {
}
}
@@ -0,0 +1,9 @@
package p;
import p2.GenericClass;
public class Class1 extends GenericClass<Integer> {
public void map(InnerClass context) {
Class2.test(context);
}
}
@@ -0,0 +1,10 @@
package p;
import p2.GenericClass.*;
public class Class2 {
public static boolean test(InnerClass context) {
return true;
}
}
@@ -0,0 +1,6 @@
package p2;
public class GenericClass<T> {
public class InnerClass {
}
}
@@ -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();
}
};
}
}
@@ -0,0 +1,9 @@
import java.lang.String;
abstract class Test {
abstract <T> T get();
void foo() {
String.valueOf(get());
}
}
@@ -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
@@ -0,0 +1,8 @@
package ppp;
public class Client {
public void execute(DataProvider data) {
for (String s : data.getData()) {
System.out.println(s);
}
}
}
@@ -0,0 +1,8 @@
package ppp;
public class Client {
public void execute(DataProvider data) {
for (String s : data.getData(10)) {
System.out.println(s);
}
}
}
@@ -0,0 +1,7 @@
package ppp;
import java.util.Collection;
public interface DataProvider {
Collection<String> getData();
}
@@ -0,0 +1,7 @@
package ppp;
import java.util.Collection;
public interface DataProvider {
Collection<String> getData(int param);
}
@@ -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());
}
}
@@ -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");
}
}
@@ -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");
}
}
@@ -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
@@ -0,0 +1,8 @@
package ppp;
public class Client {
public void execute(DataProvider data) {
for (String s : data.getData()) {
System.out.println(s);
}
}
}
@@ -0,0 +1,7 @@
package ppp;
import java.util.Collection;
public interface DataProvider {
Collection<String> getData();
}
@@ -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());
}
}
@@ -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");
}
}
@@ -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");
}
}
@@ -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
@@ -0,0 +1,8 @@
package ppp;
public class Client {
public void execute(DataProvider data) {
for (String s : data.getData()) {
System.out.println(s);
}
}
}
@@ -0,0 +1,7 @@
package ppp;
import java.util.Collection;
public interface DataProvider {
Collection<String> getData();
}
@@ -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);
}
}
@@ -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");
}
}
@@ -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");
}
}
@@ -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
@@ -0,0 +1,8 @@
package ppp;
public class Client {
public void execute(DataProvider data) {
for (String s : data.getData()) {
System.out.println(s);
}
}
}
@@ -0,0 +1,8 @@
package ppp;
public class Client {
public void execute(DataProvider data) {
for (String s : data.getData(10)) {
System.out.println(s);
}
}
}
@@ -0,0 +1,7 @@
package ppp;
import java.util.Collection;
public interface DataProvider {
Collection<String> getData();
}
@@ -0,0 +1,7 @@
package ppp;
import java.util.Collection;
public interface DataProvider {
Collection<String> getData(int param);
}
@@ -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);
}
}
@@ -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");
}
}
@@ -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);
@@ -185,6 +185,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testInfiniteLoopAndValueCompatibility() throws Exception {
doTest();
}
private void doTest() {
doTest(false);
}
@@ -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());
}
}
@@ -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
@@ -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);
@@ -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;
}
}
@@ -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);
}
}
}
@@ -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);
}
}
@@ -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);
@@ -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;
}
@@ -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);
@@ -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
@@ -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;
}
},
@@ -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);
@@ -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