diff --git a/compiler/frontend/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java b/compiler/frontend/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java index bc4fbd8ed7a..cb6ba754ebf 100644 --- a/compiler/frontend/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java @@ -46,8 +46,6 @@ public class DescriptorRendererImpl implements DescriptorRenderer { } } - private final RenderDeclarationDescriptorVisitor rootVisitor = new RenderDeclarationDescriptorVisitor(); - private final boolean shortNames; private final boolean withDefinedIn; private final boolean modifiers; @@ -286,7 +284,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer { @Override public String render(@NotNull DeclarationDescriptor declarationDescriptor) { StringBuilder stringBuilder = new StringBuilder(); - declarationDescriptor.accept(rootVisitor, stringBuilder); + declarationDescriptor.accept(new RenderDeclarationDescriptorVisitor(), stringBuilder); if (withDefinedIn) { appendDefinedIn(declarationDescriptor, stringBuilder); @@ -324,106 +322,285 @@ public class DescriptorRendererImpl implements DescriptorRenderer { } } private void renderValueParameterOfFunction(ValueParameterDescriptor descriptor, StringBuilder builder) { - rootVisitor.visitVariableDescriptor(descriptor, builder, true); + renderVariable(descriptor, builder, true); boolean withDefaultValue = debugMode ? descriptor.declaresDefaultValue() : descriptor.hasDefaultValue(); if (withDefaultValue) { builder.append(" = ..."); } } + private void renderValueParameter(ValueParameterDescriptor descriptor, StringBuilder builder) { + builder.append(renderKeyword("value-parameter")).append(" "); + renderVariable(descriptor, builder); + } + + private void renderVariable(VariableDescriptor descriptor, StringBuilder builder) { + renderVariable(descriptor, builder, false); + } + + private void renderVariable(VariableDescriptor descriptor, StringBuilder builder, boolean skipValVar) { + JetType type = descriptor.getType(); + if (descriptor instanceof ValueParameterDescriptor) { + JetType varargElementType = ((ValueParameterDescriptor) descriptor).getVarargElementType(); + if (varargElementType != null) { + builder.append(renderKeyword("vararg")).append(" "); + type = varargElementType; + } + } + String typeString = renderPropertyPrefixAndComputeTypeString( + builder, + skipValVar ? null : descriptor.isVar(), + Collections.emptyList(), + ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER, + type); + renderName(descriptor, builder); + builder.append(" : ").append(escape(typeString)); + } + + private String renderPropertyPrefixAndComputeTypeString( + @NotNull StringBuilder builder, + @Nullable Boolean isVar, + @NotNull List typeParameters, + @Nullable ReceiverParameterDescriptor receiver, + @Nullable JetType outType + ) { + String typeString = lt() + "no type>"; + if (outType != null) { + if (isVar != null && !startFromName) { + builder.append(renderKeyword(isVar ? "var" : "val")).append(" "); + } + typeString = renderType(outType); + } + + renderTypeParameters(typeParameters, builder); + + if (receiver != null) { + builder.append(escape(renderType(receiver.getType()))).append("."); + } + + return typeString; + } + + private void renderProperty(PropertyDescriptor descriptor, StringBuilder builder) { + if (!startFromName) { + renderVisibility(descriptor.getVisibility(), builder); + renderModality(descriptor.getModality(), builder); + } + String typeString = renderPropertyPrefixAndComputeTypeString( + builder, + descriptor.isVar(), + descriptor.getTypeParameters(), + descriptor.getReceiverParameter(), + descriptor.getType()); + renderName(descriptor, builder); + builder.append(" : ").append(escape(typeString)); + } + + private void renderFunction(FunctionDescriptor descriptor, StringBuilder builder) { + if (!startFromName) { + renderVisibility(descriptor.getVisibility(), builder); + renderModality(descriptor.getModality(), builder); + builder.append(renderKeyword("fun")).append(" "); + if (renderTypeParameters(descriptor.getTypeParameters(), builder)) { + builder.append(" "); + } + + ReceiverParameterDescriptor receiver = descriptor.getReceiverParameter(); + if (receiver != null) { + builder.append(escape(renderType(receiver.getType()))).append("."); + } + } + + renderName(descriptor, builder); + renderValueParameters(descriptor, builder); + builder.append(" : ").append(escape(renderType(descriptor.getReturnType()))); + renderWhereSuffix(descriptor, builder); + } + + private void renderWhereSuffix(@NotNull CallableMemberDescriptor callable, @NotNull StringBuilder builder) { + boolean first = true; + for (TypeParameterDescriptor typeParameter : callable.getTypeParameters()) { + if (typeParameter.getUpperBounds().size() > 1) { + for (JetType upperBound : typeParameter.getUpperBounds()) { + if (first) { + builder.append(" "); + builder.append(renderKeyword("where")); + builder.append(" "); + } + else { + builder.append(", "); + } + builder.append(typeParameter.getName()); + builder.append(" : "); + builder.append(escape(renderType(upperBound))); + first = false; + } + } + } + } + + private void renderConstructor(ConstructorDescriptor constructorDescriptor, StringBuilder builder) { + renderVisibility(constructorDescriptor.getVisibility(), builder); + + builder.append(renderKeyword("ctor")).append(" "); + + ClassDescriptor classDescriptor = constructorDescriptor.getContainingDeclaration(); + builder.append(classDescriptor.getName()); + + renderTypeParameters(classDescriptor.getTypeConstructor().getParameters(), builder); + renderValueParameters(constructorDescriptor, builder); + } + + private boolean renderTypeParameters(List typeParameters, StringBuilder builder) { + if (!typeParameters.isEmpty()) { + builder.append(lt()); + for (Iterator iterator = typeParameters.iterator(); iterator.hasNext(); ) { + TypeParameterDescriptor typeParameterDescriptor = iterator.next(); + renderTypeParameter(typeParameterDescriptor, builder, false); + if (iterator.hasNext()) { + builder.append(", "); + } + } + builder.append(">"); + return true; + } + return false; + } + + private void renderTypeParameter(TypeParameterDescriptor descriptor, StringBuilder builder) { + builder.append(lt()); + renderTypeParameter(descriptor, builder, true); + builder.append(">"); + } + + private void renderClass(ClassDescriptor descriptor, StringBuilder builder) { + String keyword; + switch (descriptor.getKind()) { + case TRAIT: + keyword = "trait"; + break; + case ENUM_CLASS: + keyword = "enum class"; + break; + case OBJECT: + keyword = "object"; + break; + case ANNOTATION_CLASS: + keyword = "annotation class"; + break; + case CLASS_OBJECT: + keyword = "class object"; + break; + default: + keyword = "class"; + } + renderClassDescriptor(descriptor, builder, keyword); + } + + private void renderClassDescriptor(ClassDescriptor descriptor, StringBuilder builder, String keyword) { + boolean isNotClassObject = descriptor.getKind() != ClassKind.CLASS_OBJECT; + if (!startFromName) { + if (isNotClassObject) { + renderVisibility(descriptor.getVisibility(), builder); + if (descriptor.getKind() != ClassKind.TRAIT && descriptor.getKind() != ClassKind.OBJECT) { + renderModality(descriptor.getModality(), builder); + } + } + builder.append(renderKeyword(keyword)); + if (isNotClassObject) { + builder.append(" "); + } + } + if (isNotClassObject) { + renderName(descriptor, builder); + renderTypeParameters(descriptor.getTypeConstructor().getParameters(), builder); + } + if (!descriptor.equals(KotlinBuiltIns.getInstance().getNothing())) { + Collection supertypes = descriptor.getTypeConstructor().getSupertypes(); + if (supertypes.isEmpty() || supertypes.size() == 1 && KotlinBuiltIns.getInstance().isAny(supertypes.iterator().next())) { + } + else { + builder.append(" : "); + for (Iterator iterator = supertypes.iterator(); iterator.hasNext(); ) { + JetType supertype = iterator.next(); + builder.append(renderType(supertype)); + if (iterator.hasNext()) { + builder.append(", "); + } + } + } + } + } + + private void renderTypeParameter(TypeParameterDescriptor descriptor, StringBuilder builder, boolean topLevel) { + if (!descriptor.isReified()) { + String variance = descriptor.getVariance().toString(); + if (!variance.isEmpty()) { + builder.append(renderKeyword(variance)).append(" "); + } + } + else { + builder.append(renderKeyword("reified")).append(" "); + } + renderName(descriptor, builder); + if (descriptor.getUpperBounds().size() == 1) { + JetType upperBound = descriptor.getUpperBounds().iterator().next(); + if (!KotlinBuiltIns.getInstance().getDefaultBound().equals(upperBound)) { + builder.append(" : ").append(renderType(upperBound)); + } + } + else if (topLevel) { + boolean first = true; + for (JetType upperBound : descriptor.getUpperBounds()) { + if (upperBound.equals(KotlinBuiltIns.getInstance().getDefaultBound())) { + continue; + } + if (first) { + builder.append(" : "); + } + else { + builder.append(" & "); + } + builder.append(renderType(upperBound)); + first = false; + } + } + else { + // rendered with "where" + } + } + + private void renderModuleOrScript(DeclarationDescriptor descriptor, StringBuilder builder) { + renderName(descriptor, builder); + } + + private void renderNamespace(NamespaceDescriptor namespaceDescriptor, StringBuilder builder) { + builder.append(renderKeyword(JetTokens.PACKAGE_KEYWORD.getValue())).append(" "); + renderName(namespaceDescriptor, builder); + } + private class RenderDeclarationDescriptorVisitor extends DeclarationDescriptorVisitorEmptyBodies { @Override public Void visitValueParameterDescriptor(ValueParameterDescriptor descriptor, StringBuilder builder) { - builder.append(renderKeyword("value-parameter")).append(" "); - return visitVariableDescriptor(descriptor, builder); + renderValueParameter(descriptor, builder); + return null; } @Override public Void visitVariableDescriptor(VariableDescriptor descriptor, StringBuilder builder) { - return visitVariableDescriptor(descriptor, builder, false); - } - - private Void visitVariableDescriptor(VariableDescriptor descriptor, StringBuilder builder, boolean skipValVar) { - JetType type = descriptor.getType(); - if (descriptor instanceof ValueParameterDescriptor) { - JetType varargElementType = ((ValueParameterDescriptor) descriptor).getVarargElementType(); - if (varargElementType != null) { - builder.append(renderKeyword("vararg")).append(" "); - type = varargElementType; - } - } - String typeString = renderPropertyPrefixAndComputeTypeString( - builder, - skipValVar ? null : descriptor.isVar(), - Collections.emptyList(), - ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER, - type); - renderName(descriptor, builder); - builder.append(" : ").append(escape(typeString)); + renderVariable(descriptor, builder); return null; } - private String renderPropertyPrefixAndComputeTypeString( - @NotNull StringBuilder builder, - @Nullable Boolean isVar, - @NotNull List typeParameters, - @Nullable ReceiverParameterDescriptor receiver, - @Nullable JetType outType - ) { - String typeString = lt() + "no type>"; - if (outType != null) { - if (isVar != null && !startFromName) { - builder.append(renderKeyword(isVar ? "var" : "val")).append(" "); - } - typeString = renderType(outType); - } - - renderTypeParameters(typeParameters, builder); - - if (receiver != null) { - builder.append(escape(renderType(receiver.getType()))).append("."); - } - - return typeString; - } - @Override public Void visitPropertyDescriptor(PropertyDescriptor descriptor, StringBuilder builder) { - if (!startFromName) { - renderVisibility(descriptor.getVisibility(), builder); - renderModality(descriptor.getModality(), builder); - } - String typeString = renderPropertyPrefixAndComputeTypeString( - builder, - descriptor.isVar(), - descriptor.getTypeParameters(), - descriptor.getReceiverParameter(), - descriptor.getType()); - renderName(descriptor, builder); - builder.append(" : ").append(escape(typeString)); + renderProperty(descriptor, builder); return null; } @Override public Void visitFunctionDescriptor(FunctionDescriptor descriptor, StringBuilder builder) { - if (!startFromName) { - renderVisibility(descriptor.getVisibility(), builder); - renderModality(descriptor.getModality(), builder); - builder.append(renderKeyword("fun")).append(" "); - if (renderTypeParameters(descriptor.getTypeParameters(), builder)) { - builder.append(" "); - } - - ReceiverParameterDescriptor receiver = descriptor.getReceiverParameter(); - if (receiver != null) { - builder.append(escape(renderType(receiver.getType()))).append("."); - } - } - - renderName(descriptor, builder); - renderValueParameters(descriptor, builder); - builder.append(" : ").append(escape(renderType(descriptor.getReturnType()))); - renderWhereSuffix(descriptor, builder); + renderFunction(descriptor, builder); return null; } @@ -432,182 +609,41 @@ public class DescriptorRendererImpl implements DescriptorRenderer { throw new UnsupportedOperationException("Don't render receiver parameters"); } - private void renderWhereSuffix(@NotNull CallableMemberDescriptor callable, @NotNull StringBuilder builder) { - boolean first = true; - for (TypeParameterDescriptor typeParameter : callable.getTypeParameters()) { - if (typeParameter.getUpperBounds().size() > 1) { - for (JetType upperBound : typeParameter.getUpperBounds()) { - if (first) { - builder.append(" "); - builder.append(renderKeyword("where")); - builder.append(" "); - } - else { - builder.append(", "); - } - builder.append(typeParameter.getName()); - builder.append(" : "); - builder.append(escape(renderType(upperBound))); - first = false; - } - } - } - } - @Override public Void visitConstructorDescriptor(ConstructorDescriptor constructorDescriptor, StringBuilder builder) { - renderVisibility(constructorDescriptor.getVisibility(), builder); - - builder.append(renderKeyword("ctor")).append(" "); - - ClassDescriptor classDescriptor = constructorDescriptor.getContainingDeclaration(); - builder.append(classDescriptor.getName()); - - renderTypeParameters(classDescriptor.getTypeConstructor().getParameters(), builder); - renderValueParameters(constructorDescriptor, builder); + renderConstructor(constructorDescriptor, builder); return null; } - private boolean renderTypeParameters(List typeParameters, StringBuilder builder) { - if (!typeParameters.isEmpty()) { - builder.append(lt()); - for (Iterator iterator = typeParameters.iterator(); iterator.hasNext(); ) { - TypeParameterDescriptor typeParameterDescriptor = iterator.next(); - renderTypeParameter(typeParameterDescriptor, builder, false); - if (iterator.hasNext()) { - builder.append(", "); - } - } - builder.append(">"); - return true; - } - return false; - } - @Override public Void visitTypeParameterDescriptor(TypeParameterDescriptor descriptor, StringBuilder builder) { - builder.append(lt()); - renderTypeParameter(descriptor, builder, true); - builder.append(">"); + renderTypeParameter(descriptor, builder); return null; } @Override public Void visitNamespaceDescriptor(NamespaceDescriptor namespaceDescriptor, StringBuilder builder) { - builder.append(renderKeyword(JetTokens.PACKAGE_KEYWORD.getValue())).append(" "); - renderName(namespaceDescriptor, builder); + renderNamespace(namespaceDescriptor, builder); return null; } @Override public Void visitModuleDeclaration(ModuleDescriptor descriptor, StringBuilder builder) { - renderName(descriptor, builder); + renderModuleOrScript(descriptor, builder); return null; } @Override - public Void visitScriptDescriptor(ScriptDescriptor scriptDescriptor, StringBuilder data) { - renderName(scriptDescriptor, data); + public Void visitScriptDescriptor(ScriptDescriptor scriptDescriptor, StringBuilder builder) { + renderModuleOrScript(scriptDescriptor, builder); return null; } @Override public Void visitClassDescriptor(ClassDescriptor descriptor, StringBuilder builder) { - String keyword; - switch (descriptor.getKind()) { - case TRAIT: - keyword = "trait"; - break; - case ENUM_CLASS: - keyword = "enum class"; - break; - case OBJECT: - keyword = "object"; - break; - case ANNOTATION_CLASS: - keyword = "annotation class"; - break; - case CLASS_OBJECT: - keyword = "class object"; - break; - default: - keyword = "class"; - } - renderClassDescriptor(descriptor, builder, keyword); + renderClass(descriptor, builder); return null; } - private void renderClassDescriptor(ClassDescriptor descriptor, StringBuilder builder, String keyword) { - boolean isNotClassObject = descriptor.getKind() != ClassKind.CLASS_OBJECT; - if (!startFromName) { - if (isNotClassObject) { - renderVisibility(descriptor.getVisibility(), builder); - if (descriptor.getKind() != ClassKind.TRAIT && descriptor.getKind() != ClassKind.OBJECT) { - renderModality(descriptor.getModality(), builder); - } - } - builder.append(renderKeyword(keyword)); - if (isNotClassObject) { - builder.append(" "); - } - } - if (isNotClassObject) { - renderName(descriptor, builder); - renderTypeParameters(descriptor.getTypeConstructor().getParameters(), builder); - } - if (!descriptor.equals(KotlinBuiltIns.getInstance().getNothing())) { - Collection supertypes = descriptor.getTypeConstructor().getSupertypes(); - if (supertypes.isEmpty() || supertypes.size() == 1 && KotlinBuiltIns.getInstance().isAny(supertypes.iterator().next())) { - } - else { - builder.append(" : "); - for (Iterator iterator = supertypes.iterator(); iterator.hasNext(); ) { - JetType supertype = iterator.next(); - builder.append(renderType(supertype)); - if (iterator.hasNext()) { - builder.append(", "); - } - } - } - } - } - - private void renderTypeParameter(TypeParameterDescriptor descriptor, StringBuilder builder, boolean topLevel) { - if (!descriptor.isReified()) { - String variance = descriptor.getVariance().toString(); - if (!variance.isEmpty()) { - builder.append(renderKeyword(variance)).append(" "); - } - } - else { - builder.append(renderKeyword("reified")).append(" "); - } - renderName(descriptor, builder); - if (descriptor.getUpperBounds().size() == 1) { - JetType upperBound = descriptor.getUpperBounds().iterator().next(); - if (!KotlinBuiltIns.getInstance().getDefaultBound().equals(upperBound)) { - builder.append(" : ").append(renderType(upperBound)); - } - } - else if (topLevel) { - boolean first = true; - for (JetType upperBound : descriptor.getUpperBounds()) { - if (upperBound.equals(KotlinBuiltIns.getInstance().getDefaultBound())) { - continue; - } - if (first) { - builder.append(" : "); - } - else { - builder.append(" & "); - } - builder.append(renderType(upperBound)); - first = false; - } - } - else { - // rendered with "where" - } - } } } \ No newline at end of file