Escaping keywords used as identifiers in DescriptorRenderer.

#KT-2810 fixed
This commit is contained in:
Evgeny Gerashchenko
2012-12-11 21:33:18 +04:00
parent f55e3ce681
commit b07d6d56a0
5 changed files with 90 additions and 13 deletions
@@ -16,6 +16,9 @@
package org.jetbrains.jet.resolve;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
@@ -23,8 +26,10 @@ import org.jetbrains.jet.lang.diagnostics.rendering.Renderer;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetKeywordToken;
import org.jetbrains.jet.lexer.JetTokens;
import java.util.*;
@@ -33,6 +38,14 @@ import java.util.*;
* @author abreslav
*/
public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
private static final Set<String> KEYWORDS = Sets.newHashSet();
static {
for (IElementType elementType : JetTokens.KEYWORDS.getTypes()) {
assert elementType instanceof JetKeywordToken;
assert !((JetKeywordToken) elementType).isSoft();
KEYWORDS.add(((JetKeywordToken) elementType).getValue());
}
}
public static final DescriptorRenderer COMPACT_WITH_MODIFIERS = new DescriptorRenderer() {
@Override
@@ -112,6 +125,28 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
return keyword;
}
private String renderName(Name identifier) {
String asString = identifier.toString();
return escape(KEYWORDS.contains(asString) ? '`' + asString + '`' : asString);
}
@NotNull
private String renderFqName(@NotNull FqNameUnsafe fqName) {
return renderFqName(fqName.pathSegments());
}
@NotNull
private String renderFqName(@NotNull List<Name> pathSegments) {
StringBuilder buf = new StringBuilder();
for (Name element : pathSegments) {
if (buf.length() != 0) {
buf.append(".");
}
buf.append(renderName(element));
}
return buf.toString();
}
public String renderType(JetType type) {
return renderType(type, false);
}
@@ -156,25 +191,32 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
return sb.toString();
}
private static String renderTypeName(@NotNull TypeConstructor typeConstructor, boolean shortNamesOnly) {
private String renderTypeName(@NotNull TypeConstructor typeConstructor, boolean shortNamesOnly) {
ClassifierDescriptor cd = typeConstructor.getDeclarationDescriptor();
if (cd == null || cd instanceof TypeParameterDescriptor) {
if (cd == null) {
return typeConstructor.toString();
}
else if (cd instanceof TypeParameterDescriptor) {
return renderName(cd.getName());
}
else {
if (shortNamesOnly) {
Object typeNameObject;
List<Name> qualifiedNameElements = Lists.newArrayList();
// for nested classes qualified name should be used
typeNameObject = cd.getName();
DeclarationDescriptor parent = cd.getContainingDeclaration();
while (parent instanceof ClassDescriptor) {
typeNameObject = parent.getName() + "." + typeNameObject;
parent = parent.getContainingDeclaration();
DeclarationDescriptor current = cd;
do {
qualifiedNameElements.add(current.getName());
current = current.getContainingDeclaration();
}
return typeNameObject.toString();
while (current instanceof ClassDescriptor);
Collections.reverse(qualifiedNameElements);
return renderFqName(qualifiedNameElements);
}
else {
return DescriptorUtils.getFQName(cd).getFqName();
return renderFqName(DescriptorUtils.getFQName(cd));
}
}
}
@@ -281,7 +323,7 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
final DeclarationDescriptor containingDeclaration = declarationDescriptor.getContainingDeclaration();
if (containingDeclaration != null) {
FqNameUnsafe fqName = DescriptorUtils.getFQName(containingDeclaration);
stringBuilder.append(FqName.ROOT.equalsTo(fqName) ? "root package" : escape(fqName.getFqName()));
stringBuilder.append(FqName.ROOT.equalsTo(fqName) ? "root package" : renderFqName(fqName));
}
}
@@ -627,7 +669,7 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
}
protected void renderName(DeclarationDescriptor descriptor, StringBuilder stringBuilder) {
stringBuilder.append(escape(descriptor.getName().getName()));
stringBuilder.append(escape(DescriptorRenderer.this.renderName(descriptor.getName())));
}
protected void renderTypeParameter(TypeParameterDescriptor descriptor, StringBuilder builder, boolean topLevel) {
@@ -0,0 +1,23 @@
val `val` = 5
trait `trait`
class `class`<`in`>(p: `in`?) {
class `class`
}
val `is` = `class`.`class`()
val `in` = `class`<`trait`>(null)
fun `trait`.`fun`(`false`: `trait`): `trait`
//internal final val `val` : jet.Int defined in root package
//internal trait `trait` defined in root package
//internal final class `class`<`in`> defined in root package
//<`in`> defined in `class`
//value-parameter val p : `in`? defined in `class`.<init>
//internal final class `class` defined in `class`
//internal final val `is` : `class`.`class` defined in root package
//internal final val `in` : `class`<`trait`> defined in root package
//internal final fun `trait`.`fun`(`false` : `trait`) : `trait` defined in root package
//value-parameter val `false` : `trait` defined in `fun`
@@ -15,13 +15,16 @@
*/
package org.jetbrains.jet.jvm.compiler;
import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestSuite;
import java.io.File;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.test.InnerTestClasses;
import org.jetbrains.jet.test.TestMetadata;
import java.io.File;
import org.jetbrains.jet.jvm.compiler.AbstractLoadJavaTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
@TestMetadata("compiler/testData/loadJava")
@@ -70,6 +70,11 @@ public class LazyResolveDescriptorRendererTestGenerated extends AbstractLazyReso
doTest("compiler/testData/renderer/InheritedMembersVisibility.kt");
}
@TestMetadata("KeywordsInNames.kt")
public void testKeywordsInNames() throws Exception {
doTest("compiler/testData/renderer/KeywordsInNames.kt");
}
@TestMetadata("TupleTypes.kt")
public void testTupleTypes() throws Exception {
doTest("compiler/testData/renderer/TupleTypes.kt");
@@ -80,6 +80,10 @@ public class DescriptorRendererTest extends JetLiteFixture {
doTest();
}
public void testKeywordsInNames() throws IOException {
doTest();
}
@Override
protected String getTestDataPath() {
return JetTestCaseBuilder.getTestDataPathBase() + "/renderer";