From 58d9375a258ae76de4b6ee6c6884e73d46576569 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 23 May 2014 22:03:15 +0400 Subject: [PATCH] Set up rendering for structure elements --- .../jet/renderer/DescriptorRenderer.java | 5 +- .../renderer/DescriptorRendererBuilder.java | 30 +++- .../jet/renderer/DescriptorRendererImpl.java | 83 +++++++--- .../JetStructureViewElement.java | 145 +++++++++--------- .../structureView/fileStructure/Render.after | 40 +++++ .../structureView/fileStructure/Render.kt | 54 +++++++ .../fileStructure/SeveralClasses.after | 8 +- .../structureView/fileStructure/Simple.after | 10 +- .../KotlinFileStructureTestGenerated.java | 9 +- 9 files changed, 278 insertions(+), 106 deletions(-) create mode 100644 idea/testData/structureView/fileStructure/Render.after create mode 100644 idea/testData/structureView/fileStructure/Render.kt diff --git a/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRenderer.java b/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRenderer.java index 17f5e783c09..a51522b548a 100644 --- a/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRenderer.java +++ b/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRenderer.java @@ -56,9 +56,12 @@ public interface DescriptorRenderer extends Renderer { DescriptorRenderer STARTS_FROM_NAME_WITH_SHORT_TYPES = new DescriptorRendererBuilder() .setWithDefinedIn(false) - .setUnitReturnType(false) .setModifiers() .setShortNames(true) + .setWithoutTypeParameters(true) + .setWithoutFunctionParameterNames(true) + .setReceiverAfterName(true) + .setRenderClassObjectName(true) .setStartFromName(true).build(); DescriptorRenderer FQ_NAMES_IN_TYPES = new DescriptorRendererBuilder().build(); diff --git a/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererBuilder.java b/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererBuilder.java index 0493a23b1e7..c4e0fb13b38 100644 --- a/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererBuilder.java +++ b/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2013 JetBrains s.r.o. + * Copyright 2010-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. @@ -39,6 +39,9 @@ public class DescriptorRendererBuilder { private boolean uninferredTypeParameterAsName = false; private boolean includePropertyConstant = false; private boolean includeSynthesizedParameterNames = true; + private boolean withoutFunctionParameterNames = false; + private boolean withoutTypeParameters = false; + @NotNull private DescriptorRenderer.OverrideRenderingPolicy overrideRenderingPolicy = DescriptorRenderer.OverrideRenderingPolicy.RENDER_OPEN; @NotNull @@ -47,6 +50,8 @@ public class DescriptorRendererBuilder { private DescriptorRenderer.TextFormat textFormat = DescriptorRenderer.TextFormat.PLAIN; @NotNull private Collection excludedAnnotationClasses = Collections.emptyList(); + private boolean receiverAfterName = false; + private boolean renderClassObjectName = false; public DescriptorRendererBuilder() { } @@ -162,13 +167,34 @@ public class DescriptorRendererBuilder { return this; } + public DescriptorRendererBuilder setWithoutTypeParameters(boolean withoutTypeParameters) { + this.withoutTypeParameters = withoutTypeParameters; + return this; + } + + public DescriptorRendererBuilder setWithoutFunctionParameterNames(boolean withoutFunctionParameterNames) { + this.withoutFunctionParameterNames = withoutFunctionParameterNames; + return this; + } + + public DescriptorRendererBuilder setReceiverAfterName(boolean receiverAfterName) { + this.receiverAfterName = receiverAfterName; + return this; + } + + public DescriptorRendererBuilder setRenderClassObjectName(boolean renderClassObjectName) { + this.renderClassObjectName = renderClassObjectName; + return this; + } + @NotNull public DescriptorRenderer build() { return new DescriptorRendererImpl( shortNames, withDefinedIn, modifiers, startFromName, debugMode, classWithPrimaryConstructor, verbose, unitReturnType, normalizedVisibilities, showInternalKeyword, prettyFunctionTypes, uninferredTypeParameterAsName, overrideRenderingPolicy, valueParametersHandler, textFormat, excludedAnnotationClasses, includePropertyConstant, - includeSynthesizedParameterNames); + includeSynthesizedParameterNames, withoutFunctionParameterNames, withoutTypeParameters, receiverAfterName, + renderClassObjectName); } } diff --git a/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java b/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java index 98cab90d38d..8192d4f7260 100644 --- a/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java +++ b/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2013 JetBrains s.r.o. + * Copyright 2010-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. @@ -58,7 +58,11 @@ public class DescriptorRendererImpl implements DescriptorRenderer { private final boolean prettyFunctionTypes; private final boolean uninferredTypeParameterAsName; private final boolean includeSynthesizedParameterNames; + private final boolean withoutFunctionParameterNames; + private final boolean withoutTypeParameters; + private final boolean renderClassObjectName; + private final boolean receiverAfterName; @NotNull private final OverrideRenderingPolicy overrideRenderingPolicy; @NotNull @@ -87,7 +91,11 @@ public class DescriptorRendererImpl implements DescriptorRenderer { @NotNull TextFormat textFormat, @NotNull Collection excludedAnnotationClasses, boolean includePropertyConstant, - boolean includeSynthesizedParameterNames + boolean includeSynthesizedParameterNames, + boolean withoutFunctionParameterNames, + boolean withoutTypeParameters, + boolean receiverAfterName, + boolean renderClassObjectName ) { this.shortNames = shortNames; this.withDefinedIn = withDefinedIn; @@ -107,6 +115,10 @@ public class DescriptorRendererImpl implements DescriptorRenderer { this.prettyFunctionTypes = prettyFunctionTypes; this.uninferredTypeParameterAsName = uninferredTypeParameterAsName; this.includeSynthesizedParameterNames = includeSynthesizedParameterNames; + this.withoutFunctionParameterNames = withoutFunctionParameterNames; + this.withoutTypeParameters = withoutTypeParameters; + this.receiverAfterName = receiverAfterName; + this.renderClassObjectName = renderClassObjectName; } /* FORMATTING */ @@ -187,6 +199,15 @@ public class DescriptorRendererImpl implements DescriptorRenderer { builder.append(renderName(descriptor.getName())); } + private void renderClassObjectName(@NotNull DeclarationDescriptor descriptor, @NotNull StringBuilder builder) { + if (renderClassObjectName) { + builder.append(""); + } + if (verbose) { + builder.append(renderName(descriptor.getName())); + } + } + @NotNull private String renderFqName(@NotNull FqNameBase fqName) { return renderFqName(fqName.pathSegments()); @@ -553,6 +574,8 @@ public class DescriptorRendererImpl implements DescriptorRenderer { @NotNull StringBuilder builder, boolean withSpace ) { + if (withoutTypeParameters) return; + if (!typeParameters.isEmpty()) { builder.append(lt()); for (Iterator iterator = typeParameters.iterator(); iterator.hasNext(); ) { @@ -580,24 +603,39 @@ public class DescriptorRendererImpl implements DescriptorRenderer { builder.append(renderKeyword("fun")).append(" "); renderTypeParameters(function.getTypeParameters(), builder, true); - - ReceiverParameterDescriptor receiver = function.getReceiverParameter(); - if (receiver != null) { - builder.append(escape(renderType(receiver.getType()))).append("."); - } + renderReceiver(function, builder); } renderName(function, builder); renderValueParameters(function, builder); + renderReceiverAfterName(function, builder); + JetType returnType = function.getReturnType(); - if (unitReturnType || !KotlinBuiltIns.getInstance().isUnit(returnType)) { + if (unitReturnType || (returnType == null || !KotlinBuiltIns.getInstance().isUnit(returnType))) { builder.append(": ").append(returnType == null ? "[NULL]" : escape(renderType(returnType))); } + renderWhereSuffix(function.getTypeParameters(), builder); } + private void renderReceiverAfterName(CallableDescriptor callableDescriptor, StringBuilder builder) { + if (!receiverAfterName) return; + + ReceiverParameterDescriptor receiver = callableDescriptor.getReceiverParameter(); + if (receiver != null) { + builder.append(" on ").append(escape(renderType(receiver.getType()))); + } + } + + private void renderReceiver(CallableDescriptor callableDescriptor, StringBuilder builder) { + ReceiverParameterDescriptor receiver = callableDescriptor.getReceiverParameter(); + if (receiver != null) { + builder.append(escape(renderType(receiver.getType()))).append("."); + } + } + private void renderConstructor(@NotNull ConstructorDescriptor constructor, @NotNull StringBuilder builder) { renderAnnotations(constructor, builder); renderVisibility(constructor.getVisibility(), builder); @@ -614,6 +652,8 @@ public class DescriptorRendererImpl implements DescriptorRenderer { } private void renderWhereSuffix(@NotNull List typeParameters, @NotNull StringBuilder builder) { + if (withoutTypeParameters) return; + List upperBoundStrings = Lists.newArrayList(); for (TypeParameterDescriptor typeParameter : typeParameters) { @@ -643,7 +683,8 @@ public class DescriptorRendererImpl implements DescriptorRenderer { } private void renderValueParameters(@NotNull FunctionDescriptor function, @NotNull StringBuilder builder) { - boolean includeNames = includeSynthesizedParameterNames || !function.hasSynthesizedParameterNames(); + boolean includeNames = !withoutFunctionParameterNames && + (includeSynthesizedParameterNames || !function.hasSynthesizedParameterNames()); handler.appendBeforeValueParameters(function, builder); for (ValueParameterDescriptor parameter : function.getValueParameters()) { handler.appendBeforeValueParameter(parameter, builder); @@ -711,19 +752,16 @@ public class DescriptorRendererImpl implements DescriptorRenderer { renderModalityForCallable(property, builder); renderOverride(property, builder); renderMemberKind(property, builder); - renderValVarPrefix(property, builder); + renderTypeParameters(property.getTypeParameters(), builder, true); + renderReceiver(property, builder); } - renderTypeParameters(property.getTypeParameters(), builder, true); - - ReceiverParameterDescriptor receiver = property.getReceiverParameter(); - if (receiver != null) { - builder.append(escape(renderType(receiver.getType()))).append("."); - } renderName(property, builder); builder.append(": ").append(escape(renderType(property.getType()))); + renderReceiverAfterName(property, builder); + renderInitializer(property, builder); renderWhereSuffix(property.getTypeParameters(), builder); @@ -748,13 +786,16 @@ public class DescriptorRendererImpl implements DescriptorRenderer { renderModality(klass.getModality(), builder); } renderInner(klass.isInner(), builder); - builder.append(renderKeyword(getClassKindPrefix(klass))); + renderClassKindPrefix(klass, builder); + builder.append(" "); } - if (klass.getKind() != ClassKind.CLASS_OBJECT || verbose) { - builder.append(" "); + if (klass.getKind() != ClassKind.CLASS_OBJECT) { renderName(klass, builder); } + else { + renderClassObjectName(klass, builder); + } List typeParameters = klass.getTypeConstructor().getParameters(); renderTypeParameters(typeParameters, builder, false); @@ -786,6 +827,10 @@ public class DescriptorRendererImpl implements DescriptorRenderer { renderWhereSuffix(typeParameters, builder); } + private void renderClassKindPrefix(ClassDescriptor klass, StringBuilder builder) { + builder.append(renderKeyword(getClassKindPrefix(klass))); + } + @NotNull private static String getClassKindPrefix(@NotNull ClassDescriptor klass) { switch (klass.getKind()) { diff --git a/idea/src/org/jetbrains/jet/plugin/structureView/JetStructureViewElement.java b/idea/src/org/jetbrains/jet/plugin/structureView/JetStructureViewElement.java index 28ae4e6bbb1..2843e914cc9 100644 --- a/idea/src/org/jetbrains/jet/plugin/structureView/JetStructureViewElement.java +++ b/idea/src/org/jetbrains/jet/plugin/structureView/JetStructureViewElement.java @@ -46,8 +46,9 @@ public class JetStructureViewElement implements StructureViewTreeElement, Colore private final NavigatablePsiElement element; private String elementText; + private Icon icon; - public JetStructureViewElement(NavigatablePsiElement element) { + public JetStructureViewElement(@NotNull NavigatablePsiElement element) { this.element = element; } @@ -55,10 +56,6 @@ public class JetStructureViewElement implements StructureViewTreeElement, Colore element = fileElement; } - private static DeclarationDescriptor getDescriptor(JetDeclaration declaration) { - return declaration.isValid() ? ResolvePackage.getLazyResolveSession(declaration).resolveToDescriptor(declaration) : null; - } - @NotNull public NavigatablePsiElement getElement() { return element; @@ -102,6 +99,55 @@ public class JetStructureViewElement implements StructureViewTreeElement, Colore }), TreeElement.class); } + @Nullable + @Override + public TextAttributesKey getTextAttributesKey() { + if (element instanceof JetModifierListOwner && JetPsiUtil.isDeprecated((JetModifierListOwner) element)) { + return CodeInsightColors.DEPRECATED_ATTRIBUTES; + } + return null; + } + + @Nullable + @Override + public String getPresentableText() { + if (elementText == null) { + elementText = getElementText(element, getDescriptor()); + } + + return elementText; + } + + @Nullable + @Override + public String getLocationString() { + return null; + } + + @Nullable + @Override + public Icon getIcon(boolean unused) { + if (icon == null) { + icon = getElementIcon(element, getDescriptor()); + } + + return icon; + } + + @Nullable + private DeclarationDescriptor getDescriptor() { + if (!(element.isValid() && element instanceof JetDeclaration)) { + return null; + } + + JetDeclaration declaration = (JetDeclaration) element; + if (declaration instanceof JetClassInitializer) { + return null; + } + + return ResolvePackage.getLazyResolveSession(declaration).resolveToDescriptor(declaration); + } + private List getChildrenDeclarations() { if (element instanceof JetFile) { JetFile jetFile = (JetFile) element; @@ -129,74 +175,29 @@ public class JetStructureViewElement implements StructureViewTreeElement, Colore return Collections.emptyList(); } - @Nullable - @Override - public TextAttributesKey getTextAttributesKey() { - if (element instanceof JetModifierListOwner && JetPsiUtil.isDeprecated((JetModifierListOwner) element)) { - return CodeInsightColors.DEPRECATED_ATTRIBUTES; + private static Icon getElementIcon(@NotNull NavigatablePsiElement navigatablePsiElement, @Nullable DeclarationDescriptor descriptor) { + if (descriptor != null) { + return JetDescriptorIconProvider.getIcon(descriptor, navigatablePsiElement, Iconable.ICON_FLAG_VISIBILITY); } + + return PsiIconUtil.getProvidersIcon(navigatablePsiElement, Iconable.ICON_FLAG_VISIBILITY); + } + + @Nullable + private static String getElementText(@NotNull NavigatablePsiElement navigatablePsiElement, @Nullable DeclarationDescriptor descriptor) { + if (descriptor != null) { + return DescriptorRenderer.STARTS_FROM_NAME_WITH_SHORT_TYPES.render(descriptor); + } + + String text = navigatablePsiElement.getName(); + if (!StringUtil.isEmpty(text)) { + return text; + } + + if (navigatablePsiElement instanceof JetClassInitializer) { + return ""; + } + return null; } - - @Nullable - @Override - public String getPresentableText() { - if (elementText == null) { - elementText = getElementText(); - } - - return elementText; - } - - @Nullable - @Override - public String getLocationString() { - return null; - } - - @Nullable - @Override - public Icon getIcon(boolean unused) { - if (!element.isValid()) return null; - - if (element instanceof JetDeclaration) { - DeclarationDescriptor descriptor = getDescriptor((JetDeclaration) element); - if (descriptor != null) { - JetDescriptorIconProvider.getIcon(descriptor, element, Iconable.ICON_FLAG_VISIBILITY); - } - } - - return PsiIconUtil.getProvidersIcon(element, Iconable.ICON_FLAG_VISIBILITY); - } - - private String getElementText() { - String text = ""; - - // Try to find text in correspondent descriptor - if (element instanceof JetDeclaration) { - JetDeclaration declaration = (JetDeclaration) element; - - DeclarationDescriptor descriptor = getDescriptor(declaration); - if (descriptor != null) { - //text = getDescriptorTreeText(descriptor); - text = DescriptorRenderer.STARTS_FROM_NAME_WITH_SHORT_TYPES.render(descriptor); - } - } - - if (StringUtil.isEmpty(text)) { - text = element.getName(); - } - - if (StringUtil.isEmpty(text)) { - if (element instanceof JetClassInitializer) { - return ""; - } - - if (element instanceof JetClassObject) { - return ""; - } - } - - return text; - } } diff --git a/idea/testData/structureView/fileStructure/Render.after b/idea/testData/structureView/fileStructure/Render.after new file mode 100644 index 00000000000..bdd79431150 --- /dev/null +++ b/idea/testData/structureView/fileStructure/Render.after @@ -0,0 +1,40 @@ +-Render.kt + test1(): Unit + test2(String?): Unit + test3(T, U): Unit + test4(T): Unit + test5(): String + test6(): Comparable + extension1() on String: Unit + extension2() on Comparable: Unit + a: Int + a: String on Comparable + b: Any + A1 + -A2 + a: Int + b: [ERROR : Annotation is absent] + -A3 + a: Int + b: String + -A4 + t: T? + -A5 + Inner1 + Inner2 + -A6 + - + test(): Unit + -A7 + a: Int + + -Enum1 : Enum + FIRST : Enum1 + SECOND : Enum1 + Trait + Trait1 : Trait + TestWithWhere + testWithWhere(): Unit + -WithDefaultArgs + a: Int + withDefaulArgs(Int = ..., String = ...): Unit diff --git a/idea/testData/structureView/fileStructure/Render.kt b/idea/testData/structureView/fileStructure/Render.kt new file mode 100644 index 00000000000..581ec4f8018 --- /dev/null +++ b/idea/testData/structureView/fileStructure/Render.kt @@ -0,0 +1,54 @@ +//package test.render + +fun test1() {} +fun test2(a: String?) {} +fun test3(t: T, u: U) {} +fun test4(t: T) {} +fun test5(): String = "some" +fun test6(): Comparable = "some" + +fun String.extension1() {} +fun Comparable.extension2() {} + +val a: Int = 1 +val Comparable.a = "String" +val b = object {} + +class A1 +class A2(val a: Int, var b = "some") +class A3(val a: Int) { + var b = "some" +} +class A4(val t: T?) +class A5 { + class Inner1 + inner class Inner2 +} +class A6 { + class object { + fun test() {} + } +} +class A7 { + val a: Int + + { + a = 1 + } +} + +enum class Enum1 { + FIRST + SECOND +} + +trait Trait +trait Trait1: Trait + +class TestWithWhere where T: Any? +fun testWithWhere() where T: String {} + +class WithDefaultArgs(val a: Int = 1, b: String = "str") +fun withDefaulArgs(a: Int = 1, b: String = "str") {} + + diff --git a/idea/testData/structureView/fileStructure/SeveralClasses.after b/idea/testData/structureView/fileStructure/SeveralClasses.after index fb91a9a588c..52e8c4c8a42 100644 --- a/idea/testData/structureView/fileStructure/SeveralClasses.after +++ b/idea/testData/structureView/fileStructure/SeveralClasses.after @@ -1,5 +1,5 @@ -SeveralClasses.kt - A () - B () - Some () - Other () + A + B + Some : B, A + Other : A diff --git a/idea/testData/structureView/fileStructure/Simple.after b/idea/testData/structureView/fileStructure/Simple.after index 57eb2dd4c05..a5f062100a8 100644 --- a/idea/testData/structureView/fileStructure/Simple.after +++ b/idea/testData/structureView/fileStructure/Simple.after @@ -1,6 +1,6 @@ -Simple.kt - -Test () - str:kotlin.String - some:kotlin.Int - foo():kotlin.Int - other():kotlin.Unit + -Test + str: String + some: Int + foo(): Int + other(): Unit diff --git a/idea/tests/org/jetbrains/jet/plugin/structureView/KotlinFileStructureTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/structureView/KotlinFileStructureTestGenerated.java index 9a202cf82a9..d283285b79b 100644 --- a/idea/tests/org/jetbrains/jet/plugin/structureView/KotlinFileStructureTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/structureView/KotlinFileStructureTestGenerated.java @@ -33,9 +33,7 @@ import org.jetbrains.jet.plugin.structureView.AbstractKotlinFileStructureTest; @TestMetadata("idea/testData/structureView/fileStructure") public class KotlinFileStructureTestGenerated extends AbstractKotlinFileStructureTest { public void testAllFilesPresentInFileStructure() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", - new File("idea/testData/structureView/fileStructure"), Pattern.compile("^(.+)\\.kt$"), - true); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/structureView/fileStructure"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("EmptyFile.kt") @@ -48,6 +46,11 @@ public class KotlinFileStructureTestGenerated extends AbstractKotlinFileStructur doTest("idea/testData/structureView/fileStructure/InheritedMembers.kt"); } + @TestMetadata("Render.kt") + public void testRender() throws Exception { + doTest("idea/testData/structureView/fileStructure/Render.kt"); + } + @TestMetadata("SeveralClasses.kt") public void testSeveralClasses() throws Exception { doTest("idea/testData/structureView/fileStructure/SeveralClasses.kt");