Merge remote-tracking branch 'origin/master'

This commit is contained in:
Roman Shevchenko
2017-04-26 19:28:34 +02:00
14 changed files with 130 additions and 59 deletions
@@ -85,6 +85,8 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp
private final ReentrantReadWriteLock myLock = new ReentrantReadWriteLock();
private final Lock myReadDataLock = myLock.readLock();
private final Lock myOpenCloseLock = myLock.writeLock();
// index build start/finish callbacks are not ordered, so "build1 started" -> "build2 started" -> "build1 finished" -> "build2 finished" is expected sequence
private int myActiveBuilds = 0;
private volatile CompilerReferenceReader myReader;
@@ -103,8 +105,7 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp
@Override
public void buildStarted(Project project, UUID sessionId, boolean isAutomake) {
if (project == myProject) {
myDirtyScopeHolder.compilerActivityStarted();
closeReaderIfNeed(false);
closeReaderIfNeed(IndexCloseReason.COMPILATION_STARTED);
}
}
});
@@ -129,9 +130,7 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp
return context.getCompileScope().getAffectedModules();
});
if (compilationModules == null) return;
myDirtyScopeHolder.compilerActivityFinished();
myCompilationCount.increment();
openReaderIfNeed();
openReaderIfNeed(IndexOpenReason.COMPILATION_FINISHED);
};
executeOnBuildThread(compilationFinished);
}
@@ -150,16 +149,16 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp
isUpToDate = false;
}
executeOnBuildThread(() -> {
myDirtyScopeHolder.upToDateChecked(isUpToDate);
if (isUpToDate) {
myCompilationCount.increment();
openReaderIfNeed();
openReaderIfNeed(IndexOpenReason.UP_TO_DATE_CACHE);
} else {
markAsOutdated();
}
});
});
}
Disposer.register(myProject, () -> closeReaderIfNeed(false));
Disposer.register(myProject, () -> closeReaderIfNeed(IndexCloseReason.PROJECT_CLOSED));
}
}
@@ -482,11 +481,15 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp
}
}
private void closeReaderIfNeed(boolean removeIndex) {
private void closeReaderIfNeed(IndexCloseReason reason) {
myOpenCloseLock.lock();
try {
if (reason == IndexCloseReason.COMPILATION_STARTED) {
myActiveBuilds++;
myDirtyScopeHolder.compilerActivityStarted();
}
if (myReader != null) {
myReader.close(removeIndex);
myReader.close(reason == IndexCloseReason.AN_EXCEPTION);
myReader = null;
}
} finally {
@@ -494,14 +497,41 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp
}
}
private void openReaderIfNeed() {
private void openReaderIfNeed(IndexOpenReason reason) {
myCompilationCount.increment();
myOpenCloseLock.lock();
try {
if (myProject.isOpen()) {
LOG.assertTrue(myReader == null, "isAutoMakeEnabled = " + ReadAction.compute(() -> CompilerWorkspaceConfiguration.getInstance(myProject).MAKE_PROJECT_ON_SAVE));
try {
switch (reason) {
case UP_TO_DATE_CACHE:
myDirtyScopeHolder.upToDateChecked(true);
break;
case COMPILATION_FINISHED:
myDirtyScopeHolder.compilerActivityFinished();
}
}
catch (RuntimeException e) {
--myActiveBuilds;
throw e;
}
if ((--myActiveBuilds == 0) && myProject.isOpen()) {
LOG.assertTrue(myReader == null, "isAutoMakeEnabled = " +
ReadAction
.compute(() -> CompilerWorkspaceConfiguration.getInstance(myProject).MAKE_PROJECT_ON_SAVE));
myReader = CompilerReferenceReader.create(myProject);
LOG.info("backward reference index reader " + (myReader == null ? "doesn't exist" : "is opened"));
}
}
finally {
myOpenCloseLock.unlock();
}
}
private void markAsOutdated() {
myOpenCloseLock.lock();
try {
--myActiveBuilds;
myDirtyScopeHolder.upToDateChecked(false);
} finally {
myOpenCloseLock.unlock();
}
@@ -674,7 +704,7 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp
LOG.error("an exception during " + actionName + " calculation", e);
Throwable unwrapped = e instanceof RuntimeException ? e.getCause() : e;
if (requireIndexRebuild(unwrapped)) {
closeReaderIfNeed(true);
closeReaderIfNeed(IndexCloseReason.AN_EXCEPTION);
}
return null;
}
@@ -691,4 +721,15 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp
exception instanceof StorageException ||
exception instanceof IOException;
}
private enum IndexCloseReason {
AN_EXCEPTION,
COMPILATION_STARTED,
PROJECT_CLOSED
}
private enum IndexOpenReason {
COMPILATION_FINISHED,
UP_TO_DATE_CACHE
}
}
@@ -34,11 +34,14 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ProcessingContext;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static com.intellij.patterns.PsiJavaPatterns.or;
@@ -65,21 +68,27 @@ public class MethodsChainsCompletionContributor extends CompletionContributor {
if (!Registry.is(REGISTRY_KEY)) return;
ChainCompletionContext completionContext = extractContext(parameters);
if (completionContext == null) return;
List<LookupElement> elementsFoundByMethodsChainsSearch = searchForLookups(completionContext);
final Set<PsiMethod> alreadySuggested = new THashSet<>();
if (!IS_UNIT_TEST_MODE) {
result.runRemainingContributors(parameters, completionResult -> {
LookupElement lookupElement = completionResult.getLookupElement();
PsiElement lookupElementPsi = lookupElement.getPsiElement();
if (lookupElementPsi != null) {
for (LookupElement element : elementsFoundByMethodsChainsSearch) {
if (lookupElementPsi.isEquivalentTo(element.getPsiElement())) {
elementsFoundByMethodsChainsSearch.remove(element);
break;
}
}
PsiElement psi = lookupElement.getPsiElement();
if (psi instanceof PsiMethod) {
alreadySuggested.add((PsiMethod)psi);
}
result.passResult(completionResult);
});
}
List<LookupElement> elementsFoundByMethodsChainsSearch = searchForLookups(completionContext);
if (!IS_UNIT_TEST_MODE) {
Iterator<LookupElement> it = elementsFoundByMethodsChainsSearch.iterator();
while (it.hasNext()) {
LookupElement lookupElement = it.next();
PsiElement psi = lookupElement.getPsiElement();
if (psi instanceof PsiMethod && alreadySuggested.contains(psi)) {
it.remove();
}
}
} else {
result.stopHere();
}
@@ -15,16 +15,22 @@
*/
package com.intellij.compiler.chainsSearch.context;
import com.intellij.ide.hierarchy.JavaHierarchyUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.backwardRefs.SignatureData;
import java.util.Set;
/**
* @author Dmitry Batkovich
*/
public class ChainSearchTarget {
private static final Set<String> EXCLUDED_PACKAGES = ContainerUtil.set("java.lang", "java.util.function");
private final String myClassQName;
private final byte[] myAcceptedArrayKinds;
private final PsiType myPsiType;
@@ -94,8 +100,10 @@ public class ChainSearchTarget {
@Nullable
private static ChainSearchTarget create(PsiClassType classType) {
PsiClass resolvedClass = PsiUtil.resolveClassInClassTypeOnly(classType);
if (resolvedClass == null || resolvedClass instanceof PsiTypeParameter || LambdaUtil.isFunctionalClass(resolvedClass)) return null;
String packageName = JavaHierarchyUtil.getPackageName(resolvedClass);
if (packageName == null || EXCLUDED_PACKAGES.contains(packageName)) return null;
byte iteratorKind = SignatureData.ZERO_DIM;
if (resolvedClass == null) return null;
String iteratorClass = getIteratorKind(resolvedClass);
if (iteratorClass != null) {
resolvedClass = PsiUtil.resolveClassInClassTypeOnly(PsiUtil.substituteTypeParameter(classType, iteratorClass, 0, false));
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.changeSignature.inCallers;
import com.intellij.ide.hierarchy.JavaHierarchyUtil;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.presentation.java.ClassPresentationUtil;
@@ -27,7 +28,6 @@ import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.JBColor;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashSet;
@@ -93,17 +93,9 @@ public class JavaMethodNode extends MethodNodeBase<PsiMethod> {
renderer.append(buffer.toString(), attributes);
if (containingClass != null) {
final String packageName = getPackageName(containingClass);
final String packageName = JavaHierarchyUtil.getPackageName(containingClass);
renderer.append(" (" + packageName + ")", new SimpleTextAttributes(SimpleTextAttributes.STYLE_ITALIC, JBColor.GRAY));
}
}
@Nullable
private static String getPackageName(final PsiClass aClass) {
final PsiFile file = aClass.getContainingFile();
if (file instanceof PsiJavaFile) {
return ((PsiJavaFile)file).getPackageName();
}
return null;
}
}
@@ -12,6 +12,8 @@ class JavaPsiFacade {
interface PsiElement {
PsiClass getContainingClass();
void mm();
}
interface PsiClass extends PsiElement {
@@ -12,6 +12,8 @@ class JavaPsiFacade {
interface PsiElement {
PsiClass getContainingClass();
void mm();
}
interface PsiClass extends PsiElement {
@@ -41,6 +41,8 @@ class JavaPsiFacade {
interface PsiElement {
PsiClass getContainingClass();
void mm();
}
interface PsiClass extends PsiElement {
@@ -12,6 +12,8 @@ class JavaPsiFacade {
interface PsiElement {
PsiClass getContainingClass();
void m();
}
interface PsiClass extends PsiElement {
@@ -31,6 +31,8 @@ class JavaPsiFacade {
interface PsiElement {
PsiClass getContainingClass();
void m();
}
interface PsiClass extends PsiElement {
@@ -306,29 +306,14 @@ abstract class ComponentStoreImpl : IComponentStore {
val defaultState = if (stateSpec.defaultStateAsResource) getDefaultState(component, name, stateClass) else null
if (loadPolicy == StateLoadPolicy.LOAD) {
val storageSpecs = getStorageSpecs(component, stateSpec, StateStorageOperation.READ)
val storageChooser = component as? StateStorageChooserEx
for (storageSpec in storageSpecs) {
for (storageSpec in getStorageSpecs(component, stateSpec, StateStorageOperation.READ)) {
if (storageChooser?.getResolution(storageSpec, StateStorageOperation.READ) == Resolution.SKIP) {
continue
}
val storage = storageManager.getStateStorage(storageSpec)
// todo "ProjectModuleManager" investigate why after loadState we get empty state on getState, test CMakeWorkspaceContentRootsTest
// todo fix FacetManager
// use.loaded.state.as.existing used in upsource
val stateGetter = if (isUseLoadedStateAsExisting(storage) &&
name != "AntConfiguration" &&
name != "ProjectModuleManager" &&
name != "FacetManager" &&
name != "NewModuleRootManager" /* will be changed only on actual user change, so, to speed up module loading, skip it */ &&
name != "DeprecatedModuleOptionManager" /* doesn't make sense to check it */ &&
SystemPropertyUtil.getBoolean("use.loaded.state.as.existing", true)) {
(storage as? StorageBaseEx<*>)?.createGetSession(component, name, stateClass)
}
else {
null
}
val stateGetter = if (isUseLoadedStateAsExisting(storage, name)) (storage as? StorageBaseEx<*>)?.createGetSession(component, name, stateClass) else null
var state = if (stateGetter == null) storage.getState(component, name, stateClass, defaultState, reloadData) else stateGetter.getState(defaultState)
if (state == null) {
if (changedStorages != null && changedStorages.contains(storage)) {
@@ -361,6 +346,19 @@ abstract class ComponentStoreImpl : IComponentStore {
return true
}
// todo "ProjectModuleManager" investigate why after loadState we get empty state on getState, test CMakeWorkspaceContentRootsTest
// todo fix FacetManager
// use.loaded.state.as.existing used in upsource
private fun isUseLoadedStateAsExisting(storage: StateStorage, name: String): Boolean {
return isUseLoadedStateAsExisting(storage) &&
name != "AntConfiguration" &&
name != "ProjectModuleManager" &&
name != "FacetManager" &&
name != "NewModuleRootManager" /* will be changed only on actual user change, so, to speed up module loading, skip it */ &&
name != "DeprecatedModuleOptionManager" /* doesn't make sense to check it */ &&
SystemPropertyUtil.getBoolean("use.loaded.state.as.existing", true)
}
protected open fun isUseLoadedStateAsExisting(storage: StateStorage): Boolean = (storage as? XmlElementStorage)?.roamingType != RoamingType.DISABLED
protected open fun getPathMacroManagerForDefaults(): PathMacroManager? = null
@@ -223,7 +223,7 @@ open class StateStorageManagerImpl(private val rootTagName: String,
@Suppress("DEPRECATION") stateSplitter: Class<out StateSplitter>,
exclusive: Boolean = false): StateStorage {
if (storageClass != StateStorage::class.java) {
val constructor = storageClass.constructors.get(0)!!
val constructor = storageClass.constructors.first()
constructor.isAccessible = true
return constructor.newInstance(componentManager!!, this) as StateStorage
}
@@ -34,6 +34,7 @@ import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.templateLanguages.TemplateDataLanguagePatterns;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import com.intellij.util.ui.JBDimension;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -174,7 +175,7 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
@Override
public Dimension getPreferredSize() {
return new Dimension(0, 20);
return new JBDimension(0, 20);
}
}
@@ -759,7 +759,7 @@ public abstract class DialogWrapper {
@NotNull
private JButton createJOptionsButton(@NotNull OptionAction action) {
JBOptionButton optionButton = new JBOptionButton(action, action.getOptions());
optionButton.setOkToProcessDefaultMnemonics(true);
optionButton.setOkToProcessDefaultMnemonics(false);
optionButton.setOptionTooltipText(
"Press " + KeymapUtil.getKeystrokeText(SHOW_OPTION_KEYSTROKE) + " to expand or use a mnemonic of a contained action");
@@ -775,7 +775,7 @@ public abstract class DialogWrapper {
final JBOptionButton buttonToActivate = eachInfo.getButton();
buttonToActivate.showPopup(eachInfo.getAction(), true);
}
}.registerCustomShortcutSet(MnemonicHelper.createShortcut(mnemonic), optionButton, myDisposable);
}.registerCustomShortcutSet(MnemonicHelper.createShortcut(mnemonic), rootPane, myDisposable);
}
}
}
@@ -23,6 +23,7 @@ import com.intellij.openapi.editor.colors.*;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
@@ -62,10 +63,21 @@ public class EditorColorsSchemeImplTest extends EditorColorSchemeTestCase {
}
}
/**
* TODO<rv> FIX PROPERLY
* This is a hack: since font name is taken from default scheme (why?) where it is explicitly defined as "Dejavu Sans", font names
* do not match because default font name on linux in headless environment falls back to WINDOWS_DEFAULT_FONT_FAMILY (why?)
*/
private static String substLinuxFontName(@NotNull String fontName) {
return SystemInfo.isLinux && GraphicsEnvironment.isHeadless() && FontPreferences.LINUX_DEFAULT_FONT_FAMILY.equals(fontName)?
FontPreferences.WINDOWS_DEFAULT_FONT_FAMILY :
fontName;
}
private void assertEditorFontsEqual(@NotNull String fontName, int fontSize) {
assertEquals(fontName, myScheme.getEditorFontName());
assertEquals(fontName, substLinuxFontName(myScheme.getEditorFontName()));
assertEquals(fontSize, myScheme.getEditorFontSize());
assertEquals(fontName, myScheme.getConsoleFontName());
assertEquals(fontName, substLinuxFontName(myScheme.getConsoleFontName()));
assertEquals(fontSize, myScheme.getConsoleFontSize());
}