Cleanup 201 and as41 bunch files
This commit is contained in:
-13
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
|
||||
// This object should help compiling against different ASM versions from different bunch versions
|
||||
object VersionIndependentOpcodes {
|
||||
const val ACC_RECORD = 0
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* 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.codegen;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.inline.FileMapping;
|
||||
import org.jetbrains.kotlin.codegen.inline.SMAPBuilder;
|
||||
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP;
|
||||
|
||||
public abstract class AbstractClassBuilder implements ClassBuilder {
|
||||
protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.API_VERSION) {};
|
||||
protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.API_VERSION) {};
|
||||
|
||||
private String thisName;
|
||||
|
||||
private final JvmSerializationBindings serializationBindings = new JvmSerializationBindings();
|
||||
|
||||
private String sourceName;
|
||||
|
||||
private String debugInfo;
|
||||
|
||||
public static class Concrete extends AbstractClassBuilder {
|
||||
private final ClassVisitor v;
|
||||
|
||||
public Concrete(@NotNull ClassVisitor v) {
|
||||
this.v = v;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public ClassVisitor getVisitor() {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public FieldVisitor newField(
|
||||
@NotNull JvmDeclarationOrigin origin,
|
||||
int access,
|
||||
@NotNull String name,
|
||||
@NotNull String desc,
|
||||
@Nullable String signature,
|
||||
@Nullable Object value
|
||||
) {
|
||||
FieldVisitor visitor = getVisitor().visitField(access, name, desc, signature, value);
|
||||
if (visitor == null) {
|
||||
return EMPTY_FIELD_VISITOR;
|
||||
}
|
||||
return visitor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public MethodVisitor newMethod(
|
||||
@NotNull JvmDeclarationOrigin origin,
|
||||
int access,
|
||||
@NotNull String name,
|
||||
@NotNull String desc,
|
||||
@Nullable String signature,
|
||||
@Nullable String[] exceptions
|
||||
) {
|
||||
MethodVisitor visitor = getVisitor().visitMethod(access, name, desc, signature, exceptions);
|
||||
if (visitor == null) {
|
||||
return EMPTY_METHOD_VISITOR;
|
||||
}
|
||||
return visitor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JvmSerializationBindings getSerializationBindings() {
|
||||
return serializationBindings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible) {
|
||||
return getVisitor().visitAnnotation(desc, visible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void done() {
|
||||
getVisitor().visitSource(sourceName, debugInfo);
|
||||
getVisitor().visitEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineClass(
|
||||
@Nullable PsiElement origin,
|
||||
int version,
|
||||
int access,
|
||||
@NotNull String name,
|
||||
@Nullable String signature,
|
||||
@NotNull String superName,
|
||||
@NotNull String[] interfaces
|
||||
) {
|
||||
thisName = name;
|
||||
getVisitor().visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSource(@NotNull String name, @Nullable String debug) {
|
||||
assert sourceName == null || sourceName.equals(name) : "inconsistent file name: " + sourceName + " vs " + name;
|
||||
sourceName = name;
|
||||
debugInfo = debug;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSMAP(@NotNull SourceMapper smap, boolean backwardsCompatibleSyntax) {
|
||||
if (!GENERATE_SMAP) return;
|
||||
|
||||
List<FileMapping> fileMappings = smap.getResultMappings();
|
||||
if (fileMappings.isEmpty()) return;
|
||||
|
||||
visitSource(fileMappings.get(0).getName(), SMAPBuilder.INSTANCE.build(fileMappings, backwardsCompatibleSyntax));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc) {
|
||||
getVisitor().visitOuterClass(owner, name, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access) {
|
||||
getVisitor().visitInnerClass(name, outerName, innerName, access);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getThisName() {
|
||||
assert thisName != null : "This name isn't set";
|
||||
return thisName;
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* 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.codegen;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
|
||||
public interface ClassBuilder {
|
||||
@NotNull
|
||||
FieldVisitor newField(
|
||||
@NotNull JvmDeclarationOrigin origin,
|
||||
int access,
|
||||
@NotNull String name,
|
||||
@NotNull String desc,
|
||||
@Nullable String signature,
|
||||
@Nullable Object value
|
||||
);
|
||||
|
||||
@NotNull
|
||||
MethodVisitor newMethod(
|
||||
@NotNull JvmDeclarationOrigin origin,
|
||||
int access,
|
||||
@NotNull String name,
|
||||
@NotNull String desc,
|
||||
@Nullable String signature,
|
||||
@Nullable String[] exceptions
|
||||
);
|
||||
|
||||
@NotNull
|
||||
JvmSerializationBindings getSerializationBindings();
|
||||
|
||||
@NotNull
|
||||
AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible);
|
||||
|
||||
void done();
|
||||
|
||||
@NotNull
|
||||
ClassVisitor getVisitor();
|
||||
|
||||
void defineClass(
|
||||
@Nullable PsiElement origin,
|
||||
int version,
|
||||
int access,
|
||||
@NotNull String name,
|
||||
@Nullable String signature,
|
||||
@NotNull String superName,
|
||||
@NotNull String[] interfaces
|
||||
);
|
||||
|
||||
void visitSource(@NotNull String name, @Nullable String debug);
|
||||
|
||||
void visitSMAP(@NotNull SourceMapper smap, boolean backwardsCompatibleSyntax);
|
||||
|
||||
void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc);
|
||||
|
||||
void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access);
|
||||
|
||||
@NotNull
|
||||
String getThisName();
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
@Suppress("UNUSED_PARAMETER", "unused")
|
||||
fun ClassBuilder.addRecordComponent(name: String, desc: String, signature: String?) {
|
||||
// newRecordComponent(name, desc, signature)
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* 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.codegen;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
|
||||
public abstract class DelegatingClassBuilder implements ClassBuilder {
|
||||
@NotNull
|
||||
protected abstract ClassBuilder getDelegate();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FieldVisitor newField(
|
||||
@NotNull JvmDeclarationOrigin origin,
|
||||
int access,
|
||||
@NotNull String name,
|
||||
@NotNull String desc,
|
||||
@Nullable String signature,
|
||||
@Nullable Object value
|
||||
) {
|
||||
return getDelegate().newField(origin, access, name, desc, signature, value);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public MethodVisitor newMethod(
|
||||
@NotNull JvmDeclarationOrigin origin,
|
||||
int access,
|
||||
@NotNull String name,
|
||||
@NotNull String desc,
|
||||
@Nullable String signature,
|
||||
@Nullable String[] exceptions
|
||||
) {
|
||||
return getDelegate().newMethod(origin, access, name, desc, signature, exceptions);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JvmSerializationBindings getSerializationBindings() {
|
||||
return getDelegate().getSerializationBindings();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible) {
|
||||
return getDelegate().newAnnotation(desc, visible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void done() {
|
||||
getDelegate().done();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ClassVisitor getVisitor() {
|
||||
return getDelegate().getVisitor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineClass(
|
||||
@Nullable PsiElement origin,
|
||||
int version,
|
||||
int access,
|
||||
@NotNull String name,
|
||||
@Nullable String signature,
|
||||
@NotNull String superName,
|
||||
@NotNull String[] interfaces
|
||||
) {
|
||||
getDelegate().defineClass(origin, version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSource(@NotNull String name, @Nullable String debug) {
|
||||
getDelegate().visitSource(name, debug);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSMAP(@NotNull SourceMapper smap, boolean backwardsCompatibleSyntax) {
|
||||
getDelegate().visitSMAP(smap, backwardsCompatibleSyntax);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc) {
|
||||
getDelegate().visitOuterClass(owner, name, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access) {
|
||||
getDelegate().visitInnerClass(name, outerName, innerName, access);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getThisName() {
|
||||
return getDelegate().getThisName();
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.optimization.common
|
||||
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
||||
|
||||
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>?>
|
||||
@@ -1,8 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.state
|
||||
|
||||
typealias JvmMethodExceptionTypes = Array<out String>?
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension
|
||||
import com.intellij.pom.java.LanguageLevel
|
||||
|
||||
fun Project.setupHighestLanguageLevel() {
|
||||
// LanguageLevelProjectExtension.getInstance(this).languageLevel = LanguageLevel.JDK_15_PREVIEW
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
fun setupIdeaStandaloneExecution() {
|
||||
System.getProperties().setProperty("idea.plugins.compatible.build", "201.6668.13")
|
||||
System.getProperties().setProperty("project.structure.add.tools.jar.to.new.jdk", "false")
|
||||
System.getProperties().setProperty("psi.track.invalidation", "true")
|
||||
System.getProperties().setProperty("psi.incremental.reparse.depth.limit", "1000")
|
||||
System.getProperties().setProperty("ide.hide.excluded.files", "false")
|
||||
System.getProperties().setProperty("ast.loading.filter", "false")
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.asJava.classes
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.augment.PsiAugmentProvider
|
||||
|
||||
internal fun <Psi : PsiElement> collectAugments(element: PsiElement, type: Class<out Psi>): List<Psi> {
|
||||
return PsiAugmentProvider.collectAugments(element, type)
|
||||
}
|
||||
-154
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.load.java.structure.impl
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiTypeParameter
|
||||
import com.intellij.psi.search.SearchScope
|
||||
import org.jetbrains.kotlin.asJava.KtLightClassMarker
|
||||
import org.jetbrains.kotlin.asJava.isSyntheticValuesOrValueOfMethod
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
|
||||
class JavaClassImpl(psiClass: PsiClass) : JavaClassifierImpl<PsiClass>(psiClass), VirtualFileBoundJavaClass, JavaAnnotationOwnerImpl, JavaModifierListOwnerImpl {
|
||||
init {
|
||||
assert(psiClass !is PsiTypeParameter) { "PsiTypeParameter should be wrapped in JavaTypeParameter, not JavaClass: use JavaClassifier.create()" }
|
||||
}
|
||||
|
||||
override val innerClassNames: Collection<Name>
|
||||
get() = psi.innerClasses.mapNotNull { it.name?.takeIf(Name::isValidIdentifier)?.let(Name::identifier) }
|
||||
|
||||
override fun findInnerClass(name: Name): JavaClass? {
|
||||
return psi.findInnerClassByName(name.asString(), false)?.let(::JavaClassImpl)
|
||||
}
|
||||
|
||||
override val fqName: FqName?
|
||||
get() {
|
||||
val qualifiedName = psi.qualifiedName
|
||||
return if (qualifiedName == null) null else FqName(qualifiedName)
|
||||
}
|
||||
|
||||
override val name: Name
|
||||
get() = KtPsiUtil.safeName(psi.name)
|
||||
|
||||
override val isInterface: Boolean
|
||||
get() = psi.isInterface
|
||||
|
||||
override val isAnnotationType: Boolean
|
||||
get() = psi.isAnnotationType
|
||||
|
||||
override val isEnum: Boolean
|
||||
get() = psi.isEnum
|
||||
|
||||
override val isRecord: Boolean
|
||||
get() = false
|
||||
|
||||
override val isSealed: Boolean
|
||||
get() = JavaElementUtil.isSealed(this)
|
||||
|
||||
override val permittedTypes: Collection<JavaClassifierType>
|
||||
get() = emptyList()
|
||||
|
||||
override val outerClass: JavaClassImpl?
|
||||
get() {
|
||||
val outer = psi.containingClass
|
||||
return if (outer == null) null else JavaClassImpl(outer)
|
||||
}
|
||||
|
||||
override val typeParameters: List<JavaTypeParameter>
|
||||
get() = typeParameters(psi.typeParameters)
|
||||
|
||||
override val supertypes: Collection<JavaClassifierType>
|
||||
get() = classifierTypes(psi.superTypes)
|
||||
|
||||
override val methods: Collection<JavaMethod>
|
||||
get() {
|
||||
assertNotLightClass()
|
||||
// We apply distinct here because PsiClass#getMethods() can return duplicate PSI methods, for example in Lombok (see KT-11778)
|
||||
// Return type seems to be null for example for the 'clone' Groovy method generated by @AutoClone (see EA-73795)
|
||||
return methods(
|
||||
psi.methods.filter { method ->
|
||||
!method.isConstructor && method.returnType != null && !(isEnum && isSyntheticValuesOrValueOfMethod(method))
|
||||
}
|
||||
).distinct()
|
||||
}
|
||||
|
||||
override val fields: Collection<JavaField>
|
||||
get() {
|
||||
assertNotLightClass()
|
||||
return fields(psi.fields.filter {
|
||||
// ex. Android plugin generates LightFields for resources started from '.' (.DS_Store file etc)
|
||||
Name.isValidIdentifier(it.name)
|
||||
})
|
||||
}
|
||||
|
||||
override val constructors: Collection<JavaConstructor>
|
||||
get() {
|
||||
assertNotLightClass()
|
||||
// See for example org.jetbrains.plugins.scala.lang.psi.light.ScFunctionWrapper,
|
||||
// which is present in getConstructors(), but its isConstructor() returns false
|
||||
return constructors(psi.constructors.filter { method -> method.isConstructor })
|
||||
}
|
||||
|
||||
override val recordComponents: Collection<JavaRecordComponent>
|
||||
get() {
|
||||
assertNotLightClass()
|
||||
|
||||
return emptyList<JavaRecordComponent>()
|
||||
}
|
||||
|
||||
override fun hasDefaultConstructor() = !isInterface && constructors.isEmpty()
|
||||
|
||||
override val isAbstract: Boolean
|
||||
get() = JavaElementUtil.isAbstract(this)
|
||||
|
||||
override val isStatic: Boolean
|
||||
get() = JavaElementUtil.isStatic(this)
|
||||
|
||||
override val isFinal: Boolean
|
||||
get() = JavaElementUtil.isFinal(this)
|
||||
|
||||
override val visibility: Visibility
|
||||
get() = JavaElementUtil.getVisibility(this)
|
||||
|
||||
override val lightClassOriginKind: LightClassOriginKind?
|
||||
get() = (psi as? KtLightClassMarker)?.originKind
|
||||
|
||||
override val virtualFile: VirtualFile?
|
||||
get() = psi.containingFile?.virtualFile
|
||||
|
||||
override fun isFromSourceCodeInScope(scope: SearchScope): Boolean = psi.containingFile.virtualFile in scope
|
||||
|
||||
override fun getAnnotationOwnerPsi() = psi.modifierList
|
||||
|
||||
private fun assertNotLightClass() {
|
||||
val psiClass = psi
|
||||
if (psiClass !is KtLightClassMarker) return
|
||||
|
||||
val message = "Querying members of JavaClass created for $psiClass of type ${psiClass::class.java} defined in file ${psiClass.containingFile?.virtualFile?.canonicalPath}"
|
||||
LOGGER.error(message)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOGGER = Logger.getInstance(JavaClassImpl::class.java)
|
||||
}
|
||||
}
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* 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.load.java.structure.impl;
|
||||
|
||||
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiAnnotationOwner;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities;
|
||||
import org.jetbrains.kotlin.descriptors.Visibility;
|
||||
import org.jetbrains.kotlin.descriptors.java.JavaVisibilities;
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.jetbrains.kotlin.load.java.structure.impl.JavaElementCollectionFromPsiArrayUtil.annotations;
|
||||
import static org.jetbrains.kotlin.load.java.structure.impl.JavaElementCollectionFromPsiArrayUtil.nullabilityAnnotations;
|
||||
|
||||
/* package */ class JavaElementUtil {
|
||||
private JavaElementUtil() {
|
||||
}
|
||||
|
||||
public static boolean isAbstract(@NotNull JavaModifierListOwnerImpl owner) {
|
||||
return owner.getPsi().hasModifierProperty(PsiModifier.ABSTRACT);
|
||||
}
|
||||
|
||||
public static boolean isStatic(@NotNull JavaModifierListOwnerImpl owner) {
|
||||
return owner.getPsi().hasModifierProperty(PsiModifier.STATIC);
|
||||
}
|
||||
|
||||
public static boolean isFinal(@NotNull JavaModifierListOwnerImpl owner) {
|
||||
return owner.getPsi().hasModifierProperty(PsiModifier.FINAL);
|
||||
}
|
||||
|
||||
public static boolean isSealed(@NotNull JavaModifierListOwnerImpl owner) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Visibility getVisibility(@NotNull JavaModifierListOwnerImpl owner) {
|
||||
PsiModifierListOwner psiOwner = owner.getPsi();
|
||||
if (psiOwner.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
return Visibilities.Public.INSTANCE;
|
||||
}
|
||||
if (psiOwner.hasModifierProperty(PsiModifier.PRIVATE)) {
|
||||
return Visibilities.Private.INSTANCE;
|
||||
}
|
||||
if (psiOwner.hasModifierProperty(PsiModifier.PROTECTED)) {
|
||||
return owner.isStatic() ? JavaVisibilities.ProtectedStaticVisibility.INSTANCE : JavaVisibilities.ProtectedAndPackage.INSTANCE;
|
||||
}
|
||||
return JavaVisibilities.PackageVisibility.INSTANCE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Collection<JavaAnnotation> getAnnotations(@NotNull JavaAnnotationOwnerImpl owner) {
|
||||
PsiAnnotationOwner annotationOwnerPsi = owner.getAnnotationOwnerPsi();
|
||||
if (annotationOwnerPsi != null) {
|
||||
return annotations(annotationOwnerPsi.getAnnotations());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiAnnotation[] getExternalAnnotations(@NotNull JavaModifierListOwnerImpl modifierListOwner) {
|
||||
PsiModifierListOwner psiModifierListOwner = modifierListOwner.getPsi();
|
||||
ExternalAnnotationsManager externalAnnotationManager = ExternalAnnotationsManager
|
||||
.getInstance(psiModifierListOwner.getProject());
|
||||
return externalAnnotationManager.findExternalAnnotations(psiModifierListOwner);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static <T extends JavaAnnotationOwnerImpl & JavaModifierListOwnerImpl>
|
||||
Collection<JavaAnnotation> getRegularAndExternalAnnotations(@NotNull T owner) {
|
||||
PsiAnnotation[] externalAnnotations = getExternalAnnotations(owner);
|
||||
if (externalAnnotations == null) {
|
||||
return getAnnotations(owner);
|
||||
}
|
||||
Collection<JavaAnnotation> annotations = new ArrayList<>(getAnnotations(owner));
|
||||
annotations.addAll(nullabilityAnnotations(externalAnnotations));
|
||||
return annotations;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static JavaAnnotation findAnnotation(@NotNull JavaAnnotationOwnerImpl owner, @NotNull FqName fqName) {
|
||||
PsiAnnotationOwner annotationOwnerPsi = owner.getAnnotationOwnerPsi();
|
||||
if (annotationOwnerPsi != null) {
|
||||
PsiAnnotation psiAnnotation = annotationOwnerPsi.findAnnotation(fqName.asString());
|
||||
return psiAnnotation == null ? null : new JavaAnnotationImpl(psiAnnotation);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
-247
@@ -1,247 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.load.java.structure.impl.classFiles
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.search.SearchScope
|
||||
import gnu.trove.THashMap
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.VirtualFileBoundJavaClass
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaAnnotation.Companion.computeTypeParameterBound
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.org.objectweb.asm.*
|
||||
import java.text.CharacterIterator
|
||||
import java.text.StringCharacterIterator
|
||||
|
||||
class BinaryJavaClass(
|
||||
override val virtualFile: VirtualFile,
|
||||
override val fqName: FqName,
|
||||
internal val context: ClassifierResolutionContext,
|
||||
private val signatureParser: BinaryClassSignatureParser,
|
||||
override var access: Int = 0,
|
||||
override val outerClass: JavaClass?,
|
||||
classContent: ByteArray? = null
|
||||
) : ClassVisitor(ASM_API_VERSION_FOR_CLASS_READING), VirtualFileBoundJavaClass, BinaryJavaModifierListOwner, MutableJavaAnnotationOwner {
|
||||
override val annotations: MutableCollection<JavaAnnotation> = SmartList()
|
||||
|
||||
override lateinit var typeParameters: List<JavaTypeParameter>
|
||||
override lateinit var supertypes: List<JavaClassifierType>
|
||||
|
||||
override val methods = arrayListOf<JavaMethod>()
|
||||
override val fields = arrayListOf<JavaField>()
|
||||
override val constructors = arrayListOf<JavaConstructor>()
|
||||
override val recordComponents = arrayListOf<JavaRecordComponent>()
|
||||
|
||||
override fun hasDefaultConstructor() = false // never: all constructors explicit in bytecode
|
||||
|
||||
private lateinit var myInternalName: String
|
||||
|
||||
// In accordance with JVMS, super class always comes before the interface list
|
||||
private val superclass: JavaClassifierType? get() = supertypes.firstOrNull()
|
||||
private val implementedInterfaces: List<JavaClassifierType> get() = supertypes.drop(1)
|
||||
|
||||
override val annotationsByFqName by buildLazyValueForMap()
|
||||
|
||||
// Short name of a nested class of this class -> access flags as seen in the InnerClasses attribute value.
|
||||
// Note that it doesn't include classes mentioned in other InnerClasses attribute values (those which are not nested in this class).
|
||||
private val ownInnerClassNameToAccess: MutableMap<Name, Int> = THashMap()
|
||||
|
||||
override val innerClassNames get() = ownInnerClassNameToAccess.keys
|
||||
|
||||
override val name: Name
|
||||
get() = fqName.shortName()
|
||||
|
||||
override val isInterface get() = isSet(Opcodes.ACC_INTERFACE)
|
||||
override val isAnnotationType get() = isSet(Opcodes.ACC_ANNOTATION)
|
||||
override val isEnum get() = isSet(Opcodes.ACC_ENUM)
|
||||
|
||||
override val isRecord get() = false
|
||||
|
||||
override val lightClassOriginKind: LightClassOriginKind? get() = null
|
||||
|
||||
override val isSealed: Boolean get() = permittedTypes.isNotEmpty()
|
||||
override val permittedTypes = arrayListOf<JavaClassifierType>()
|
||||
|
||||
override fun isFromSourceCodeInScope(scope: SearchScope): Boolean = false
|
||||
|
||||
override fun visitTypeAnnotation(typeRef: Int, typePath: TypePath?, descriptor: String?, visible: Boolean): AnnotationVisitor? {
|
||||
if (descriptor == null)
|
||||
return null
|
||||
|
||||
fun getTargetType(baseType: JavaType) =
|
||||
if (typePath != null) BinaryJavaAnnotation.computeTargetType(baseType, typePath) else baseType
|
||||
|
||||
val typeReference = TypeReference(typeRef)
|
||||
|
||||
val annotationOwner = when (typeReference.sort) {
|
||||
TypeReference.CLASS_EXTENDS ->
|
||||
getTargetType(if (typeReference.superTypeIndex == -1) superclass!! else implementedInterfaces[typeReference.superTypeIndex])
|
||||
TypeReference.CLASS_TYPE_PARAMETER -> typeParameters[typeReference.typeParameterIndex]
|
||||
TypeReference.CLASS_TYPE_PARAMETER_BOUND -> getTargetType(computeTypeParameterBound(typeParameters, typeReference))
|
||||
else -> return null
|
||||
}
|
||||
|
||||
if (annotationOwner !is MutableJavaAnnotationOwner) return null
|
||||
|
||||
return BinaryJavaAnnotation.addAnnotation(annotationOwner, descriptor, context, signatureParser, isFreshlySupportedAnnotation = true)
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
methods.trimToSize()
|
||||
fields.trimToSize()
|
||||
constructors.trimToSize()
|
||||
}
|
||||
|
||||
init {
|
||||
try {
|
||||
ClassReader(classContent ?: virtualFile.contentsToByteArray()).accept(
|
||||
this,
|
||||
ClassReader.SKIP_CODE or ClassReader.SKIP_FRAMES
|
||||
)
|
||||
} catch (e: Throwable) {
|
||||
throw IllegalStateException("Could not read class: $virtualFile", e)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
|
||||
if (access.isSet(Opcodes.ACC_SYNTHETIC) || access.isSet(Opcodes.ACC_BRIDGE) || name == "<clinit>") return null
|
||||
|
||||
// skip semi-synthetic enum methods
|
||||
if (isEnum) {
|
||||
if (name == "values" && desc.startsWith("()")) return null
|
||||
if (name == "valueOf" && desc.startsWith("(Ljava/lang/String;)")) return null
|
||||
}
|
||||
|
||||
val (member, visitor) = BinaryJavaMethodBase.create(name, access, desc, signature, this, context.copyForMember(), signatureParser)
|
||||
|
||||
when (member) {
|
||||
is JavaMethod -> methods.add(member)
|
||||
is JavaConstructor -> constructors.add(member)
|
||||
else -> error("Unexpected member: ${member.javaClass}")
|
||||
}
|
||||
|
||||
return visitor
|
||||
}
|
||||
|
||||
override fun visitInnerClass(name: String, outerName: String?, innerName: String?, access: Int) {
|
||||
if (access.isSet(Opcodes.ACC_SYNTHETIC)) return
|
||||
if (innerName == null || outerName == null) return
|
||||
|
||||
// Do not read InnerClasses attribute values where full name != outer + $ + inner; treat those classes as top level instead.
|
||||
// This is possible for example for Groovy-generated $Trait$FieldHelper classes.
|
||||
if (name == "$outerName$$innerName") {
|
||||
context.addInnerClass(name, outerName, innerName)
|
||||
|
||||
if (myInternalName == outerName) {
|
||||
ownInnerClassNameToAccess[context.mapInternalNameToClassId(name).shortClassName] = access
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visit(
|
||||
version: Int,
|
||||
access: Int,
|
||||
name: String,
|
||||
signature: String?,
|
||||
superName: String?,
|
||||
interfaces: Array<out String>?
|
||||
) {
|
||||
this.access = this.access or access
|
||||
this.myInternalName = name
|
||||
|
||||
if (signature != null) {
|
||||
parseClassSignature(signature)
|
||||
} else {
|
||||
this.typeParameters = emptyList()
|
||||
this.supertypes = mutableListOf<JavaClassifierType>().apply {
|
||||
addIfNotNull(superName?.convertInternalNameToClassifierType())
|
||||
interfaces?.forEach {
|
||||
addIfNotNull(it.convertInternalNameToClassifierType())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseClassSignature(signature: String) {
|
||||
val iterator = StringCharacterIterator(signature)
|
||||
this.typeParameters =
|
||||
signatureParser
|
||||
.parseTypeParametersDeclaration(iterator, context)
|
||||
.also(context::addTypeParameters)
|
||||
|
||||
val supertypes = SmartList<JavaClassifierType>()
|
||||
supertypes.addIfNotNull(signatureParser.parseClassifierRefSignature(iterator, context))
|
||||
while (iterator.current() != CharacterIterator.DONE) {
|
||||
supertypes.addIfNotNull(signatureParser.parseClassifierRefSignature(iterator, context))
|
||||
}
|
||||
this.supertypes = supertypes
|
||||
}
|
||||
|
||||
private fun String.convertInternalNameToClassifierType(): JavaClassifierType =
|
||||
PlainJavaClassifierType({ context.resolveByInternalName(this) }, emptyList())
|
||||
|
||||
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
|
||||
if (access.isSet(Opcodes.ACC_SYNTHETIC)) return null
|
||||
|
||||
val type = signatureParser.parseTypeString(StringCharacterIterator(signature ?: desc), context)
|
||||
val processedValue = processValue(value, type)
|
||||
val filed = BinaryJavaField(Name.identifier(name), access, this, access.isSet(Opcodes.ACC_ENUM), type, processedValue)
|
||||
|
||||
fields.add(filed)
|
||||
|
||||
return AnnotationsCollectorFieldVisitor(filed, context, signatureParser)
|
||||
}
|
||||
|
||||
/**
|
||||
* All the int-like values (including Char/Boolean) come in visitor as Integer instances
|
||||
*/
|
||||
private fun processValue(value: Any?, fieldType: JavaType): Any? {
|
||||
if (fieldType !is JavaPrimitiveType || fieldType.type == null || value !is Int) return value
|
||||
|
||||
return when (fieldType.type) {
|
||||
PrimitiveType.BOOLEAN -> {
|
||||
when (value) {
|
||||
0 -> false
|
||||
1 -> true
|
||||
else -> value
|
||||
}
|
||||
}
|
||||
PrimitiveType.CHAR -> value.toChar()
|
||||
else -> value
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitAnnotation(desc: String, visible: Boolean) =
|
||||
BinaryJavaAnnotation.addAnnotation(this, desc, context, signatureParser)
|
||||
|
||||
override fun findInnerClass(name: Name): JavaClass? = findInnerClass(name, classFileContent = null)
|
||||
|
||||
fun findInnerClass(name: Name, classFileContent: ByteArray?): JavaClass? {
|
||||
val access = ownInnerClassNameToAccess[name] ?: return null
|
||||
|
||||
return virtualFile.parent.findChild("${virtualFile.nameWithoutExtension}$$name.class")?.let {
|
||||
BinaryJavaClass(
|
||||
it, fqName.child(name), context.copyForMember(), signatureParser, access, this,
|
||||
classFileContent
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
-346
@@ -1,346 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.test.testFramework;
|
||||
|
||||
import com.intellij.core.CoreASTFactory;
|
||||
import com.intellij.ide.util.AppPropertiesComponentImpl;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.lang.*;
|
||||
import com.intellij.lang.impl.PsiBuilderFactoryImpl;
|
||||
import com.intellij.mock.*;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
|
||||
import com.intellij.openapi.fileTypes.FileTypeFactory;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.FileTypeRegistry;
|
||||
import com.intellij.openapi.options.SchemeManagerFactory;
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.impl.CoreProgressManager;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.pom.PomModel;
|
||||
import com.intellij.pom.core.impl.PomModelImpl;
|
||||
import com.intellij.pom.tree.TreeAspect;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.*;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import com.intellij.testFramework.MockSchemeManagerFactory;
|
||||
import com.intellij.testFramework.TestDataFile;
|
||||
import com.intellij.util.CachedValuesManagerImpl;
|
||||
import com.intellij.util.Function;
|
||||
import junit.framework.TestCase;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType;
|
||||
import org.picocontainer.ComponentAdapter;
|
||||
import org.picocontainer.MutablePicoContainer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
public abstract class KtParsingTestCase extends KtPlatformLiteFixture {
|
||||
public static final Key<Document> HARD_REF_TO_DOCUMENT_KEY = Key.create("HARD_REF_TO_DOCUMENT_KEY");
|
||||
protected String myFilePrefix = "";
|
||||
protected String myFileExt;
|
||||
protected final String myFullDataPath;
|
||||
protected PsiFile myFile;
|
||||
private MockPsiManager myPsiManager;
|
||||
private PsiFileFactoryImpl myFileFactory;
|
||||
protected Language myLanguage;
|
||||
private final ParserDefinition[] myDefinitions;
|
||||
private final boolean myLowercaseFirstLetter;
|
||||
|
||||
protected KtParsingTestCase(@NonNls @NotNull String dataPath, @NotNull String fileExt, @NotNull ParserDefinition... definitions) {
|
||||
this(dataPath, fileExt, false, definitions);
|
||||
}
|
||||
|
||||
protected KtParsingTestCase(@NonNls @NotNull String dataPath, @NotNull String fileExt, boolean lowercaseFirstLetter, @NotNull ParserDefinition... definitions) {
|
||||
myDefinitions = definitions;
|
||||
myFullDataPath = getTestDataPath() + "/" + dataPath;
|
||||
myFileExt = fileExt;
|
||||
myLowercaseFirstLetter = lowercaseFirstLetter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
initApplication();
|
||||
ComponentAdapter component = getApplication().getPicoContainer().getComponentAdapter(ProgressManager.class.getName());
|
||||
|
||||
Extensions.registerAreaClass("IDEA_PROJECT", null);
|
||||
myProject = new MockProjectEx(getTestRootDisposable());
|
||||
myPsiManager = new MockPsiManager(myProject);
|
||||
myFileFactory = new PsiFileFactoryImpl(myPsiManager);
|
||||
MutablePicoContainer appContainer = getApplication().getPicoContainer();
|
||||
final MockEditorFactory editorFactory = new MockEditorFactory();
|
||||
MockFileTypeManager mockFileTypeManager = new MockFileTypeManager(KotlinFileType.INSTANCE);
|
||||
MockFileDocumentManagerImpl mockFileDocumentManager = new MockFileDocumentManagerImpl(new Function<CharSequence, Document>() {
|
||||
@Override
|
||||
public Document fun(CharSequence charSequence) {
|
||||
return editorFactory.createDocument(charSequence);
|
||||
}
|
||||
}, HARD_REF_TO_DOCUMENT_KEY);
|
||||
|
||||
registerApplicationService(PropertiesComponent.class, new AppPropertiesComponentImpl());
|
||||
registerApplicationService(PsiBuilderFactory.class, new PsiBuilderFactoryImpl());
|
||||
registerApplicationService(DefaultASTFactory.class, new CoreASTFactory());
|
||||
registerApplicationService(SchemeManagerFactory.class, new MockSchemeManagerFactory());
|
||||
registerApplicationService(FileTypeManager.class, mockFileTypeManager);
|
||||
registerApplicationService(FileDocumentManager.class, mockFileDocumentManager);
|
||||
|
||||
registerApplicationService(ProgressManager.class, new CoreProgressManager());
|
||||
|
||||
registerComponentInstance(appContainer, FileTypeRegistry.class, mockFileTypeManager);
|
||||
registerComponentInstance(appContainer, FileTypeManager.class, mockFileTypeManager);
|
||||
registerComponentInstance(appContainer, EditorFactory.class, editorFactory);
|
||||
registerComponentInstance(appContainer, FileDocumentManager.class, mockFileDocumentManager);
|
||||
registerComponentInstance(appContainer, PsiDocumentManager.class, new MockPsiDocumentManager());
|
||||
|
||||
|
||||
myProject.registerService(CachedValuesManager.class, new CachedValuesManagerImpl(myProject, new PsiCachedValuesFactory(myPsiManager)));
|
||||
myProject.registerService(PsiManager.class, myPsiManager);
|
||||
|
||||
this.registerExtensionPoint(FileTypeFactory.FILE_TYPE_FACTORY_EP, FileTypeFactory.class);
|
||||
registerExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
|
||||
|
||||
for (ParserDefinition definition : myDefinitions) {
|
||||
addExplicitExtension(LanguageParserDefinitions.INSTANCE, definition.getFileNodeType().getLanguage(), definition);
|
||||
}
|
||||
if (myDefinitions.length > 0) {
|
||||
configureFromParserDefinition(myDefinitions[0], myFileExt);
|
||||
}
|
||||
|
||||
// That's for reparse routines
|
||||
final PomModelImpl pomModel = new PomModelImpl(myProject);
|
||||
myProject.registerService(PomModel.class, pomModel);
|
||||
new TreeAspect(pomModel);
|
||||
}
|
||||
|
||||
public void configureFromParserDefinition(ParserDefinition definition, String extension) {
|
||||
myLanguage = definition.getFileNodeType().getLanguage();
|
||||
myFileExt = extension;
|
||||
addExplicitExtension(LanguageParserDefinitions.INSTANCE, this.myLanguage, definition);
|
||||
registerComponentInstance(
|
||||
getApplication().getPicoContainer(), FileTypeManager.class,
|
||||
new MockFileTypeManager(new MockLanguageFileType(myLanguage, myFileExt)));
|
||||
}
|
||||
|
||||
protected <T> void addExplicitExtension(final LanguageExtension<T> instance, final Language language, final T object) {
|
||||
instance.addExplicitExtension(language, object);
|
||||
Disposer.register(myProject, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
instance.removeExplicitExtension(language, object);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> void registerExtensionPoint(final ExtensionPointName<T> extensionPointName, Class<T> aClass) {
|
||||
super.registerExtensionPoint(extensionPointName, aClass);
|
||||
Disposer.register(myProject, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
Extensions.getRootArea().unregisterExtensionPoint(extensionPointName.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected <T> void registerApplicationService(final Class<T> aClass, T object) {
|
||||
getApplication().registerService(aClass, object);
|
||||
Disposer.register(myProject, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
getApplication().getPicoContainer().unregisterComponent(aClass.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public MockProjectEx getProject() {
|
||||
return myProject;
|
||||
}
|
||||
|
||||
public MockPsiManager getPsiManager() {
|
||||
return myPsiManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
myFile = null;
|
||||
myProject = null;
|
||||
myPsiManager = null;
|
||||
}
|
||||
|
||||
protected String getTestDataPath() {
|
||||
return PathManager.getHomePath();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final String getTestName() {
|
||||
return getTestName(myLowercaseFirstLetter);
|
||||
}
|
||||
|
||||
protected boolean includeRanges() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean skipSpaces() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean checkAllPsiRoots() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void doTest(boolean checkResult) {
|
||||
String name = getTestName();
|
||||
try {
|
||||
String text = loadFile(name + "." + myFileExt);
|
||||
myFile = createPsiFile(name, text);
|
||||
ensureParsed(myFile);
|
||||
assertEquals("light virtual file text mismatch", text, ((LightVirtualFile)myFile.getVirtualFile()).getContent().toString());
|
||||
assertEquals("virtual file text mismatch", text, LoadTextUtil.loadText(myFile.getVirtualFile()));
|
||||
assertEquals("doc text mismatch", text, myFile.getViewProvider().getDocument().getText());
|
||||
assertEquals("psi text mismatch", text, myFile.getText());
|
||||
ensureCorrectReparse(myFile);
|
||||
if (checkResult){
|
||||
checkResult(name, myFile);
|
||||
}
|
||||
else{
|
||||
toParseTreeText(myFile, skipSpaces(), includeRanges());
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doTest(String suffix) throws IOException {
|
||||
String name = getTestName();
|
||||
String text = loadFile(name + "." + myFileExt);
|
||||
myFile = createPsiFile(name, text);
|
||||
ensureParsed(myFile);
|
||||
assertEquals(text, myFile.getText());
|
||||
checkResult(name + suffix, myFile);
|
||||
}
|
||||
|
||||
protected void doCodeTest(String code) throws IOException {
|
||||
String name = getTestName();
|
||||
myFile = createPsiFile("a", code);
|
||||
ensureParsed(myFile);
|
||||
assertEquals(code, myFile.getText());
|
||||
checkResult(myFilePrefix + name, myFile);
|
||||
}
|
||||
|
||||
protected PsiFile createPsiFile(String name, String text) {
|
||||
return createFile(name + "." + myFileExt, text);
|
||||
}
|
||||
|
||||
protected PsiFile createFile(@NonNls String name, String text) {
|
||||
LightVirtualFile virtualFile = new LightVirtualFile(name, myLanguage, text);
|
||||
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
|
||||
return createFile(virtualFile);
|
||||
}
|
||||
|
||||
protected PsiFile createFile(LightVirtualFile virtualFile) {
|
||||
return myFileFactory.trySetupPsiForFile(virtualFile, myLanguage, true, false);
|
||||
}
|
||||
|
||||
protected void checkResult(@NonNls @TestDataFile String targetDataName, final PsiFile file) throws IOException {
|
||||
doCheckResult(myFullDataPath, file, checkAllPsiRoots(), targetDataName, skipSpaces(), includeRanges());
|
||||
}
|
||||
|
||||
public static void doCheckResult(String testDataDir,
|
||||
PsiFile file,
|
||||
boolean checkAllPsiRoots,
|
||||
String targetDataName,
|
||||
boolean skipSpaces,
|
||||
boolean printRanges) throws IOException {
|
||||
FileViewProvider provider = file.getViewProvider();
|
||||
Set<Language> languages = provider.getLanguages();
|
||||
|
||||
if (!checkAllPsiRoots || languages.size() == 1) {
|
||||
doCheckResult(testDataDir, targetDataName + ".txt", toParseTreeText(file, skipSpaces, printRanges).trim());
|
||||
return;
|
||||
}
|
||||
|
||||
for (Language language : languages) {
|
||||
PsiFile root = provider.getPsi(language);
|
||||
String expectedName = targetDataName + "." + language.getID() + ".txt";
|
||||
doCheckResult(testDataDir, expectedName, toParseTreeText(root, skipSpaces, printRanges).trim());
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkResult(String actual) throws IOException {
|
||||
String name = getTestName();
|
||||
doCheckResult(myFullDataPath, myFilePrefix + name + ".txt", actual);
|
||||
}
|
||||
|
||||
protected void checkResult(@TestDataFile @NonNls String targetDataName, String actual) throws IOException {
|
||||
doCheckResult(myFullDataPath, targetDataName, actual);
|
||||
}
|
||||
|
||||
public static void doCheckResult(String fullPath, String targetDataName, String actual) throws IOException {
|
||||
String expectedFileName = fullPath + File.separatorChar + targetDataName;
|
||||
KtUsefulTestCase.assertSameLinesWithFile(expectedFileName, actual);
|
||||
}
|
||||
|
||||
protected static String toParseTreeText(PsiElement file, boolean skipSpaces, boolean printRanges) {
|
||||
return DebugUtil.psiToString(file, skipSpaces, printRanges);
|
||||
}
|
||||
|
||||
protected String loadFile(@NonNls @TestDataFile String name) throws IOException {
|
||||
return loadFileDefault(myFullDataPath, name);
|
||||
}
|
||||
|
||||
public static String loadFileDefault(String dir, String name) throws IOException {
|
||||
return FileUtil.loadFile(new File(dir, name), CharsetToolkit.UTF8, true).trim();
|
||||
}
|
||||
|
||||
public static void ensureParsed(PsiFile file) {
|
||||
file.accept(new PsiElementVisitor() {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
element.acceptChildren(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void ensureCorrectReparse(@NotNull PsiFile file) {
|
||||
String psiToStringDefault = DebugUtil.psiToString(file, false, false);
|
||||
String fileText = file.getText();
|
||||
DiffLog diffLog = (new BlockSupportImpl()).reparseRange(
|
||||
file, file.getNode(), TextRange.allOf(fileText), fileText, new EmptyProgressIndicator(), fileText);
|
||||
diffLog.performActualPsiChange(file);
|
||||
|
||||
TestCase.assertEquals(psiToStringDefault, DebugUtil.psiToString(file, false, false));
|
||||
}
|
||||
}
|
||||
-1187
File diff suppressed because it is too large
Load Diff
-1186
File diff suppressed because it is too large
Load Diff
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.utils
|
||||
|
||||
import com.intellij.util.containers.ConcurrentMultiMap
|
||||
import com.intellij.util.containers.Interner
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import com.intellij.util.containers.StringInterner
|
||||
|
||||
fun createStringInterner(): Interner<String> =
|
||||
StringInterner()
|
||||
|
||||
fun <K, V> createConcurrentMultiMap(): MultiMap<K, V> =
|
||||
ConcurrentMultiMap<K, V>()
|
||||
Reference in New Issue
Block a user