Test it's safe to call PsiElement methods on Kotlin light elements
This commit is contained in:
committed by
Nikolay Krasko
parent
7c752c1463
commit
178aba54dd
+2
@@ -27,4 +27,6 @@ public class KotlinLightTypeParameterListBuilder(manager: PsiManager): LightType
|
||||
override fun processDeclarations(processor: PsiScopeProcessor, state: ResolveState, lastParent: PsiElement?, place: PsiElement): Boolean {
|
||||
return getTypeParameters().all { processor.execute(it, state) }
|
||||
}
|
||||
|
||||
override fun getText(): String? = ""
|
||||
}
|
||||
|
||||
@@ -69,9 +69,9 @@ sealed class KtLightFieldImpl(
|
||||
|
||||
override fun hasModifierProperty(@NonNls name: String) = delegate.hasModifierProperty(name)
|
||||
|
||||
override fun getText() = delegate.text
|
||||
override fun getText() = origin?.text ?: ""
|
||||
|
||||
override fun getTextRange() = TextRange(-1, -1)
|
||||
override fun getTextRange() = origin?.textRange ?: TextRange.EMPTY_RANGE
|
||||
|
||||
override fun isValid() = containingClass.isValid
|
||||
|
||||
@@ -82,7 +82,7 @@ sealed class KtLightFieldImpl(
|
||||
override fun getDelegate() = delegate
|
||||
|
||||
override fun getNavigationElement() = origin ?: super.getNavigationElement()
|
||||
|
||||
|
||||
override fun isEquivalentTo(another: PsiElement?): Boolean {
|
||||
if (another is KtLightField && origin == another.getOrigin() && delegate == another.getDelegate()) {
|
||||
return true
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.asJava
|
||||
|
||||
import com.intellij.core.JavaCoreBundle
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.light.LightMethod
|
||||
import com.intellij.psi.scope.PsiScopeProcessor
|
||||
@@ -68,6 +69,8 @@ sealed class KtLightMethodImpl(
|
||||
override fun getDelegate() = delegate
|
||||
override fun getOrigin() = origin
|
||||
override fun getParent(): PsiElement? = containingClass
|
||||
override fun getText() = origin?.text ?: ""
|
||||
override fun getTextRange() = origin?.textRange ?: TextRange.EMPTY_RANGE
|
||||
|
||||
override fun accept(visitor: PsiElementVisitor) {
|
||||
if (visitor is JavaElementVisitor) {
|
||||
@@ -140,7 +143,7 @@ sealed class KtLightMethodImpl(
|
||||
override fun hashCode(): Int = ((name.hashCode() * 31 + (origin?.hashCode() ?: 0)) * 31 + containingClass.hashCode()) * 31 + delegate.hashCode()
|
||||
|
||||
override fun toString(): String = "${this.javaClass.simpleName}:$name"
|
||||
|
||||
|
||||
private class KtLightMethodForDeclaration(
|
||||
delegate: PsiMethod, origin: KtDeclaration?, containingClass: KtLightClass
|
||||
) : KtLightMethodImpl(delegate, origin, containingClass)
|
||||
|
||||
@@ -135,4 +135,9 @@ public class KtLightParameter extends LightParameter implements KtLightElement<K
|
||||
public KtLightMethod getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,11 @@ public class KtLightTypeParameter
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
|
||||
@@ -155,7 +155,7 @@ public abstract class KtWrappingLightClass extends AbstractLightClass implements
|
||||
@Override
|
||||
public String getText() {
|
||||
KtClassOrObject origin = getOrigin();
|
||||
return origin == null ? null : origin.getText();
|
||||
return origin == null ? "" : origin.getText();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescrip
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractIdeLightClassTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
|
||||
fun doTest(testDataPath: String) {
|
||||
myFixture.configureByFile(testDataPath)
|
||||
|
||||
@@ -32,15 +31,23 @@ abstract class AbstractIdeLightClassTest : KotlinLightCodeInsightFixtureTestCase
|
||||
LightClassTestCommon.testLightClass(
|
||||
File(testDataPath),
|
||||
findLightClass = {
|
||||
JavaPsiFacade.getInstance(project).findClass(it, GlobalSearchScope.allScope(project))
|
||||
val clazz = JavaPsiFacade.getInstance(project).findClass(it, GlobalSearchScope.allScope(project))
|
||||
if (clazz != null) {
|
||||
PsiElementChecker.checkPsiElementStructure(clazz)
|
||||
}
|
||||
clazz
|
||||
|
||||
},
|
||||
normalizeText = {
|
||||
//NOTE: ide and compiler differ in names generated for parameters with unspecified names
|
||||
it.replace("java.lang.String s,", "java.lang.String p,").replace("java.lang.String s)", "java.lang.String p)")
|
||||
.replace("java.lang.String s1", "java.lang.String p1").replace("java.lang.String s2", "java.lang.String p2")
|
||||
it
|
||||
.replace("java.lang.String s,", "java.lang.String p,")
|
||||
.replace("java.lang.String s)", "java.lang.String p)")
|
||||
.replace("java.lang.String s1", "java.lang.String p1")
|
||||
.replace("java.lang.String s2", "java.lang.String p2")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.idea.caches.resolve;
|
||||
|
||||
public class AssertionErrorWithCause extends AssertionError {
|
||||
public AssertionErrorWithCause(String detailMessage, Throwable cause) {
|
||||
super(detailMessage);
|
||||
|
||||
initCause(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.idea.caches.resolve
|
||||
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.asJava.KtLightElement
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.junit.Assert
|
||||
|
||||
object PsiElementChecker {
|
||||
val TEST_DATA_KEY = Key.create<Int>("Test Key")
|
||||
|
||||
public fun checkPsiElementStructure(lightClass: PsiClass) {
|
||||
checkPsiElement(lightClass)
|
||||
|
||||
lightClass.innerClasses.forEach { checkPsiElementStructure(it) }
|
||||
|
||||
lightClass.methods.forEach {
|
||||
it.parameterList.parameters.forEach { checkPsiElement(it) }
|
||||
checkPsiElement(it)
|
||||
}
|
||||
|
||||
lightClass.fields.forEach { checkPsiElement(it) }
|
||||
}
|
||||
|
||||
private fun checkPsiElement(element: PsiElement) {
|
||||
if (element !is KtLightElement<*, *>) return
|
||||
|
||||
if (element is PsiModifierListOwner) {
|
||||
val modifierList = element.modifierList
|
||||
if (modifierList != null) {
|
||||
checkPsiElement(modifierList)
|
||||
}
|
||||
}
|
||||
|
||||
if (element is PsiTypeParameterListOwner) {
|
||||
val typeParameterList = element.typeParameterList
|
||||
if (typeParameterList != null) {
|
||||
checkPsiElement(typeParameterList)
|
||||
typeParameterList.typeParameters.forEach { checkPsiElement(it) }
|
||||
}
|
||||
}
|
||||
|
||||
with(element) {
|
||||
try {
|
||||
Assert.assertEquals("Number of methods has changed. Please update test.", 54, PsiElement::class.java.methods.size)
|
||||
|
||||
project
|
||||
Assert.assertTrue(language == KotlinLanguage.INSTANCE)
|
||||
manager
|
||||
children
|
||||
parent
|
||||
firstChild
|
||||
lastChild
|
||||
nextSibling
|
||||
prevSibling
|
||||
containingFile
|
||||
textRange
|
||||
startOffsetInParent
|
||||
textLength
|
||||
findElementAt(0)
|
||||
findReferenceAt(0)
|
||||
textOffset
|
||||
text
|
||||
textToCharArray()
|
||||
navigationElement
|
||||
originalElement
|
||||
textMatches("")
|
||||
Assert.assertTrue(textMatches(this))
|
||||
textContains('a')
|
||||
accept(PsiElementVisitor.EMPTY_VISITOR)
|
||||
acceptChildren(PsiElementVisitor.EMPTY_VISITOR)
|
||||
|
||||
val copy = copy()
|
||||
Assert.assertTrue(copy == null || copy.javaClass == this.javaClass)
|
||||
|
||||
// Modify methods:
|
||||
// add(this)
|
||||
// addBefore(this, lastChild)
|
||||
// addAfter(firstChild, this)
|
||||
// checkAdd(this)
|
||||
// addRange(firstChild, lastChild)
|
||||
// addRangeBefore(firstChild, lastChild, lastChild)
|
||||
// addRangeAfter(firstChild, lastChild, firstChild)
|
||||
// delete()
|
||||
// checkDelete()
|
||||
// deleteChildRange(firstChild, lastChild)
|
||||
// replace(this)
|
||||
|
||||
Assert.assertTrue(isValid)
|
||||
isWritable
|
||||
reference
|
||||
references
|
||||
putCopyableUserData(TEST_DATA_KEY, 12)
|
||||
|
||||
Assert.assertTrue(getCopyableUserData(TEST_DATA_KEY) == 12)
|
||||
// Assert.assertTrue(copy().getCopyableUserData(TEST_DATA_KEY) == 12) { this } Doesn't work
|
||||
|
||||
// processDeclarations(...)
|
||||
|
||||
context
|
||||
isPhysical
|
||||
resolveScope
|
||||
useScope
|
||||
node
|
||||
toString()
|
||||
Assert.assertTrue(isEquivalentTo(this))
|
||||
}
|
||||
catch (t: Throwable) {
|
||||
throw AssertionErrorWithCause("Failed for ${this.javaClass} ${this}", t)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user