make CompositeFoldingBuilder more dumb-aware, provide a fallback if INRE is thrown (IDEA-165853)

This commit is contained in:
peter
2017-01-19 14:54:19 +01:00
parent 0d9f16e6f2
commit 7c63d91d3b
2 changed files with 34 additions and 9 deletions
@@ -18,12 +18,14 @@ package com.intellij.lang.folding;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.PossiblyDumbAware;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
@@ -38,7 +40,7 @@ import java.util.Set;
* @see LanguageFolding
* @since 9.0
*/
public class CompositeFoldingBuilder extends FoldingBuilderEx implements DumbAware {
public class CompositeFoldingBuilder extends FoldingBuilderEx implements PossiblyDumbAware {
public static final Key<FoldingBuilder> FOLDING_BUILDER = new Key<FoldingBuilder>("FOLDING_BUILDER");
private final List<FoldingBuilder> myBuilders;
@@ -56,7 +58,7 @@ public class CompositeFoldingBuilder extends FoldingBuilderEx implements DumbAwa
final List<FoldingDescriptor> descriptors = new ArrayList<FoldingDescriptor>();
final Set<TextRange> rangesCoveredByDescriptors = ContainerUtil.newHashSet();
for (FoldingBuilder builder : myBuilders) {
for (FoldingBuilder builder : DumbService.getInstance(root.getProject()).filterByDumbAwareness(myBuilders)) {
for (FoldingDescriptor descriptor : LanguageFolding.buildFoldingDescriptors(builder, root, document, quick)) {
if (rangesCoveredByDescriptors.add(descriptor.getRange())) {
descriptor.getElement().putUserData(FOLDING_BUILDER, builder);
@@ -71,24 +73,38 @@ public class CompositeFoldingBuilder extends FoldingBuilderEx implements DumbAwa
@Override
public String getPlaceholderText(@NotNull ASTNode node, @NotNull TextRange range) {
final FoldingBuilder builder = node.getUserData(FOLDING_BUILDER);
return builder == null ? node.getText() : builder instanceof FoldingBuilderEx
? ((FoldingBuilderEx)builder).getPlaceholderText(node, range)
: builder.getPlaceholderText(node);
return !mayUseBuilder(node, builder) ? node.getText() :
builder instanceof FoldingBuilderEx ? ((FoldingBuilderEx)builder).getPlaceholderText(node, range)
: builder.getPlaceholderText(node);
}
@Override
public String getPlaceholderText(@NotNull ASTNode node) {
final FoldingBuilder builder = node.getUserData(FOLDING_BUILDER);
return builder == null ? node.getText() : builder.getPlaceholderText(node);
return !mayUseBuilder(node, builder) ? node.getText() : builder.getPlaceholderText(node);
}
public boolean isCollapsedByDefault(@NotNull ASTNode node) {
final FoldingBuilder builder = node.getUserData(FOLDING_BUILDER);
return builder != null && builder.isCollapsedByDefault(node);
return mayUseBuilder(node, builder) && builder.isCollapsedByDefault(node);
}
private static boolean mayUseBuilder(@NotNull ASTNode node, @Nullable FoldingBuilder builder) {
return builder != null && (DumbService.isDumbAware(builder) || !DumbService.isDumb(node.getPsi().getProject()));
}
@Override
public String toString() {
return getClass().getSimpleName() + myBuilders;
}
@Override
public boolean isDumbAware() {
for (FoldingBuilder builder : myBuilders) {
if (DumbService.isDumbAware(builder)) {
return true;
}
}
return false;
}
}
@@ -19,13 +19,16 @@ package com.intellij.codeInsight.folding.impl;
import com.intellij.lang.Language;
import com.intellij.lang.folding.FoldingBuilder;
import com.intellij.lang.folding.LanguageFolding;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class FoldingPolicy {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.folding.impl.FoldingPolicy");
private static final GenericElementSignatureProvider GENERIC_PROVIDER = new GenericElementSignatureProvider();
@@ -34,7 +37,13 @@ public class FoldingPolicy {
public static boolean isCollapseByDefault(PsiElement element) {
final Language lang = element.getLanguage();
final FoldingBuilder foldingBuilder = LanguageFolding.INSTANCE.forLanguage(lang);
return foldingBuilder != null && foldingBuilder.isCollapsedByDefault(element.getNode());
try {
return foldingBuilder != null && foldingBuilder.isCollapsedByDefault(element.getNode());
}
catch (IndexNotReadyException e) {
LOG.error(e);
return false;
}
}
@Nullable