Implement getDebugText() which should be used instead of getText() for debug purposes
This commit is contained in:
@@ -0,0 +1,344 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.lang.psi.debugText
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.psi.JetElementImplStub
|
||||||
|
import org.jetbrains.jet.lang.psi.JetElement
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClass
|
||||||
|
import org.jetbrains.jet.lang.psi.JetVisitor
|
||||||
|
import org.jetbrains.jet.lang.psi.JetModifierList
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeParameterList
|
||||||
|
import org.jetbrains.jet.lang.psi.JetParameterList
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDelegationSpecifierList
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClassBody
|
||||||
|
import org.jetbrains.jet.lang.psi.JetStubbedPsiUtil
|
||||||
|
import org.jetbrains.jet.lang.psi.JetAnnotation
|
||||||
|
import org.jetbrains.jet.lang.psi.JetAnnotationEntry
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClassInitializer
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClassObject
|
||||||
|
import org.jetbrains.jet.lang.psi.JetConstructorCalleeExpression
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDelegationSpecifier
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression
|
||||||
|
import org.jetbrains.jet.lang.psi.JetEnumEntry
|
||||||
|
import org.jetbrains.jet.lang.psi.JetInitializerList
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFunctionType
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeReference
|
||||||
|
import org.jetbrains.jet.lexer.JetTokens
|
||||||
|
import org.jetbrains.jet.lang.psi.JetNamedFunction
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeConstraintList
|
||||||
|
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
||||||
|
import org.jetbrains.jet.lang.psi.JetNullableType
|
||||||
|
import org.jetbrains.jet.lang.psi.JetObjectDeclaration
|
||||||
|
import org.jetbrains.jet.lang.psi.JetParameter
|
||||||
|
import org.jetbrains.jet.lang.psi.JetProperty
|
||||||
|
import org.jetbrains.jet.lang.psi.JetPropertyAccessor
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeArgumentList
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeConstraint
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeParameter
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeProjection
|
||||||
|
import org.jetbrains.jet.lang.psi.JetUserType
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFile
|
||||||
|
import org.jetbrains.jet.lang.psi.JetPackageDirective
|
||||||
|
import org.jetbrains.jet.lang.psi.JetImportDirective
|
||||||
|
import org.jetbrains.jet.lang.psi.JetImportList
|
||||||
|
|
||||||
|
// invoke this instead of getText() when you need debug text to identify some place in PSI without storing the element itself
|
||||||
|
// this is need to avoid unnecessary file parses
|
||||||
|
// this defaults to get text if the element is not stubbed
|
||||||
|
public fun JetElement.getDebugText(): String? {
|
||||||
|
if (this !is JetElementImplStub<*> || this.getStub() == null) {
|
||||||
|
return getText()
|
||||||
|
}
|
||||||
|
if (this is JetPackageDirective) {
|
||||||
|
val fqName = getFqName()
|
||||||
|
if (fqName.isRoot()) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return "package " + fqName.asString()
|
||||||
|
}
|
||||||
|
return accept(DebugTextBuildingVisitor, Unit.VALUE)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private object DebugTextBuildingVisitor : JetVisitor<String, Unit>() {
|
||||||
|
|
||||||
|
private val LOG = Logger.getInstance(this.javaClass)
|
||||||
|
|
||||||
|
override fun visitJetFile(file: JetFile, data: Unit?): String? {
|
||||||
|
return "STUB file: ${file.getName()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitJetElement(element: JetElement, data: Unit?): String? {
|
||||||
|
if (element is JetElementImplStub<*>) {
|
||||||
|
LOG.error("getDebugText() is not defined for ${element.getClass()}")
|
||||||
|
}
|
||||||
|
return element.getText()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitImportDirective(importDirective: JetImportDirective, data: Unit?): String? {
|
||||||
|
val importPath = importDirective.getImportPath()
|
||||||
|
if (importPath == null) {
|
||||||
|
return "import <invalid>"
|
||||||
|
}
|
||||||
|
val aliasStr = if (importPath.hasAlias()) " as " + importPath.getAlias()!!.asString() else ""
|
||||||
|
return "import ${importPath.getPathStr()}" + aliasStr
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitImportList(importList: JetImportList, data: Unit?): String? {
|
||||||
|
return renderChildren(importList, separator = "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitAnnotationEntry(annotationEntry: JetAnnotationEntry, data: Unit?): String? {
|
||||||
|
return render(annotationEntry, annotationEntry.getCalleeExpression(), annotationEntry.getTypeArgumentList())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeReference(typeReference: JetTypeReference, data: Unit?): String? {
|
||||||
|
return renderChildren(typeReference, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeArgumentList(typeArgumentList: JetTypeArgumentList, data: Unit?): String? {
|
||||||
|
return renderChildren(typeArgumentList, ", ", "<", ">")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeConstraintList(list: JetTypeConstraintList, data: Unit?): String? {
|
||||||
|
return renderChildren(list, ", ", "where ", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitUserType(userType: JetUserType, data: Unit?): String? {
|
||||||
|
return render(userType, userType.getQualifier(), userType.getReferenceExpression(), userType.getTypeArgumentList())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitAnnotation(annotation: JetAnnotation, data: Unit?): String? {
|
||||||
|
return renderChildren(annotation, " ", "[", "]")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitConstructorCalleeExpression(constructorCalleeExpression: JetConstructorCalleeExpression, data: Unit?): String? {
|
||||||
|
return render(constructorCalleeExpression, constructorCalleeExpression.getConstructorReferenceExpression())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitDelegationSpecifier(specifier: JetDelegationSpecifier, data: Unit?): String? {
|
||||||
|
return render(specifier, specifier.getTypeReference())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitDelegationSpecifierList(list: JetDelegationSpecifierList, data: Unit?): String? {
|
||||||
|
return renderChildren(list, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeParameterList(list: JetTypeParameterList, data: Unit?): String? {
|
||||||
|
return renderChildren(list, ", ", "<", ">")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitDotQualifiedExpression(expression: JetDotQualifiedExpression, data: Unit?): String? {
|
||||||
|
return renderChildren(expression, ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitInitializerList(list: JetInitializerList, data: Unit?): String? {
|
||||||
|
return renderChildren(list, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitParameterList(list: JetParameterList, data: Unit?): String? {
|
||||||
|
return renderChildren(list, ", ", "(", ")")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitEnumEntry(enumEntry: JetEnumEntry, data: Unit?): String? {
|
||||||
|
return buildText {
|
||||||
|
append("STUB: ")
|
||||||
|
appendInn(enumEntry.getModifierList(), suffix = " ")
|
||||||
|
append("enum entry ")
|
||||||
|
appendInn(enumEntry.getNameAsName())
|
||||||
|
appendInn(enumEntry.getInitializerList(), prefix = " : ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFunctionType(functionType: JetFunctionType, data: Unit?): String? {
|
||||||
|
return buildText {
|
||||||
|
appendInn(functionType.getReceiverTypeRef(), suffix = ".")
|
||||||
|
appendInn(functionType.getParameterList())
|
||||||
|
appendInn(functionType.getReturnTypeRef(), prefix = " -> ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeParameter(parameter: JetTypeParameter, data: Unit?): String? {
|
||||||
|
return buildText {
|
||||||
|
appendInn(parameter.getModifierList(), suffix = " ")
|
||||||
|
appendInn(parameter.getNameAsName())
|
||||||
|
appendInn(parameter.getExtendsBound(), prefix = " : ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeProjection(typeProjection: JetTypeProjection, data: Unit?): String? {
|
||||||
|
return buildText {
|
||||||
|
val token = typeProjection.getProjectionKind().getToken()
|
||||||
|
appendInn(token?.getValue())
|
||||||
|
val typeReference = typeProjection.getTypeReference()
|
||||||
|
if (token != null && typeReference != null) {
|
||||||
|
append(" ")
|
||||||
|
}
|
||||||
|
appendInn(typeReference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitModifierList(list: JetModifierList, data: Unit?): String? {
|
||||||
|
return buildText {
|
||||||
|
var first = true
|
||||||
|
for (modifierKeywordToken in JetTokens.MODIFIER_KEYWORDS_ARRAY) {
|
||||||
|
if (list.hasModifier(modifierKeywordToken)) {
|
||||||
|
if (!first) {
|
||||||
|
append(" ")
|
||||||
|
}
|
||||||
|
append(modifierKeywordToken.getValue())
|
||||||
|
first = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSimpleNameExpression(expression: JetSimpleNameExpression, data: Unit?): String? {
|
||||||
|
return expression.getReferencedName()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitNullableType(nullableType: JetNullableType, data: Unit?): String? {
|
||||||
|
return renderChildren(nullableType, "", "", "?")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitAnonymousInitializer(initializer: JetClassInitializer, data: Unit?): String? {
|
||||||
|
val containingDeclaration = JetStubbedPsiUtil.getContainingDeclaration(initializer)
|
||||||
|
return "initializer in " + (containingDeclaration?.getDebugText() ?: "...")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitClassObject(classObject: JetClassObject, data: Unit?): String? {
|
||||||
|
val containingDeclaration = JetStubbedPsiUtil.getContainingDeclaration(classObject)
|
||||||
|
return "class object in " + (containingDeclaration?.getDebugText() ?: "...")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitClassBody(classBody: JetClassBody, data: Unit?): String? {
|
||||||
|
val containingDeclaration = JetStubbedPsiUtil.getContainingDeclaration(classBody)
|
||||||
|
return "class body for " + (containingDeclaration?.getDebugText() ?: "...")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitPropertyAccessor(accessor: JetPropertyAccessor, data: Unit?): String? {
|
||||||
|
val containingProperty = JetStubbedPsiUtil.getContainingDeclaration(accessor, javaClass<JetProperty>())
|
||||||
|
val what = (if (accessor.isGetter()) "getter" else "setter")
|
||||||
|
return what + " for " + (if (containingProperty != null) containingProperty.getDebugText() else "...")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitClass(klass: JetClass, data: Unit?): String? {
|
||||||
|
return buildText {
|
||||||
|
append("STUB: ")
|
||||||
|
appendInn(klass.getModifierList(), suffix = " ")
|
||||||
|
append("class ")
|
||||||
|
appendInn(klass.getNameAsName())
|
||||||
|
appendInn(klass.getTypeParameterList())
|
||||||
|
appendInn(klass.getPrimaryConstructorModifierList(), prefix = " ", suffix = " ")
|
||||||
|
appendInn(klass.getPrimaryConstructorParameterList())
|
||||||
|
appendInn(klass.getDelegationSpecifierList(), prefix = " : ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitNamedFunction(function: JetNamedFunction, data: Unit?): String? {
|
||||||
|
return buildText {
|
||||||
|
append("STUB: ")
|
||||||
|
appendInn(function.getModifierList(), suffix = " ")
|
||||||
|
append("fun ")
|
||||||
|
|
||||||
|
val typeParameterList = function.getTypeParameterList()
|
||||||
|
if (function.hasTypeParameterListBeforeFunctionName()) {
|
||||||
|
appendInn(typeParameterList, suffix = " ")
|
||||||
|
}
|
||||||
|
appendInn(function.getReceiverTypeRef(), suffix = ".")
|
||||||
|
appendInn(function.getNameAsName())
|
||||||
|
if (!function.hasTypeParameterListBeforeFunctionName()) {
|
||||||
|
appendInn(typeParameterList)
|
||||||
|
}
|
||||||
|
appendInn(function.getValueParameterList())
|
||||||
|
appendInn(function.getReturnTypeRef(), prefix = ": ")
|
||||||
|
appendInn(function.getTypeConstraintList(), prefix = " ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitObjectDeclaration(declaration: JetObjectDeclaration, data: Unit?): String? {
|
||||||
|
return buildText {
|
||||||
|
append("STUB: ")
|
||||||
|
appendInn(declaration.getModifierList(), suffix = " ")
|
||||||
|
append("object ")
|
||||||
|
appendInn(declaration.getNameAsName())
|
||||||
|
appendInn(declaration.getDelegationSpecifierList(), prefix = " : ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitParameter(parameter: JetParameter, data: Unit?): String? {
|
||||||
|
return buildText {
|
||||||
|
if (parameter.hasValOrVarNode()) {
|
||||||
|
if (parameter.isMutable()) append("var ") else append("val ")
|
||||||
|
}
|
||||||
|
val name = parameter.getNameAsName()
|
||||||
|
appendInn(name)
|
||||||
|
val typeReference = parameter.getTypeReference()
|
||||||
|
if (typeReference != null && name != null) {
|
||||||
|
append(": ")
|
||||||
|
}
|
||||||
|
appendInn(typeReference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitProperty(property: JetProperty, data: Unit?): String? {
|
||||||
|
return buildText {
|
||||||
|
append("STUB: ")
|
||||||
|
appendInn(property.getModifierList(), suffix = " ")
|
||||||
|
append(if (property.isVar()) "var " else "val ")
|
||||||
|
appendInn(property.getNameAsName())
|
||||||
|
appendInn(property.getTypeRef(), prefix = ": ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeConstraint(constraint: JetTypeConstraint, data: Unit?): String? {
|
||||||
|
return buildText {
|
||||||
|
if (constraint.isClassObjectConstraint()) {
|
||||||
|
append("class object ")
|
||||||
|
}
|
||||||
|
appendInn(constraint.getSubjectTypeParameterName())
|
||||||
|
appendInn(constraint.getBoundTypeReference(), prefix = " : ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun buildText(body: StringBuilder.() -> Unit): String? {
|
||||||
|
val sb = StringBuilder()
|
||||||
|
sb.body()
|
||||||
|
return sb.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun renderChildren(element: JetElementImplStub<*>, separator: String, prefix: String = "", postfix: String = ""): String? {
|
||||||
|
val childrenTexts = element.getStub()?.getChildrenStubs()?.map { (it?.getPsi() as? JetElement)?.getDebugText() }
|
||||||
|
return childrenTexts?.filterNotNull()?.makeString(separator, prefix, postfix) ?: element.getText()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun render(element: JetElementImplStub<*>, vararg relevantChildren: JetElement?): String? {
|
||||||
|
if (element.getStub() == null) return element.getText()
|
||||||
|
return relevantChildren.filterNotNull().map { it.getDebugText() }.makeString("", "", "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun StringBuilder.appendInn(target: Any?, prefix: String = "", suffix: String = "") {
|
||||||
|
if (target == null) return
|
||||||
|
append(prefix)
|
||||||
|
append(when (target) {
|
||||||
|
is JetElement -> target.getDebugText()
|
||||||
|
else -> target.toString()
|
||||||
|
})
|
||||||
|
append(suffix)
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@ import com.intellij.psi.PsiElement;
|
|||||||
import com.intellij.util.IncorrectOperationException;
|
import com.intellij.util.IncorrectOperationException;
|
||||||
import org.jetbrains.annotations.NonNls;
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.JetNodeTypes;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.psi.stubs.PsiJetClassStub;
|
import org.jetbrains.jet.lang.psi.stubs.PsiJetClassStub;
|
||||||
import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementTypes;
|
import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementTypes;
|
||||||
|
|
||||||
@@ -63,13 +63,18 @@ public class JetEnumEntry extends JetClass {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<JetDelegationSpecifier> getDelegationSpecifiers() {
|
public List<JetDelegationSpecifier> getDelegationSpecifiers() {
|
||||||
JetInitializerList initializerList = getStubOrPsiChild(JetStubElementTypes.INITIALIZER_LIST);
|
JetInitializerList initializerList = getInitializerList();
|
||||||
if (initializerList == null) {
|
if (initializerList == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
return initializerList.getInitializers();
|
return initializerList.getInitializers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public JetInitializerList getInitializerList() {
|
||||||
|
return getStubOrPsiChild(JetStubElementTypes.INITIALIZER_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
|
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
|
||||||
return visitor.visitEnumEntry(this, data);
|
return visitor.visitEnumEntry(this, data);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ abstract class JetTypeParameterListOwnerStub<T extends PsiJetStubWithFqName> ext
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
JetTypeConstraintList getTypeConstraintList() {
|
public JetTypeConstraintList getTypeConstraintList() {
|
||||||
return getStubOrPsiChild(JetStubElementTypes.TYPE_CONSTRAINT_LIST);
|
return getStubOrPsiChild(JetStubElementTypes.TYPE_CONSTRAINT_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,226 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.plugin.stubs
|
||||||
|
|
||||||
|
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFile
|
||||||
|
import org.jetbrains.jet.lang.psi.stubs.elements.JetFileStubBuilder
|
||||||
|
import com.intellij.psi.stubs.StubElement
|
||||||
|
import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementTypes
|
||||||
|
import org.junit.Assert
|
||||||
|
import org.jetbrains.jet.lang.psi.JetPackageDirective
|
||||||
|
import org.jetbrains.jet.lang.psi.stubs.PsiJetPlaceHolderStub
|
||||||
|
import org.jetbrains.jet.lang.psi.JetImportList
|
||||||
|
import org.jetbrains.jet.lang.psi.JetNamedFunction
|
||||||
|
import org.jetbrains.jet.lang.psi.stubs.PsiJetFunctionStub
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeReference
|
||||||
|
import org.jetbrains.jet.lang.psi.stubs.PsiJetClassStub
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClass
|
||||||
|
import org.jetbrains.jet.lang.psi.stubs.PsiJetObjectStub
|
||||||
|
import org.jetbrains.jet.lang.psi.JetObjectDeclaration
|
||||||
|
import org.jetbrains.jet.lang.psi.JetProperty
|
||||||
|
import org.jetbrains.jet.lang.psi.stubs.PsiJetPropertyStub
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClassBody
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClassInitializer
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClassObject
|
||||||
|
import org.jetbrains.jet.lang.psi.debugText.getDebugText
|
||||||
|
|
||||||
|
public class DebugTextByStubTest : LightCodeInsightFixtureTestCase() {
|
||||||
|
private fun createFileAndStubTree(text: String): Pair<JetFile, StubElement<*>> {
|
||||||
|
val file = myFixture.configureByText("test.kt", text) as JetFile
|
||||||
|
val stub = JetFileStubBuilder().buildStubTree(file)!!
|
||||||
|
return Pair(file, stub)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createStubTree(text: String) = createFileAndStubTree(text).second
|
||||||
|
|
||||||
|
fun packageDirective(text: String) {
|
||||||
|
val (file, tree) = createFileAndStubTree(text)
|
||||||
|
val packageDirective = tree.findChildStubByType(JetStubElementTypes.PACKAGE_DIRECTIVE)
|
||||||
|
val psi = JetPackageDirective(packageDirective as PsiJetPlaceHolderStub)
|
||||||
|
Assert.assertEquals(file.getPackageDirective()!!.getText(), psi.getDebugText())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun function(text: String) {
|
||||||
|
val (file, tree) = createFileAndStubTree(text)
|
||||||
|
val function = tree.findChildStubByType(JetStubElementTypes.FUNCTION)
|
||||||
|
val psi = JetNamedFunction(function as PsiJetFunctionStub)
|
||||||
|
Assert.assertEquals("STUB: " + file.findChildByClass(javaClass<JetNamedFunction>())!!.getText(), psi.getDebugText())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun typeReference(text: String) {
|
||||||
|
val (file, tree) = createFileAndStubTree("fun foo(i: $text)")
|
||||||
|
val function = tree.findChildStubByType(JetStubElementTypes.FUNCTION)!!
|
||||||
|
val parameterList = function.findChildStubByType(JetStubElementTypes.VALUE_PARAMETER_LIST)!!
|
||||||
|
val valueParameter = parameterList.findChildStubByType(JetStubElementTypes.VALUE_PARAMETER)!!
|
||||||
|
val typeReferenceStub = valueParameter.findChildStubByType(JetStubElementTypes.TYPE_REFERENCE)
|
||||||
|
val psiFromStub = JetTypeReference(typeReferenceStub as PsiJetPlaceHolderStub)
|
||||||
|
val typeReferenceByPsi = file.findChildByClass(javaClass<JetNamedFunction>())!!.getValueParameters()[0].getTypeReference()
|
||||||
|
Assert.assertEquals(typeReferenceByPsi!!.getText(), psiFromStub.getDebugText())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clazz(text: String, expectedText: String? = null) {
|
||||||
|
val (file, tree) = createFileAndStubTree(text)
|
||||||
|
val clazz = tree.findChildStubByType(JetStubElementTypes.CLASS)!!
|
||||||
|
val psiFromStub = JetClass(clazz as PsiJetClassStub)
|
||||||
|
val classByPsi = file.findChildByClass(javaClass<JetClass>())
|
||||||
|
val toCheckAgainst = "STUB: " + (expectedText ?: classByPsi!!.getText())
|
||||||
|
Assert.assertEquals(toCheckAgainst, psiFromStub.getDebugText())
|
||||||
|
if (expectedText != null) {
|
||||||
|
Assert.assertNotEquals("Expected text should not be specified", classByPsi.getDebugText(), psiFromStub.getDebugText())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun obj(text: String, expectedText: String? = null) {
|
||||||
|
val (file, tree) = createFileAndStubTree(text)
|
||||||
|
val obj = tree.findChildStubByType(JetStubElementTypes.OBJECT_DECLARATION)!!
|
||||||
|
val psiFromStub = JetObjectDeclaration(obj as PsiJetObjectStub)
|
||||||
|
val objectByPsi = file.findChildByClass(javaClass<JetObjectDeclaration>())
|
||||||
|
val toCheckAgainst = "STUB: " + (expectedText ?: objectByPsi!!.getText())
|
||||||
|
Assert.assertEquals(toCheckAgainst, psiFromStub.getDebugText())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun property(text: String, expectedText: String? = null) {
|
||||||
|
val (file, tree) = createFileAndStubTree(text)
|
||||||
|
val property = tree.findChildStubByType(JetStubElementTypes.PROPERTY)!!
|
||||||
|
val psiFromStub = JetProperty(property as PsiJetPropertyStub)
|
||||||
|
val propertyByPsi = file.findChildByClass(javaClass<JetProperty>())
|
||||||
|
val toCheckAgainst = "STUB: " + (expectedText ?: propertyByPsi!!.getText())
|
||||||
|
Assert.assertEquals(toCheckAgainst, psiFromStub.getDebugText())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun importList(text: String) {
|
||||||
|
val (file, tree) = createFileAndStubTree(text)
|
||||||
|
val importList = tree.findChildStubByType(JetStubElementTypes.IMPORT_LIST)
|
||||||
|
val psi = JetImportList(importList as PsiJetPlaceHolderStub)
|
||||||
|
Assert.assertEquals(file.getImportList()!!.getText(), psi.getDebugText())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testPackageDirective() {
|
||||||
|
packageDirective("package a.b.c")
|
||||||
|
packageDirective("")
|
||||||
|
packageDirective("package b")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testImportList() {
|
||||||
|
importList("import a\nimport b.c.d")
|
||||||
|
importList("import a.*")
|
||||||
|
importList("import a.c as Alias")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testFunction() {
|
||||||
|
function("fun foo()")
|
||||||
|
function("fun <T> foo()")
|
||||||
|
function("fun foo<T>()")
|
||||||
|
function("fun foo<T, G>()")
|
||||||
|
function("fun foo(a: Int, b: String)")
|
||||||
|
function("fun Int.foo()")
|
||||||
|
function("fun foo(): String")
|
||||||
|
function("fun <T> T.foo(b: T): List<T>")
|
||||||
|
function("fun <T, G> f() where T : G")
|
||||||
|
function("fun <T, G> f() where T : G, G : T")
|
||||||
|
function("fun <T, G> f() where class object T : G")
|
||||||
|
function("private final fun f()")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testTypeReference() {
|
||||||
|
typeReference("T")
|
||||||
|
typeReference("T<G>")
|
||||||
|
typeReference("T<G, H>")
|
||||||
|
typeReference("T<in G>")
|
||||||
|
typeReference("T<out G>")
|
||||||
|
typeReference("T<*>")
|
||||||
|
typeReference("T<*, in G>")
|
||||||
|
typeReference("T?")
|
||||||
|
typeReference("T<G?>")
|
||||||
|
typeReference("() -> T")
|
||||||
|
typeReference("(G?, H) -> T?")
|
||||||
|
typeReference("L.(G?, H) -> T?")
|
||||||
|
typeReference("L?.(G?, H) -> T?")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testClass() {
|
||||||
|
clazz("class A")
|
||||||
|
clazz("open private class A")
|
||||||
|
clazz("public class private A")
|
||||||
|
clazz("class A()")
|
||||||
|
clazz("class A() : B()", expectedText = "class A() : B")
|
||||||
|
clazz("class A() : B<T>")
|
||||||
|
clazz("class A() : B(), C()", expectedText = "class A() : B, C")
|
||||||
|
clazz("class A() : B by g", expectedText = "class A() : B")
|
||||||
|
clazz("class A() : B by g, C(), T", expectedText = "class A() : B, C, T")
|
||||||
|
clazz("class A(i: Int, g: String)")
|
||||||
|
clazz("class A(val i: Int, var g: String)")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testObject() {
|
||||||
|
obj("object Foo")
|
||||||
|
obj("public final object Foo")
|
||||||
|
obj("object Foo : A()", expectedText = "object Foo : A")
|
||||||
|
obj("object Foo : A by foo", expectedText = "object Foo : A")
|
||||||
|
obj("object Foo : A, T, C by g, B()", expectedText = "object Foo : A, T, C, B")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testProperty() {
|
||||||
|
property("val c: Int")
|
||||||
|
property("var c: Int")
|
||||||
|
property("var : Int")
|
||||||
|
property("private final var c: Int")
|
||||||
|
property("val g")
|
||||||
|
property("val g = 3", expectedText = "val g")
|
||||||
|
property("val g by z", expectedText = "val g")
|
||||||
|
property("val g: Int by z", expectedText = "val g: Int")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testClassBody() {
|
||||||
|
val tree = createStubTree("class A {\n {} fun f(): Int val c: Int}")
|
||||||
|
val classBody = tree.findChildStubByType(JetStubElementTypes.CLASS)!!.findChildStubByType(JetStubElementTypes.CLASS_BODY)
|
||||||
|
assertEquals("class body for STUB: class A", JetClassBody(classBody as PsiJetPlaceHolderStub).getDebugText())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testClassInitializer() {
|
||||||
|
val tree = createStubTree("class A {\n {} }")
|
||||||
|
val initializer = tree.findChildStubByType(JetStubElementTypes.CLASS)!!.findChildStubByType(JetStubElementTypes.CLASS_BODY)!!
|
||||||
|
.findChildStubByType(JetStubElementTypes.ANONYMOUS_INITIALIZER)
|
||||||
|
assertEquals("initializer in STUB: class A", JetClassInitializer(initializer as PsiJetPlaceHolderStub).getDebugText())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testClassObject() {
|
||||||
|
val tree = createStubTree("class A { class object {} }")
|
||||||
|
val classObject = tree.findChildStubByType(JetStubElementTypes.CLASS)!!.findChildStubByType(JetStubElementTypes.CLASS_BODY)!!
|
||||||
|
.findChildStubByType(JetStubElementTypes.CLASS_OBJECT)
|
||||||
|
assertEquals("class object in STUB: class A", JetClassObject(classObject as PsiJetPlaceHolderStub).getDebugText())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testPropertyAccessors() {
|
||||||
|
val tree = createStubTree("var c: Int\nget() = 3\nset(i: Int) {}")
|
||||||
|
val propertyStub = tree.findChildStubByType(JetStubElementTypes.PROPERTY)!!
|
||||||
|
val accessors = propertyStub.getChildrenByType(JetStubElementTypes.PROPERTY_ACCESSOR, JetStubElementTypes.PROPERTY_ACCESSOR.getArrayFactory())!!
|
||||||
|
assertEquals("getter for STUB: var c: Int", accessors[0].getDebugText())
|
||||||
|
assertEquals("setter for STUB: var c: Int", accessors[1].getDebugText())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testEnumEntry() {
|
||||||
|
val tree = createStubTree("enum class Enum { E1 E2: Enum() E3: Enum(1, 2)}")
|
||||||
|
val enumClass = tree.findChildStubByType(JetStubElementTypes.CLASS)!!.findChildStubByType(JetStubElementTypes.CLASS_BODY)!!
|
||||||
|
val entries = enumClass.getChildrenByType(JetStubElementTypes.ENUM_ENTRY, JetStubElementTypes.ENUM_ENTRY.getArrayFactory())!!
|
||||||
|
assertEquals("STUB: enum entry E1", entries[0].getDebugText())
|
||||||
|
assertEquals("STUB: enum entry E2 : Enum", entries[1].getDebugText())
|
||||||
|
assertEquals("STUB: enum entry E3 : Enum", entries[2].getDebugText())
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user