diff --git a/platform/platform-impl/src/com/intellij/ide/TypePresentationServiceImpl.java b/platform/platform-impl/src/com/intellij/ide/TypePresentationServiceImpl.java index 82696e8ce6e3..6fb531607124 100644 --- a/platform/platform-impl/src/com/intellij/ide/TypePresentationServiceImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/TypePresentationServiceImpl.java @@ -17,7 +17,9 @@ package com.intellij.ide; import com.intellij.ide.presentation.Presentation; import com.intellij.ide.presentation.PresentationProvider; +import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.util.ClassExtension; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.NullableLazyValue; import com.intellij.openapi.util.text.StringUtil; @@ -36,6 +38,9 @@ import java.util.Set; */ public class TypePresentationServiceImpl extends TypePresentationService { + private static final ExtensionPointName PROVIDER_EP = ExtensionPointName.create("com.intellij.presentationProvider"); + private static final ClassExtension PROVIDERS = new ClassExtension<>(PROVIDER_EP.getName()); + @Override public Icon getIcon(Object o) { return getIcon(o.getClass(), o); @@ -88,7 +93,11 @@ public class TypePresentationServiceImpl extends TypePresentationService { private PresentationTemplate createPresentationTemplate(Class type) { Presentation presentation = type.getAnnotation(Presentation.class); if (presentation != null) { - return new PresentationTemplateImpl(presentation, type); + return new AnnotationBasedTemplate(presentation, type); + } + PresentationProvider provider = PROVIDERS.forClass(type); + if (provider != null) { + return new ProviderBasedTemplate(provider); } final NullableLazyValue icon = myIcons.get(type.getName()); final NullableLazyValue typeName = myNames.get(type.getName()); @@ -120,13 +129,13 @@ public class TypePresentationServiceImpl extends TypePresentationService { private final Map> myIcons = new HashMap<>(); private final Map> myNames = new HashMap<>(); - @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) private final Map> mySuperClasses = ConcurrentFactoryMap.createMap(key-> { LinkedHashSet templates = new LinkedHashSet<>(); walkSupers(key, new LinkedHashSet<>(), templates); return templates; } ); + private void walkSupers(Class aClass, Set classes, Set templates) { if (!classes.add(aClass)) { return; @@ -142,10 +151,65 @@ public class TypePresentationServiceImpl extends TypePresentationService { } } - /** - * @author Dmitry Avdeev - */ - public static class PresentationTemplateImpl implements PresentationTemplate { + /** @noinspection unchecked*/ + public static class ProviderBasedTemplate implements PresentationTemplate { + + private final PresentationProvider myProvider; + + public ProviderBasedTemplate(PresentationProvider provider) { + myProvider = provider; + } + + @Nullable + @Override + public Icon getIcon(Object o, int flags) { + return myProvider instanceof PresentationTemplate ? + ((PresentationTemplate)myProvider).getIcon(o, flags) : + myProvider.getIcon(o); + } + + @Nullable + @Override + public String getName(Object o) { + return myProvider.getName(o); + } + + @Nullable + @Override + public String getTypeName() { + return myProvider instanceof PresentationTemplate ? + ((PresentationTemplate)myProvider).getTypeName() : null; + } + + @Override + public String getTypeName(Object o) { + return myProvider.getTypeName(o); + } + } + + public static class PresentationTemplateImpl extends ProviderBasedTemplate { + + public PresentationTemplateImpl(Presentation presentation, Class aClass) { + super(new AnnotationBasedTemplate(presentation, aClass)); + } + } + + /** @noinspection unchecked*/ + private static class AnnotationBasedTemplate extends PresentationProvider implements PresentationTemplate { + + private final Presentation myPresentation; + private final Class myClass; + + AnnotationBasedTemplate(Presentation presentation, Class aClass) { + myPresentation = presentation; + myClass = aClass; + } + + @Override + @Nullable + public Icon getIcon(Object o) { + return getIcon(o, 0); + } @Override @Nullable @@ -184,14 +248,6 @@ public class TypePresentationServiceImpl extends TypePresentationService { return namer == null ? null : namer.getName(o); } - public PresentationTemplateImpl(Presentation presentation, Class aClass) { - this.myPresentation = presentation; - myClass = aClass; - } - - private final Presentation myPresentation; - private final Class myClass; - private final NullableLazyValue myIcon = new NullableLazyValue() { @Override protected Icon compute() { diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 674b722410d9..294e874d650f 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -826,8 +826,10 @@ - + + +