Merge remote-tracking branch 'origin/master'

This commit is contained in:
Anna Kozlova
2014-11-18 19:41:05 +01:00
10 changed files with 87 additions and 90 deletions
@@ -45,7 +45,6 @@ import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.*;
import gnu.trove.THashSet;
@@ -191,34 +190,27 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
CompositeElement treeParent = expression.getTreeParent();
IElementType parentType = treeParent == null ? null : treeParent.getElementType();
List<PsiElement> qualifiers = resolveAllQualifiers(expression, containingFile);
try {
JavaResolveResult[] result = expression.resolve(parentType, containingFile);
List<ResolveResult[]> qualifiers = resolveAllQualifiers(expression, containingFile);
JavaResolveResult[] result = expression.resolve(parentType, containingFile);
if (result.length == 0 && incompleteCode && parentType != JavaElementType.REFERENCE_EXPRESSION) {
result = expression.resolve(JavaElementType.REFERENCE_EXPRESSION, containingFile);
}
JavaResolveUtil.substituteResults(expression, result);
return result;
}
finally {
PsiElement item = qualifiers.isEmpty() ? PsiUtilCore.NULL_PSI_ELEMENT : qualifiers.get(qualifiers.size()-1);
qualifiers.clear(); // hold qualifiers list until this moment to avoid psi elements inside to GC
if (item == null) {
throw new IncorrectOperationException();
}
if (result.length == 0 && incompleteCode && parentType != JavaElementType.REFERENCE_EXPRESSION) {
result = expression.resolve(JavaElementType.REFERENCE_EXPRESSION, containingFile);
}
JavaResolveUtil.substituteResults(expression, result);
qualifiers.clear(); // hold qualifier target list until this moment to avoid psi elements inside to GC
return result;
}
@NotNull
private static List<PsiElement> resolveAllQualifiers(@NotNull PsiReferenceExpressionImpl expression, @NotNull final PsiFile containingFile) {
private static List<ResolveResult[]> resolveAllQualifiers(@NotNull PsiReferenceExpressionImpl expression, @NotNull final PsiFile containingFile) {
// to avoid SOE, resolve all qualifiers starting from the innermost
PsiElement qualifier = expression.getQualifier();
if (qualifier == null) return Collections.emptyList();
final List<PsiElement> qualifiers = new SmartList<PsiElement>();
final List<ResolveResult[]> qualifiers = new SmartList<ResolveResult[]>();
final ResolveCache resolveCache = ResolveCache.getInstance(containingFile.getProject());
qualifier.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
@@ -238,7 +230,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
if (!(element instanceof PsiReferenceExpressionImpl)) return;
PsiReferenceExpressionImpl expression = (PsiReferenceExpressionImpl)element;
resolveCache.resolveWithCaching(expression, INSTANCE, false, false, containingFile);
qualifiers.add(expression);
qualifiers.add(resolveCache.resolveWithCaching(expression, INSTANCE, false, false, containingFile));
}
});
return qualifiers;
@@ -20,7 +20,7 @@ import groovy.lang.GroovyClassLoader
import junit.framework.{TestResult, TestCase}
import org.scalacheck.Arbitrary.arbitrary
import org.scalacheck.Gen._
import org.scalacheck.Prop.forAll
import org.scalacheck.Prop.{forAll, BooleanOperators}
import org.scalacheck._
import scala.collection.JavaConversions._
@@ -40,6 +40,7 @@ object IndexTestGenerator {
const(Gc),
const(Commit),
const(Save),
const(PsiChange),
for (withImport <- arbitrary[Boolean];
viaDocument <- arbitrary[Boolean])
yield TextChange(viaDocument, withImport),
@@ -49,7 +50,13 @@ object IndexTestGenerator {
arbitrary[Boolean] map UpdateDocumentRef
)
val propIndexTest = forAll(Gen.nonEmptyListOf(genAction)) { actions =>
new IndexTestSeq(actions).isSuccessful
containsChange(actions) ==> new IndexTestSeq(actions).isSuccessful
}
def containsChange(actions: List[Action]) = actions.exists {
case TextChange(_, _) => true
case PsiChange => true
case _ => false
}
def main(args: Array[String]) {
@@ -62,14 +69,13 @@ case class IndexTestSeq(actions: List[Action]) {
val sb = StringBuilder.newBuilder
sb.append(prefix)
sb.append(
s"""
s"""
|public void "$testName"() {
|def vFile =
| myFixture.addFileToProject("Foo.java", "class Foo {}").virtualFile
|def psiFile = myFixture.addFileToProject("Foo.java", "class Foo {}")
|def vFile = psiFile.virtualFile
|def lastPsiName = "Foo"
|long counterBefore
|Document document
|PsiFile psiFile
|ASTNode astNode
|PsiClass psiClass
|def scope = GlobalSearchScope.allScope(project)
@@ -86,6 +92,15 @@ case class IndexTestSeq(actions: List[Action]) {
s"""PsiDocumentManager.getInstance(project).commitAllDocuments()
|lastPsiName = "$docClassName"
|""".stripMargin)
case PsiChange =>
sb.append(
s"""PsiDocumentManager.getInstance(project).commitAllDocuments()
|lastPsiName = "$docClassName"
|myFixture.findClass("$docClassName").add(
| elementFactory.createMethod("foo", PsiType.VOID))
|PostprocessReformattingAspect.getInstance(getProject()).
| doPostponedFormatting()
|""".stripMargin)
case Save =>
sb.append("FileDocumentManager.instance.saveAllDocuments()\n")
case UpdatePsiClassRef(load) =>
@@ -144,6 +159,7 @@ case class IndexTestSeq(actions: List[Action]) {
|import com.intellij.openapi.util.Ref
|import com.intellij.openapi.vfs.VfsUtil
|import com.intellij.psi.*
|import com.intellij.psi.impl.source.*
|import com.intellij.psi.search.GlobalSearchScope
|import com.intellij.testFramework.PlatformTestUtil
|import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
@@ -186,3 +202,4 @@ case class UpdatePsiClassRef(load: Boolean) extends Action
case class UpdatePsiFileRef(load: Boolean) extends Action
case class UpdateDocumentRef(load: Boolean) extends Action
case class UpdateASTNodeRef(load: Boolean) extends Action
case object PsiChange extends Action
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -73,7 +73,7 @@ public interface SchemesManager <T extends Scheme, E extends ExternalizableSchem
}
@Override
public Scheme findSchemeByName(final String schemeName) {
public Scheme findSchemeByName(String schemeName) {
return null;
}
@@ -82,8 +82,7 @@ public interface SchemesManager <T extends Scheme, E extends ExternalizableSchem
}
@Override
public void setCurrentSchemeName(final String schemeName) {
public void setCurrentSchemeName(String schemeName) {
}
@Override
@@ -92,8 +91,7 @@ public interface SchemesManager <T extends Scheme, E extends ExternalizableSchem
}
@Override
public void removeScheme(final Scheme scheme) {
public void removeScheme(@NotNull Scheme scheme) {
}
@Override
@@ -104,7 +102,7 @@ public interface SchemesManager <T extends Scheme, E extends ExternalizableSchem
@Override
@NotNull
public Collection loadSharedSchemes(final Collection currentSchemeList) {
public Collection loadSharedSchemes(Collection currentSchemeList) {
return loadSharedSchemes();
}
@@ -114,7 +112,8 @@ public interface SchemesManager <T extends Scheme, E extends ExternalizableSchem
}
};
@NotNull Collection<E> loadSchemes();
@NotNull
Collection<E> loadSchemes();
@Deprecated
@SuppressWarnings({"unused", "deprecation"})
@@ -158,9 +157,10 @@ public interface SchemesManager <T extends Scheme, E extends ExternalizableSchem
@Nullable
T getCurrentScheme();
void removeScheme(final T scheme);
void removeScheme(@NotNull T scheme);
@NotNull Collection<String> getAllSchemeNames();
@NotNull
Collection<String> getAllSchemeNames();
File getRootDirectory();
}
@@ -73,15 +73,16 @@ public abstract class AbstractSchemesManager<T extends Scheme, E extends Externa
@Override
public void clearAllSchemes() {
for (T t : getAllSchemes()) {
removeScheme(t);
for (T myScheme : mySchemes) {
onSchemeDeleted(myScheme);
}
mySchemes.clear();
}
@Override
@NotNull
public List<T> getAllSchemes() {
return new ArrayList<T>(mySchemes);
return Collections.unmodifiableList(mySchemes);
}
@Override
@@ -112,37 +113,28 @@ public abstract class AbstractSchemesManager<T extends Scheme, E extends Externa
}
@Override
public void removeScheme(final T scheme) {
String schemeName = scheme.getName();
Scheme toDelete = findSchemeToDelete(schemeName);
public void removeScheme(@NotNull T scheme) {
for (int i = 0, n = mySchemes.size(); i < n; i++) {
T s = mySchemes.get(i);
if (scheme.getName().equals(s.getName())) {
onSchemeDeleted(s);
mySchemes.remove(i);
break;
}
}
}
//noinspection SuspiciousMethodCalls
mySchemes.remove(toDelete);
protected void onSchemeDeleted(@NotNull Scheme toDelete) {
if (myCurrentScheme == toDelete) {
myCurrentScheme = null;
}
onSchemeDeleted(toDelete);
}
protected abstract void onSchemeDeleted(@NotNull Scheme toDelete);
private Scheme findSchemeToDelete(final String schemeName) {
for (T scheme : mySchemes) {
if (Comparing.equal(schemeName, scheme.getName())) return scheme;
}
return null;
}
@Override
@NotNull
public Collection<String> getAllSchemeNames() {
return getAllSchemeNames(mySchemes);
}
public Collection<String> getAllSchemeNames(@NotNull Collection<T> schemes) {
Set<String> names = new THashSet<String>(schemes.size());
for (T scheme : schemes) {
List<String> names = new ArrayList<String>(mySchemes.size());
for (T scheme : mySchemes) {
names.add(scheme.getName());
}
return names;
@@ -181,6 +173,10 @@ public abstract class AbstractSchemesManager<T extends Scheme, E extends Externa
return false;
}
@Override
public void exportScheme(@NotNull final E scheme, final String name, final String description) {
}
protected boolean isExternalizable(final T scheme) {
return scheme instanceof ExternalizableScheme;
}
@@ -193,7 +193,7 @@ public class InspectionProfileManagerImpl extends InspectionProfileManager imple
@Override
public void initProfiles() {
if (myProfilesAreInitialized.getAndSet(true)) {
if (mySchemesManager.getAllSchemeNames().isEmpty()) {
if (mySchemesManager.getAllSchemes().isEmpty()) {
createDefaultProfile();
}
return;
@@ -201,8 +201,7 @@ public class InspectionProfileManagerImpl extends InspectionProfileManager imple
if (!LOAD_PROFILES) return;
mySchemesManager.loadSchemes();
final Collection<Profile> profiles = mySchemesManager.getAllSchemes();
Collection<Profile> profiles = mySchemesManager.getAllSchemes();
if (profiles.isEmpty()) {
createDefaultProfile();
}
@@ -337,8 +336,7 @@ public class InspectionProfileManagerImpl extends InspectionProfileManager imple
@Override
@NotNull
public String[] getAvailableProfileNames() {
final Collection<String> names = mySchemesManager.getAllSchemeNames();
return ArrayUtil.toStringArray(names);
return ArrayUtil.toStringArray(mySchemesManager.getAllSchemeNames());
}
@Override
@@ -346,11 +344,6 @@ public class InspectionProfileManagerImpl extends InspectionProfileManager imple
return getProfile(name, true);
}
@NotNull
public SchemesManager<Profile, InspectionProfileImpl> getSchemesManager() {
return mySchemesManager;
}
public static void onProfilesChanged() {
//cleanup caches blindly for all projects in case ide profile was modified
for (final Project project : ProjectManager.getInstance().getOpenProjects()) {
@@ -20,9 +20,12 @@ package com.intellij.tools;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.components.ExportableApplicationComponent;
import com.intellij.openapi.components.RoamingType;
import com.intellij.openapi.options.*;
import com.intellij.openapi.options.SchemeProcessor;
import com.intellij.openapi.options.SchemesManager;
import com.intellij.openapi.options.SchemesManagerFactory;
import com.intellij.openapi.util.Comparing;
import com.intellij.util.ArrayUtil;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -77,7 +80,7 @@ public abstract class BaseToolManager<T extends Tool> implements ExportableAppli
}
public List<T> getTools() {
ArrayList<T> result = new ArrayList<T>();
List<T> result = new SmartList<T>();
for (ToolsGroup group : mySchemesManager.getAllSchemes()) {
result.addAll(group.getElements());
}
@@ -24,7 +24,6 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class CompoundScheme<T extends SchemeElement> implements ExternalizableScheme {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.options.CompoundScheme");
@@ -49,8 +48,6 @@ public class CompoundScheme<T extends SchemeElement> implements ExternalizableSc
}
}
public List<T> getElements() {
return Collections.unmodifiableList(new ArrayList<T>(myElements));
}
@@ -51,8 +51,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
@@ -214,18 +213,17 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Name
@NotNull
@Override
public EditorColorsScheme[] getAllSchemes() {
List<EditorColorsScheme> schemes = new ArrayList<EditorColorsScheme>(mySchemesManager.getAllSchemes());
Collections.sort(schemes, new Comparator<EditorColorsScheme>() {
List<EditorColorsScheme> schemes = mySchemesManager.getAllSchemes();
EditorColorsScheme[] result = schemes.toArray(new EditorColorsScheme[schemes.size()]);
Arrays.sort(result, new Comparator<EditorColorsScheme>() {
@Override
public int compare(@NotNull EditorColorsScheme s1, @NotNull EditorColorsScheme s2) {
if (isDefaultScheme(s1) && !isDefaultScheme(s2)) return -1;
if (!isDefaultScheme(s1) && isDefaultScheme(s2)) return 1;
return s1.getName().compareToIgnoreCase(s2.getName());
}
});
return schemes.toArray(new EditorColorsScheme[schemes.size()]);
return result;
}
@Override
@@ -164,15 +164,18 @@ public class KeymapManagerImpl extends KeymapManagerEx implements PersistentStat
}
public void removeAllKeymapsExceptUnmodifiable() {
for (Keymap keymap : mySchemesManager.getAllSchemes()) {
List<Keymap> schemes = mySchemesManager.getAllSchemes();
for (int i = schemes.size() - 1; i >= 0; i--) {
Keymap keymap = schemes.get(i);
if (keymap.canModify()) {
mySchemesManager.removeScheme(keymap);
}
}
mySchemesManager.setCurrentSchemeName(null);
Collection<Keymap> keymaps = mySchemesManager.getAllSchemes();
if (keymaps.size() > 0) {
if (!keymaps.isEmpty()) {
mySchemesManager.setCurrentSchemeName(keymaps.iterator().next().getName());
}
}
@@ -431,10 +431,6 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
return myFileSpec + '/' + subPath;
}
@Override
public void exportScheme(@NotNull final E scheme, final String name, final String description) throws WriteExternalException, IOException {
}
@Override
public boolean isImportAvailable() {
return false;
@@ -632,6 +628,8 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
@Override
protected void onSchemeDeleted(@NotNull Scheme toDelete) {
super.onSchemeDeleted(toDelete);
if (toDelete instanceof ExternalizableScheme) {
ContainerUtilRt.addIfNotNull(myFilesToDelete, ((ExternalizableScheme)toDelete).getExternalInfo().getCurrentFileName());
}